現(xiàn)在android開(kāi)發(fā)都轉(zhuǎn)到android studio上了, unity與android交互,如unity打開(kāi)android的界面(activity),當(dāng)eclipse工程轉(zhuǎn)到android studio時(shí)遇上java.lang.NoSuchMethodError, 網(wǎng)上找了很多資料查到的都是簡(jiǎn)單的例子如打開(kāi)android的Toast, Dialog,官方文檔也比較少,android新手折騰了幾天終于搞定了,特寫(xiě)此文記錄一下。
Android新手在開(kāi)發(fā)工具的選擇上果斷用了Android Studio,確實(shí)好用。
一、Unity與Androd交互參考:
我的需求是用android開(kāi)發(fā)sdk,供unity游戲使用。
1. android項(xiàng)目新建2個(gè)activity,主activity繼承UnityplayerActivity,作為與Unity交互的接口,
2. 主activity中提供打開(kāi)新activity的接口。
3. Unity創(chuàng)建若干按鈕,打開(kāi)android的Toast, 和多種方式打開(kāi)android的界面(activity)。
4. android打包aar和androidmanifest.xml放入U(xiǎn)nity項(xiàng)目的Assets/Plugin
5. unity打出apk包,安裝在海馬玩或mumu模擬器中。
6. android studio打開(kāi)Android monitor查看模擬器的adb log,
模擬器時(shí)不時(shí)掉線,還連不上,可重啟android monitor和模擬器試試。
Unity與Android交互參考下面幾個(gè)鏈接:
1.實(shí)現(xiàn)Unity和Android進(jìn)行交互
2.Android Native Plugin: From Android Studio to Unity
3.BUILDING ANDROID PLUGINS WITH UNITYPLAYERACTIVITY
4.Unity3D游戲開(kāi)發(fā)之Unity與Android交互調(diào)用研究
這個(gè)是Eclipse 工程結(jié)構(gòu)的
5.https://www.thepolyglotdeveloper.com/2014/06/creating-an-android-java-plugin-for-unity3d/
6.https://library.vuforia.com/articles/Solution/How-To-Use-Android-Plugins-in-Unity-Apps
7.http://www.xuanyusong.com/archives/667
Unity3D研究院之打開(kāi)Activity與調(diào)用JAVA代碼傳遞參數(shù)
看這幾個(gè)例子就夠了,有的是含有demo的,可下載。
希望是美好的,過(guò)程是痛苦的,作為組內(nèi)第一個(gè)吃螃蟹的人,坑是不少的,下面我們一個(gè)個(gè)來(lái)踩踩。
二、遇到的問(wèn)題
1. Unity 打Android包錯(cuò)誤: Invalid command android,
解決方案:更換sdk tools到25.2.3
參考如下:Unity編譯時(shí)找不到AndroidSDK的問(wèn)題 | Unable to list target platforms
http://www.itdecent.cn/p/fe4c334ee9fe
2.Android調(diào)試,方法有多種:
Android Studio自帶ADT;Eclipse + adt;也可adb控制臺(tái)查看 #adb logcat。
我在windows上裝了android模擬器,海馬玩,mumu都可以;也可用真機(jī)調(diào)試。
adb log,試過(guò)控制臺(tái),總是找不到模擬器.
一般是端口問(wèn)題,需要手工指定端口,比較麻煩,棄之。
試AS自帶的Android Monitor,立馬連上了
如下圖所示,右邊開(kāi)著海馬玩模擬器運(yùn)行android apk,左邊是顯示的adb log。

