本文主要面向对Android开发不甚了解的Unity开发者,介绍了基于最新的Android Studio的标准Android开发环境与项目结构的配置流程,在此基础上,开发者可以快速的进行SDK的接入与插件的开发。

目前国内各大博客上搜到的文章内容基本上都是相互抄来抄去,比如说先是清一色的继承UnityPlayerActivity,然后再配置AndroidManifest文件等等,这些确实有效果,但是具有很大的局限性。例如,如果项目中如果存在两个Android插件或SDK会怎么样?都继承UnityPlayerActivity显然是不行的,启动入口Activity只能有一个,AndroidManifest文件没法这样配置。笔者最近在做毕设,帮同学接了若干个Android下的SDK,包括支付宝,科大讯飞以及二维码扫描的SDK,参考一些国外的优秀博客以及自己的实践,总结出一套SDK接入与插件开发的通用流程,在这里分享给大家。

开发环境

1.开发软件:笔者使用的开发软件是Unity 5.4.3f 和Android Studio 2.3。

2.所需类库:UnityPlayer等需要的classes.jar包。在 Unity支持Android下IL2CPP后,UnityPlayer相关的这个jar包位置由原来的`Editor\Data\PlaybackEngines\AndroidPlayer\bin`变成了`Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono(or il2cpp)\Release\Classes`,选择jar包时需要注意选择对应Backend的版本。

项目构建

1.启动Android Studio新建一个Project,会弹出创建工程向导,这里可以随意填写Package NameMininum SDK,最后让选择的Activity类型也可以随意。因为我们并不会用到现在创建的这个项目,我们只是在其结构上再创建一个Library作为我们的Plugin。这里值得注意的是,根据你填写的Company domainApplication name生成的Package name总是小写的,点击右侧的Edit按钮可以对其进行修改。
2.创建项目点击Finish后进入编辑器界面,空无一物,点击左侧的Project,然后切换至Project视图,如图下图左所示。随后在项目名称上点击右键选择New -> Module来创建一个新的模块,这时新的创建向导会启动,选择Android Library类型,随后输入包名的配置与Mininum SDK,注意这里的Package Name需要和Unity项目中的Bundle Identifier保持一致(包括大小写),保持一致的原因是Unity在最后打包时会将所有插件里的AndroidManifest.XML进行合并,如果包名不一致就会出错;而Mininum SDK这里需要在Android 3.0(API 11)以上,因为随后会用到Android 3.0之后才支持的Fragment特性,最后点击Finish完成创建,项目结构应该如下图右所示,红框部分是新创建的Library。
                     
3.在新的Library创建完成后,需要删除app相关的内容。点击菜单栏File -> Project Structure,选中左侧的app然后点击上方的`-`号,最后点击OK,稍等一会儿,Gradle Build会完成构建(可以注意到每次进行一次大的操作如增删,Android Studio都会编译一下项目,所以构建的时候请坐和放宽)。回到Project视图,右键点击app,选择删除。展开Library目录如下图中所示,以后所有的开发操作都会在创建的这个Library下面进行。下面对项目的结构进行一些说明。build/outputs/aar/文件下面是构建生产的供Unity使用的aar文件(aar文件和jar文件类似,Unity可以识别);libs文件夹下面是项目以来的类库,可以说各种SDK的jar等等;最后是src文件夹,这里面存放了AndroidManifest以及源码。这些内容有一些是不需要的,例如一些单元测试的内容,我们删掉测试工程以及res下面的Android自带的资源及配置,最后的项目结构如下图右所示,只保留了AndroidManifest.xml。
                
4.接下来是配置AndroidManifest的内容。双击打开AndroidManifest.xml,里面有一些红色的内容,那些是因为刚才各种删除导致的,这里不再需要常规的插入UnityPlayer等一堆东西,删掉其余不相关的内容后如下所示,可以看到内容非常精简,只保留了最基础的东西:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.soulgame.myplugin"><application android:allowBackup="true" android:supportsRtl="true"></application>
</manifest>

5.最后就是编写我们的插件或者对接第三方SDK了。首先引入Unity的jar包,将classes.jar拷贝到文件夹里libs文件夹下面,通用点击File -> Project Structure,在左侧选择我们的插件,然后在上方选择Dependencies,先删除的现存的所有依赖库,然后点击`+`号 ->Jar Dependency添加Unity的jar包,点击OK完成设置,稍等一会儿就完成了构建。对于第三方SDK的jar包,以同样的方式进行引入。如果第三方依赖库中有so文件,先不需要导入,稍后将会说明如何添加so文件。到这一步,项目、依赖库都设置完毕。

