一、前言
论学习心态:
每当进入一个新的工作环境,处于一种新的领域时,人总是会变得急功近利,特别是当任务紧急时,人总是会想着不断的从网上搜寻答案,不断的去寻问他人,十足的拿来主义,竟没有静下来自己思考与尝试过,回头看来,其实很多东西并没有当初认为的那么复杂,只是少了自己的一些总结和深思。
论问题本身:
关于Unity和Android的互相调用,网上的教程太多了,大同小异,抄来抄去。这次我就尝试着慢慢来,讲讲我的理解(简单的我会一笔带过,网上可以轻松找到答案,就不赘述了),希望大家看的时候并不是秉承着“拿来主义”,而是静下心来,一起知其然,知其所以然,如果有错误和不足,请在我的博客留言。
博客地址:http://blog.csdn.net/yang8456211
内容分为三部分,分三篇写完
- 前篇:Unity3d 与 Android之间的互相调用
- 中篇:Unity3d Android SDK的两种接入方式
http://blog.csdn.net/yang8456211/article/details/51356193 - 后篇:Unity3d 接入Android Libriary的理解与实现
http://blog.csdn.net/yang8456211/article/details/51435465
二、前篇:Unity3d 与 Android之间的互相调用
总体来说Unity3d与Android之间的互相调用,是通过Unity3d提供的classes.jar来实现的(具体实现在中篇说)。
那么下面假设已经按照要求建立好了Android的工程,并配置好了classes.jar,开始写调用:
2.1 Unity3d调用Android
最常见的写法:
1)首先在Android层写好接口u3dCall
这个方法只打印成功的提示:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">u3dCall</span>() {
Log.i(U2ATAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"u3dCall Android Successful"</span>);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
2)在Unity3d cs脚本中调用Android
通过反射机制拿取对象并调用Android的接口u3dCall,这里我们画了一个Button,点击Button调用u3dCall接口:
<code class="hljs vbscript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(GUI.Button(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Rect(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">750</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span>),<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"U3dToAnd"</span>))
{
AndroidJavaClass jc = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> AndroidJavaClass(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com.unity3d.player.UnityPlayer"</span>);
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"currentActivity"</span>);
jo.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Call</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"u3dCall"</span>);
} </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
通过打印看到,我们成功的从Unity3d调用到了Android的代码。
![](https://img-blog.csdn.net/20160508141903039)
(没有充满疑问?)
- 这个com.unity3d.player.UnityPlayer是什么东西?currentActivity又是什么?
- Call是个方法吧,那参数和返回值呢?是调用的什么类型的方法?
只有通过实践慢慢探索,才能知道真相
3)Unity3d调用Android接口的api
我们先说第二个问题,Call只是Unity3d调用Android所设置的api之一,还有一些常用的:
方法名 | 方法类型 | 说明 |
---|
Call | 实例 | 调用实例方法 |
Get | 实例 | 获取实例变量(非静态) |
Set | 实例 | 设置实例变量(非静态) |
CallStatic | 静态 | 调用静态方法 |
GetStatic | 静态 | 获取静态变量 |
SetStatic | 静态 | 设置静态变量 |
通过这些方法,我们能够方便的调用静态方法、实例方法,还有获取变量的值。
如果Android的方法是需要传入参数的,则如下:
Android:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">u3dCallWithArgs</span>(String str, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i) {
Log.i(U2ATAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"u3dCall Android Str|int is "</span> + str + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"|"</span> + i);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
U3d:
<code class="hljs sql has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> jo.<span class="hljs-operator" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Call</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"u3dCallWithArgs"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Atany"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>);</span> </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
成功调用:
![](https://img-blog.csdn.net/20160508152544597)
如果需要返回值:
Android:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String <span class="hljs-title" style="box-sizing: border-box;">u3dCallReturn</span>() {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"This is the return Value of Android"</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
U3d:
<code class="hljs lua has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span> msg = jo.Call<<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span>>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"u3dCallReturn"</span>);
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"U3d msg is "</span>+msg);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
成功调用:
![](https://img-blog.csdn.net/20160508152718615)
其他的方法类似,可以猜到jo = jc.GetStatic(“currentActivity”);的意思,就是通过GetStatic获取了静态变量currentActivity的值,它的类型是AndroidJavaObject(Unity3d的JavaObject的基本类型)。
4) 那UnityPlayer是什么?
通过反编译Unity3d生成的apk发现,UnityPlayer是FrameLayout的一个子类,而currentActivity则是UnityPlayer类中的静态对象。
![](https://img-blog.csdn.net/20160508144200867)
致此,就弄明白了,这个UnityPlayer原来就是一个Unity3d生成的一个类,我们通过new(”完整类名”)的方式获取到了这个类,然后通过getStatic获取到了currentActivity这个静态对象。
(那么问题又来了,currentActivity这个类是怎么找到我写的方法的呢?)
5)MyActivity与currentActivity
我刻意的避开了中篇要讲的内容,但如果一点不提,感觉问题始终不能讲明白,所以这里就稍微说明一下。
在写Android工程的时候,网上一般要求我们建立了一个新的MyActivity继承UnityPlayerActivity,并在AndroidManifest中把MyActivity设置为启动的Activity,然后使用currentActivity这个jo来调用方法。
为什么要这么做呢?通过观察发现,他们的继承关系是这样的:
MyActivity <-- UnityPlayerActivity <--UnityPlayerNativeActivity <-- NativeActivity<-- Activity
(然而里面并没有com.unity3d.player.UnityPlayer这个class?)
继续查找源码发现,在 UnityPlayerNativeActivity 这个类中,声明了一个UnityPlayer对象
![](https://img-blog.csdn.net/20160508164930427)
在oncreate方法里面初始化了这个对象,把UnityPlayerNativeActivity上下文作为参数传了进去
![](https://img-blog.csdn.net/20160508171325865)
然后在UnityPlayer类的构造方法中,把当前的上下文赋值给了currentActivity
![](https://img-blog.csdn.net/20160508171644337)
所以,我们使用的currentActivity 就是当前activity的上下文。写到这里,我还有一个疑问,就是currentActivity是拿到的UnityPlayerNativeActivity的上下文,但是是怎么调用到的Myactivity里面的方法的呢?希望知道的人告诉我。
2.2 Android调用Unity
如果想要异步的发送消息回Unity那么应该怎么处理呢?就是使用Unity3d的UnitySendMessage发送回去
Android:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">andToU3d</span>() {
UnityPlayer.UnitySendMessage(OBJNAME, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"andToU3dCallback"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"exit"</span>);
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
U3d:
<code class="hljs axapta has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> andToU3dCallback(string <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>){
print (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"andToU3dCallback string is "</span>+<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
杨光(atany)原创,转载请注明博主与博文链接,未经博主允许,禁止任何商业用途。