然而,問(wèn)題來(lái)了:AS會(huì)經(jīng)常顯示顯示offline 或者disconnect,明明剛剛用的好好的,怎么突然不行了。一度懷疑過(guò)是不是剛打包問(wèn)題改了sdk版本導(dǎo)致的,重新更換回去也不行。
接著試試各種方法:
1). adb restart
2). 更新 sdk tools, sdk platform tools
。。。
還是不行,
換個(gè)mumu模擬器就好了,經(jīng)多次實(shí)踐發(fā)現(xiàn) AS adb調(diào)試,設(shè)備會(huì)是不是連不上,我的解決方法很暴力,重啟AS,重啟模擬器,再不行,換另一個(gè)模擬器就好了,有其他小伙伴遇到這個(gè)問(wèn)題嗎?告訴我解決方法,謝謝!
- unity打android包之后,模擬器安裝運(yùn)行運(yùn)行。
unity調(diào)用android打開(kāi)Toast,Dialog,打log都沒(méi)問(wèn)題,但是打開(kāi)android的activity時(shí)找不到class,報(bào)錯(cuò):
No package identifier when getting name for resource number 0x00000000
Caused by: java.lang.NoClassDefFoundError: com.test.unity.Main2Activity
這個(gè)是重磅錯(cuò)誤,打開(kāi)jar包發(fā)現(xiàn)class明明就在里面
先說(shuō)我的解決方法:
經(jīng)過(guò)各種嘗試發(fā)現(xiàn),unity要打開(kāi)android studio的activity,需要以下條件:
- android studio 打出aar包 + unity5.x (支持aar包) ,必須用aar包 + AndroidManifest.xml,android studio打出的aar包解壓后得到的jar文件,
內(nèi)部是沒(méi)有R.class文件的,會(huì)導(dǎo)致找不到資源,猜測(cè)若要使用eclipse的工程結(jié)構(gòu),需想辦法打出包含R.class的jar包,目前未嘗試。
2.Android 主activity 需繼承AndroidPlayerActivity
3.AndroidJavaClassjc=newAndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObjectjo=jc.GetStatic("currentActivity"); jo.Call("方法");
必須使用UnityPlayer,然后獲取currentActivity,再去調(diào)用方法。
分析AS 與Eclipse導(dǎo)出android包的區(qū)別:
AS打jar包有2種方式,
在gradle文件中寫(xiě)命令:task makeJar(type: Copy)
{ delete'build/libs/mysdk.jar' from('build/intermediates/bundles/release/') into('build/libs/') include('classes.jar') rename('classes.jar','mysdk.jar') }
makeJar.dependsOn(build)//在終端執(zhí)行生成JAR包// gradlew makeJar
在Terminal中鍵入 gradlew makeJar 回車看到如下所示就OK了:
build 出aar包,解壓縮得到j(luò)ar包;
這里我采用的第二種方式。
unity也支持兩種結(jié)構(gòu)的android plugin,
unity4.x支持eclipse工程結(jié)構(gòu)的android plugin,
unity5.x即支持eclipse工程結(jié)構(gòu)的android plugin,也支持android studio導(dǎo)出的aar包 + AndroidManifest.xml。
兩種方式都試過(guò),容我細(xì)細(xì)道來(lái)。
1. AS打出的jar包有問(wèn)題?
找到的例子里都是用的Eclipse工程結(jié)構(gòu),(UNITY3D游戲開(kāi)發(fā)之UNITY與ANDROID交互調(diào)用研究)這個(gè)例子里unity能夠正常打開(kāi)android的界面,有demo可下載。
于是將AS的android包與eclipse工程的plugins/Android 包比較,發(fā)現(xiàn)jar包不同,AS的jar包里缺少了R.class。
那么AS怎樣才能打出帶R.class的jar包? 目前未嘗試成功
2. Android 主activity 需繼承AndroidPlayerActivity

如果Android項(xiàng)目需要用到android 的activity,主Activity.java 是需要繼承AndroidPlayerActivity的;
3. unity調(diào)用Android接口的方式:
1)AndroidJavaClassjc =newAndroidJavaClass("com.test.unity.MainActivity");
jc.Call("init");
2)AndroidJavaClassjc=newAndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObjectjo=jc.GetStatic("currentActivity");
jo.Call("showToast","Showing on Toast");
1)直接使用真實(shí)的Class名:com.test.unity.MainActivity"
2)使用UnityPlayer,然后獲取currentActivity,再去調(diào)用方法。
結(jié)論: 簡(jiǎn)單的功能,如打印日志,打開(kāi)android的Toast, dialog,兩種方法都可以,但是打開(kāi)android activity必須使用2),1)無(wú)法打開(kāi)。
4 Unity調(diào)用Android的靜態(tài)和非靜態(tài)方法
public void AndroidCallNonStatic() { using (AndroidJavaClass javaClass = new AndroidJavaClass("com.codestalkers.plugin.Main")) { using (AndroidJavaObject activity = javaClass.GetStatic("mContext")) { activity.Call("nonStaticMethod"); } } }
publicvoidAndroidCallStatic(){ using(AndroidJavaClass javaClass =newAndroidJavaClass("com.codestalkers.plugin.Main")){ javaClass.CallStatic("StaticMethod"); } }
5. Android 哪些方法需要runOnUiThread:
public voidstartActivity1() { runOnUiThread(newRunnable() { @Override public void run() { Intent intent =newIntent(mContext,Main2Activity.class); mContext.startActivity(intent); } });}
public voidshowAndroidUI() { Intent intent =newIntent(mContext,Main2Activity.class); this.startActivity(intent); }
startActivity采用上述兩種方式都能夠在unity中打開(kāi),區(qū)別有待研究。
6)Android向Unity發(fā)消息
Android代碼:
UnityPlayer.UnitySendMessage("GameManager","HelloFromAndroid","Hello!");
Unity代碼:
usingUnityEngine; publicclassGameManager : MonoBehaviour { publicvoidHelloFromAndroid(stringdataReceived) { Debug.Log("Received data from Android plugin: "+ dataReceived); } }
7.解決NoClassDefFoundError問(wèn)題的過(guò)程中還會(huì)遇到下面問(wèn)題
java.lang.NoClassDefFoundError: com.test.unity.R$layout 找不到資源文件
java.lang.NoSuchMethodError 找不到方法,
按照上述我的解決方法可以解決這些報(bào)錯(cuò):
目前的方案只是一種解決辦法,
要想使用Eclipse工程結(jié)構(gòu)的android包,主要問(wèn)題還是在jar包上,解壓aar包發(fā)現(xiàn)有R.txt,而解壓出的jar包沒(méi)有R.class,若想使用eclipse的工程結(jié)構(gòu)的android包,就需要打出合適的jar包,無(wú)奈嘗試gradle makeJar出錯(cuò),待有時(shí)間再試試這種直接build jar包的方法。