编写代码

不要再继承UnityPlayerActivity了!具体原因会在后面的参考资料里给出。首先贴一段Android Studio里的示例代码,创建一个MyPluginClass类,这里简单的用到了一个static的Instance作为这个类访问的入口(类似单例),在Unity中只需要拿到Instance进行操作即可,里面涉及到一些Android原生的Fragment的操作,具体含义可以Google一下:
package com.soulgame.myplugin;import android.app.Fragment;
import android.os.Bundle;import com.unity3d.player.UnityPlayer;public class MyPluginClass extends Fragment
{private static final String TAG = "MyPlugin";private static MyPluginClass Instance = null;private String gameObjectName;public static MyPluginClass GetInstance(String gameObject){if(Instance == null){Instance = new MyPluginClass();Instance.gameObjectName = gameObject;UnityPlayer.currentActivity.getFragmentManager().beginTransaction().add(Instance, TAG).commit();}return Instance;}@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setRetainInstance(true);  // 这一句很重要,保存对该Fragment的引用,防止在旋转屏幕等操作时时丢失引用(Fragment隶属于Activity)}//示例方法一:简单的向Unity回调  public void SayHello(){UnityPlayer.UnitySendMessage(gameObjectName,"PluginCallBack","Hello Unity!");}//示例方法二:计算传入的参数并返回计算结果public int CalculateAdd(int one, int another){return one + another;}
}

编写完成,将插件编译导出,选中Android Studio右侧的Gradle,选中如图所示的选项编译输出,稍等一会儿,在左侧的Project面板可以看到相关的aar文件了,这个aar文件就是最终输出给Unity使用的aar包,拿到aar包之后,需要进行一项关键的操作,将其后缀改为压缩格式(zip或rar)打开压缩包删除掉libs/下面的classes.jar(原因是Unity在打包的时候会再次拷贝安装目录下的classes.jar到项目中造成冲突)!如果插件使用到了so文件,将对应平台的so文件拷贝至libs下面,如下图右所示:
        

