標籤:
一、前言論學習心態:
每當進入一個新的工作環境,處於一種新的領域時,人總是會變得急功近利,特別是當任務緊急時,人總是會想著不斷的從網上搜尋答案,不斷的去尋問他人,十足的拿來主義,竟沒有靜下來自己思考與嘗試過,回頭看來,其實很多東西並沒有當初認為的那麼複雜,只是少了自己的一些總結和深思。
論問題本身:
關於Unity和Android的互相調用,網上的教程太多了,大同小異,抄來抄去。這次我就嘗試著慢慢來,講講我的理解(簡單的我會一筆帶過,網上可以輕鬆找到答案,就不贅述了),希望大家看的時候並不是秉承著“拿來主義”,而是靜下心來,一起知其然,知其所以然,如果有錯誤和不足,請在我的部落格留言。
部落格地址:http://blog.csdn.net/yang8456211
內容分為三部分,分三篇寫完
- 前篇:Unity3d 與 Android之間的互相調用
- 中篇:Unity3d Android SDK的兩種接入方式
http://blog.csdn.net/yang8456211/article/details/51356193
- 後篇:Unity3d 接入Android Libriary的理解與實現
二、前篇:Unity3d 與 Android之間的互相調用
總體來說Unity3d與Android之間的互相調用,是通過Unity3d提供的classes.jar來實現的(具體實現在中篇說)。
那麼下面假設已經按照要求建立好了Android的工程,並配置好了classes.jar,開始寫調用:
2.1 Unity3d調用Android
最常見的寫法:
1)首先在Android層寫好介面u3dCall
這個方法只列印成功的提示:
public void u3dCall() { Log.i(U2ATAG, "u3dCall Android Successful"); }
2)在Unity3d cs指令碼中調用Android
通過反射機制拿取對象並調用Android的介面u3dCall,這裡我們畫了一個Button,點擊Button調用u3dCall介面:
if(GUI.Button(new Rect(100,200,750,200),"U3dToAnd")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("u3dCall"); }
通過列印看到,我們成功的從Unity3d調用到了Android的代碼。
(沒有充滿疑問?)
- 這個com.unity3d.player.UnityPlayer是什麼東西?currentActivity又是什嗎?
- Call是個方法吧,那參數和傳回值呢?是調用的什麼類型的方法?
只有通過實踐慢慢探索,才能知道真相
3)Unity3d調用Android介面的api
我們先說第二個問題,Call只是Unity3d調用Android所設定的api之一,還有一些常用的:
| 方法名 |
方法類型 |
說明 |
| Call |
執行個體 |
調用執行個體方法 |
| Get |
執行個體 |
擷取執行個體變數(非靜態) |
| Set |
執行個體 |
設定執行個體變數(非靜態) |
| CallStatic |
靜態 |
調用靜態方法 |
| GetStatic |
靜態 |
擷取靜態變數 |
| SetStatic |
靜態 |
設定靜態變數 |
通過這些方法,我們能夠方便的調用靜態方法、執行個體方法,還有擷取變數的值。
如果Android的方法是需要傳入參數的,則如下:
Android:
public void u3dCallWithArgs(String str, int i) { Log.i(U2ATAG, "u3dCall Android Str|int is " + str + "|" + i); }
U3d:
jo.Call("u3dCallWithArgs","Atany",100);
成功調用:
如果需要傳回值:
Android:
public String u3dCallReturn() { return "This is the return Value of Android"; }
U3d:
string msg = jo.Call<string>("u3dCallReturn"); print ("U3d msg is "+msg);
成功調用:
其他的方法類似,可以猜到jo = jc.GetStatic(“currentActivity”);的意思,就是通過GetStatic擷取了靜態變數currentActivity的值,它的類型是AndroidJavaObject(Unity3d的JavaObject的基本類型)。
4) 那UnityPlayer是什嗎?
通過反編譯Unity3d產生的apk發現,UnityPlayer是FrameLayout的一個子類,而currentActivity則是UnityPlayer類中的靜態對象。
致此,就弄明白了,這個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對象
在oncreate方法裡面初始化了這個對象,把UnityPlayerNativeActivity上下文作為參數傳了進去
然後在UnityPlayer類的構造方法中,把當前的上下文賦值給了currentActivity
所以,我們使用的currentActivity 就是當前activity的上下文。寫到這裡,我還有一個疑問,就是currentActivity是拿到的UnityPlayerNativeActivity的上下文,但是是怎麼調用到的Myactivity裡面的方法的呢?希望知道的人告訴我。
2.2 Android調用Unity
如果想要非同步發送訊息回Unity那麼應該怎麼處理呢?就是使用Unity3d的UnitySendMessage發送回去
Android:
public void andToU3d() { UnityPlayer.UnitySendMessage(OBJNAME, "andToU3dCallback", "exit"); }
U3d:
void andToU3dCallback(string str){ print ("andToU3dCallback string is "+str); }
楊光(atany)原創,轉載請註明博主與博文連結,未經博主允許,禁止任何商業用途。
博文地址:http://blog.csdn.net/yang8456211/article/details/51331358
部落格地址:http://blog.csdn.net/yang8456211
本文遵循“署名-非商業用途-保持一致”創作公用協議
Unity3d Android SDK接入解析(一)