(转)Unity-接⼊AndroidSDK
在⽹络上,关于Unity与Android如何进⾏交互,⾬松MOMO⼤神已经有两篇⽂章简单介绍了如何操作(1)(2)。这两篇⽂章简单介绍如何操作,但是具体的内部细节并没有涉及到。下⾯介绍两种Unity与Android交互的⽅式(或者说就是接⼊Android SDK),分别是(1)Unity 导出Android⼯程,然后你将SDK⼯程作为Library来接⼊(2)Plugins⽅式,这种⽅式就是在Assets⽬录下新建Plugins/Android⽬录,把你需要的资源、jar包等按规定放进去。
(1)Unity导出Android项⽬
通过在Build Settings中选择Google Android Project选项,点击Export,可以得到⼀个Unity⽣成的Android项⽬。
将项⽬导⼊到Eclipse中,可以看见如下的项⽬结构:
让我们先不管src的源代码,⾸先关注libs。
libs⽬录
libs有三部分:前两者(armeabi-v7a, x86)表⽰⼿机的两种硬件设备,包含了各⾃所需的so⽂件,我们可
以在Unity的Player Settings->Other Settings->Device Filter中来进⾏选择。⽽unity_classes.jar就是UnityPlayerActivity类所在的jar包,其实就是Unity⽬录下的
Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Development\Classes\classes.jar。(注意,这个路径是Unity5.3的路径,不同版本的Unity中,该路径是不同的)
下⾯我们来查看classes.jar(即unity_classes.jar)的内容
classes.jar
在⽹上下载⼀个Java反编译⼯具,⽐如JD-GUI,打开classes.jar,我们可以看见如下结构:
其中jnibridge应该是⽤来实现Java与其他语⾔的通信,⽽fmod是⽤来控制⾳频的,剩下的com.unity3d.player才是我们需要重点关注的。通常我们⾃⼰新创建的Activity,都是要继承UnityPlayerActivity类,因此我们⾸先查看该类,其部分内容如下:
该类的内容⼗分简单,其中最为重要的是UnityPlayer:
回忆⼀下,我们在Android⾥定义⾃⼰的Activity:
1. public class UnityTestActivity extends UnityPlayerActivity
在Unity⾥调⽤Android的⽅法的步骤:
1. AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
2. AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
3. jo.Call("StartActivity0","第⼀个Activity");
因为我们继承了UnityPlayerActivity,那么当我们的UnityTestActivity调⽤onCreate⽅法时,就同时把⾃⼰这个实例传递到了UnityPlayer中的currentActivity。因此在Unity中我们就可以利⽤currentActivity来调⽤我们⾃定义的UnityTestActivity中的⽅法。
这时回头查看src的源代码,可以发现其内容和classes.jar中差不多。
清单⽂件 l
⼀个默认的清单⽂件中有以下重要内容:
这⾥,package是在Player Settings->Other Settings->Bundle Identifier设置。默认UnityPlayerActivity为主Activity。
PS.
除了通过导出Android⼯程来查看⾃动⽣成的内容,也可以通过Unity安装⽬录下的Editor\Data\PlaybackEngines\AndroidPlayer来查看,其⽬录内容如下:
我们重点看Apk、Source、Variations,这三者⾥⾯就包含默认的l,res⽬录和assets⽬录等。
(2)Plugins/Android
我们可以通过在Plugins/Android中添加东西来影响Unity⽣成的Android项⽬。
我们可以直接在Android⽬录下添加⼀个l⽂件,这个⽂件会影响最终的Android项⽬中的清单⽂件。注意,这⾥的程度只是影响,⽽不是完全替换,⽐如package会最终替换为Bundle Identifier的设置,如果没有以下⼏⾏
1. <uses-feature android:name="uchscreen" android:required="false" />
2. <uses-feature android:name="uchscreen.multitouch" android:required="false" />
3. <uses-feature android:name="uchscreen.multitouch.distinct" android:required="false" />
如果是默认设置他也会默认加上去,等等。androidsdk安装步骤
PS: l要放到Android⽬录下才会对主清单⽂件起作⽤,如果你放到其他⽬录,⽐如test,则不会对最终的Android项⽬有作⽤。
res⽬录
你可以在Android⽬录下增加⼀个res⽬录。不管这个⽬录是空的还是有东西,导出来的Android项⽬都会多⼀个叫unity-android-resources的Library⼯程,⽽我们的主Android⼯程则引⽤了该Library,如图:
观察这个Library就知道,这个⼯程主要就是存放资源的,⽐如我们这⾥把东西放到res⽬录中,则这些多出来的东西就会放到Library⼯程中。注意,res⽬录的东西不能随便乱放,要按照合格的⽬录结构来,即⼀般如下:
如果你是随便把资源放到res⽬录下,或其他错误名字的⼦⽬录,⽐如res/test等⽬录下,都会报出以下的错误:
assets⽬录
assets⽬录和res⽬录类似,都是存放资源的,只是res⽬录⾥⾯的资源会在R⽂件中⽣成ID,⽽assets⽬录不会⽣成ID,需要⾃⼰⼿动根据路径来访问资源。
jar包
在查看⽹上的相关⽂章时,发现⼤多数⽂章都说要把jar包放到Plugins/Android⽬录的libs或bin⽬录。不知道是不是Unity5做出了修改,我发现jar包不管放到哪,只要在Assets⽬录下,都能起作⽤,成为最终Android⼯程的libs中的内容。
Library⼯程
你可以在Plugins/Android⽬录下放置⼀个Android Library⼯程,只要设置得当,这个⼯程就会被Unity识别并在最终⽣成的Android⼯程中引⽤。这个也是我接⼊Android SDK时主要使⽤的⽅式,⼗分⽅便并且易于管理(毕竟这让你知道哪些资源、jar包是归哪个SDK的。⽽如果所有资源都放在res⽬录,jar包都放在libs⽬录,这样就不知道某个SDK原本的东西在哪了)
我的SDK接⼊⼯作流程
下⾯介绍我接⼊SDK时的流程,这只是我个⼈感觉⽐较⽅便的流程,如果⼤家有更好的流程,希望能在评论区告知。我⼀般会同时使⽤上述两种⽅式,因为第⼀种⽅式的缺点是不好进⾏项⽬管理(毕竟有两个分开的项⽬),并且要打包⼀个apk也⽐较⿇烦;⽽第⼆种⽅式的缺点就是不直观,调试不⽅便。
(1)建⽴SDK的Android Demo⼯程
根据⽂档,将需要的功能以Unity易于调⽤的⽅式写成接⼝,⽐如我⼀般定义函数签名为void FuncName(String params, String callbackTarget, String callbackMethod)
这⾥,params就是SDK接⼝需要的参数(或者是参数列表,以";"等分隔符连接具体的参数,⽐如: "Apple;12"),callbackTarget就是Unity ⾥调⽤回调⽅法的GameObject的名字,⽽callbackMethod就是回调⽅法的名字。
然后创建简易的界⾯(⽐如⼏个按钮)来调⽤这些写好的接⼝,确定接⼝的功能⽆误
(2)将Demo⼯程转换为Library⼯程
去掉Demo⼯程中测试⽤的Activity、布局⽂件,在清单⽂件中去掉主Activity的设置,最后把项⽬设置为Library。
(3)Unity导出Android⼯程,和上⾯的Library⼯程⼀起导⼊到Eclipse中
导⼊完成后,如果你的Library⼯程⽤到classes.jar,你需要先删掉该classes.jar,然后再添加Unity的Android⼯程的unity_classes.jar引⽤。(4)把Library⼯程添加到Unity⼯程
通过(3),我们可以得到⼀个设置正确的Library⼯程,这时候我们可以直接把该⼯程拖到Unity⼯程的Plugins/Android⽬录下
(5)在Unity中编写调⽤Library⼯程接⼝的代码
其他
(1)Unity在直接导出Apk时,会在Temp⽬录(与Assets⽬录同级)下的StagingArea⽬录⽣成⼀些临时的Android代码
(2)在Eclipse中,如果adb⼀直提⽰断开连接,可以⽤360⼿机助⼿连上⼿机,这时adb就能正常⼯作了
参考