最后将aar文件后缀改回为aar拷贝至Unity工程中Plugins/Android文件夹下,不再需要AndroidManifest.xml
在Unity中编写如下示例代码调用插件的两个方法:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;public class PluginManager : MonoBehaviour
{public string className = "com.soulgame.myplugin.MyPluginClass";public Text callbackText = null;public Text resultText = null;private AndroidJavaObject pluginObject = null;void Start(){
#if UNITY_ANDROID && !UNITY_EDITORpluginObject = new AndroidJavaClass(className).CallStatic<AndroidJavaObject>("GetInstance", gameObject.name);pluginObject.Call("SayHello");                                                                               resultText.text = pluginObject.Call<int>("CalculateAdd", 22, 33).ToString();
#endif}public void PluginCallBack(string text){callbackText.text = text;}
}

编写完成后,设置好Platform和Bundle Identifier以及Mininum API Level(和插件保持一致),到真机上测试即可。

注意事项

1.UnityPlayer.UnitySendMessage()方法接受三个参数,每一个都不能为null!如果不想填就用string.Empty。
2.AndroidJavaObject.Call()传参的时候必须严格按照类型传递,如果参数是float却填了一个int类型的也会造成调用失败!
3.真机在打开开发者模式后可以用adb logcat -s Unity来获取手机中Unity输出的日志,进而进行定位(adb需要在环境变量里配置好),如下图所示的日志就说明找不到插件类里对应的参数(笔者在操作的时候忘记填参数了):
4.以这种方式开发出的插件可以多个并存,例如将一些常用功能封装成静态类获取电量,wifi状态等,然后和支付宝,暴风魔镜的SDK并存等等。
5.快速更改插件的包名,点击齿轮并取消勾选Compact Empty Middle Packages,之后项目的结构中包名会变成三层结构,修改对应的结构即可:
         

参考资料

1.关于插件中继承Fragment而不是UnityPlayerActivity的原因:Unity Android plugin tutorial 。
2.关于Android Fragment的资料:Fragment。

Unity Android平台下插件/SDK开发通用流程相关推荐

  1. Unity Android平台接入支付宝SDK

    这篇文章前面讲的创建Android Studio工程的流程是不正确的!!! 正确的流程请参见:Unity Android平台下插件/SDK开发通用流程 最近帮一个群里的朋友接了一下支付宝的SDK,开发 ...

  2. android平台下使用点九PNG技术

    "点九"是andriod平台的应用软件开发里的一种特殊的图片形式,文件扩展名为:.9.png 智能手机中有自动横屏的功能,同一幅界面会在随着手机(或平板电脑)中的方向传感器的参数不 ...

  3. Android基于环信SDK开发IM即时聊天(一)

    2016-09-02更新:可以看一下最新的这篇文章和源码,Android基于环信SDK开发IM即时聊天(二) 目前市面上我了解的做第三方即时聊天SDK的有两家:环信.融云,这里我使用环信SDK来完成即 ...

  4. android平台下基于ANativeWindow实现渲染bitmap图像

    OpenGL ES 3.0学习实践 android平台下OpenGL ES 3.0从零开始 android平台下OpenGL ES 3.0绘制纯色背景 android平台下OpenGL ES 3.0绘 ...

  5. 文通Android平台证件识别SDK

    文通Android平台证件识别SDK 功能介绍 1.通过拍照界面,指导用户拍出合格证件图像. 2.采用文字识别(OCR)技术,自动提取证件信息(如姓名.证件号码.地址等)及头像. 3.识别证件种类包括 ...

  6. Android基于环信SDK开发IM即时聊天(二)

    声明1:北京时间现在是2019/6/10,评论里的问题我看到了,这几天我找时间看看源代码问题出在哪,在此感谢大家的监督 声明2:此Demo我是在5.1测试机上测试通过,感谢WTQ_DOMIAN的评论, ...

  7. 在Android平台下实现音视频语音聊天

    音视频通信 作为独立开发者或想缩短音视频开发周期的公司来说,想要在Android平台下实现音视频通信,最快捷的方法是寻找开源项目或调用其他公司API.之所以这么说是因为音视频通信技术涉及到底层音视频采 ...

  8. Android平台手机UI应用开发——软件管理器

    第一次写博客,与大家分享源代码,博客很多地方不知道怎么设计,望见谅. 希望大家多多支持,雅林和大家一起学习Android,共同进步. 今天我们要做的这个软件管理器,主要目的是为了学习Android平台 ...

  9. unity Android平台最佳效果探索(二)

    上一篇 unity Android平台最佳效果探索(一) 上篇写到了实现PC版的效果 继续 3.切换到Android平台后效果 直接切换后,不能运行,报错挺多. 原因: (1)Android平台不支持 ...

最新文章

  1. 64% 的企业未实现智能化,5成公司算法工程师团队规模小于 10人,AI 工程师的机遇在哪里?...
  2. crontab FAQ
  3. 手把手教你手动创建线程池
  4. P3197 [HNOI2008]越狱(快速幂)
  5. java对日期进行加减操作以及比较大小
  6. web前端页面优化——个人见解
  7. 怎样使用libmad
  8. alarm/pause
  9. 实验4-1-8 求给定精度的简单交错序列部分和 (15 分)
  10. Java开发笔记(一百二十六)Swing的窗口
  11. 制作符合期刊审图号标准的中国地图(含九段线)
  12. 运动控制器的自定义G代码编程应用
  13. 每秒浮点运算次数FLOPS
  14. Python分析中国大陆各直辖市及各省省会的平均工资与平均房价 课程报告+源码及数据
  15. Mac安装Jadx反编译工具
  16. OpenCV 视频人数统计研究
  17. 安卓美化——添加下拉菜单图片或下拉菜单透明
  18. 怎样根据不同的睡姿选择合适的枕头?
  19. django 输入城市名称获取相应城市即将上映电影
  20. 使用DIV、CSS技术设计的个人博客网页(web期末考试)

热门文章

  1. 汽车的TPMS智能胎压监测系统 -
  2. 2020-08-11
  3. idea设置全局护眼色-背景图片
  4. 通过SOCKS代理渗透整个内网
  5. Android中服务器端与客户端交互
  6. 走好脚下的路--写给迷茫的计算机专业在校生
  7. 金蝶云星空采购订单套打模板明细表里相同编码取最小交货日期
  8. RocketMQ入门(4.可靠异步发送)
  9. 售价40万,年租金500的房子值得投资不?
  10. error starting applicationcontext. to display the conditions report re-run y完美解决