Unity與Android(Android Studio)交互及遇到的問題

現在android開發都轉到android studio上了, unity與android交互,如unity打開android的界面(activity),當eclipse工程轉到android studio時遇上java.lang.NoSuchMethodError, 網上找了很多資料查到的都是簡單的例子如打開android的Toast, Dialog,官方文檔也比較少,android新手折騰了幾天終于搞定了,特寫此文記錄一下。


Android新手在開發工具的選擇上果斷用了Android Studio,確實好用。

一、Unity與Androd交互參考:

我的需求是用android開發sdk,供unity游戲使用。
1. android項目新建2個activity,主activity繼承UnityplayerActivity,作為與Unity交互的接口,
2. 主activity中提供打開新activity的接口。
3. Unity創建若干按鈕,打開android的Toast, 和多種方式打開android的界面(activity)。
4. android打包aar和androidmanifest.xml放入Unity項目的Assets/Plugin
5. unity打出apk包,安裝在海馬玩或mumu模擬器中。
6. android studio打開Android monitor查看模擬器的adb log,
模擬器時不時掉線,還連不上,可重啟android monitor和模擬器試試。

Unity與Android交互參考下面幾個鏈接:
1.實現Unity和Android進行交互
2.Android Native Plugin: From Android Studio to Unity
3.BUILDING ANDROID PLUGINS WITH UNITYPLAYERACTIVITY
4.Unity3D游戲開發之Unity與Android交互調用研究
這個是Eclipse 工程結構的
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研究院之打開Activity與調用JAVA代碼傳遞參數
看這幾個例子就夠了,有的是含有demo的,可下載。
希望是美好的,過程是痛苦的,作為組內第一個吃螃蟹的人,坑是不少的,下面我們一個個來踩踩。

二、遇到的問題

1. Unity 打Android包錯誤: Invalid command android,

解決方案:更換sdk tools到25.2.3
參考如下:Unity編譯時找不到AndroidSDK的問題 | Unable to list target platforms
http://www.lxweimin.com/p/fe4c334ee9fe

2.Android調試,方法有多種:

Android Studio自帶ADT;Eclipse + adt;也可adb控制臺查看 #adb logcat。
我在windows上裝了android模擬器,海馬玩,mumu都可以;也可用真機調試。
adb log,試過控制臺,總是找不到模擬器.
一般是端口問題,需要手工指定端口,比較麻煩,棄之。
試AS自帶的Android Monitor,立馬連上了
如下圖所示,右邊開著海馬玩模擬器運行android apk,左邊是顯示的adb log。

然而,問題來了:AS會經常顯示顯示offline 或者disconnect,明明剛剛用的好好的,怎么突然不行了。一度懷疑過是不是剛打包問題改了sdk版本導致的,重新更換回去也不行。
接著試試各種方法:
1). adb restart
2). 更新 sdk tools, sdk platform tools
。。。
還是不行,
換個mumu模擬器就好了,經多次實踐發現 AS adb調試,設備會是不是連不上,我的解決方法很暴力,重啟AS,重啟模擬器,再不行,換另一個模擬器就好了,有其他小伙伴遇到這個問題嗎?告訴我解決方法,謝謝!

  1. unity打android包之后,模擬器安裝運行運行。
    unity調用android打開Toast,Dialog,打log都沒問題,但是打開android的activity時找不到class,報錯:
    No package identifier when getting name for resource number 0x00000000
    Caused by: java.lang.NoClassDefFoundError: com.test.unity.Main2Activity
    這個是重磅錯誤,打開jar包發現class明明就在里面

先說我的解決方法:
經過各種嘗試發現,unity要打開android studio的activity,需要以下條件:

  1. android studio 打出aar包 + unity5.x (支持aar包) ,必須用aar包 + AndroidManifest.xml,android studio打出的aar包解壓后得到的jar文件,
    內部是沒有R.class文件的,會導致找不到資源,猜測若要使用eclipse的工程結構,需想辦法打出包含R.class的jar包,目前未嘗試。
    2.Android 主activity 需繼承AndroidPlayerActivity
    3.AndroidJavaClassjc=newAndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObjectjo=jc.GetStatic("currentActivity"); jo.Call("方法");
    必須使用UnityPlayer,然后獲取currentActivity,再去調用方法。

分析AS 與Eclipse導出android包的區別
AS打jar包有2種方式,
在gradle文件中寫命令: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)//在終端執行生成JAR包// gradlew makeJar
在Terminal中鍵入 gradlew makeJar 回車看到如下所示就OK了:
build 出aar包,解壓縮得到jar包;
這里我采用的第二種方式。
unity也支持兩種結構的android plugin,
unity4.x支持eclipse工程結構的android plugin,
unity5.x即支持eclipse工程結構的android plugin,也支持android studio導出的aar包 + AndroidManifest.xml。
兩種方式都試過,容我細細道來。

1. AS打出的jar包有問題?

找到的例子里都是用的Eclipse工程結構,(UNITY3D游戲開發之UNITY與ANDROID交互調用研究)這個例子里unity能夠正常打開android的界面,有demo可下載。
于是將AS的android包與eclipse工程的plugins/Android 包比較,發現jar包不同,AS的jar包里缺少了R.class。
那么AS怎樣才能打出帶R.class的jar包? 目前未嘗試成功

2. Android 主activity 需繼承AndroidPlayerActivity


如果Android項目需要用到android 的activity,主Activity.java 是需要繼承AndroidPlayerActivity的;

3. unity調用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)直接使用真實的Class名:com.test.unity.MainActivity"
2)使用UnityPlayer,然后獲取currentActivity,再去調用方法。
結論: 簡單的功能,如打印日志,打開android的Toast, dialog,兩種方法都可以,但是打開android activity必須使用2),1)無法打開。

4 Unity調用Android的靜態和非靜態方法

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中打開,區別有待研究。
6)Android向Unity發消息
Android代碼:
UnityPlayer.UnitySendMessage("GameManager","HelloFromAndroid","Hello!");
Unity代碼:
usingUnityEngine; publicclassGameManager : MonoBehaviour { publicvoidHelloFromAndroid(stringdataReceived) { Debug.Log("Received data from Android plugin: "+ dataReceived); } }

7.解決NoClassDefFoundError問題的過程中還會遇到下面問題

  java.lang.NoClassDefFoundError: com.test.unity.R$layout 找不到資源文件
  java.lang.NoSuchMethodError  找不到方法,

按照上述我的解決方法可以解決這些報錯:

目前的方案只是一種解決辦法,
要想使用Eclipse工程結構的android包,主要問題還是在jar包上,解壓aar包發現有R.txt,而解壓出的jar包沒有R.class,若想使用eclipse的工程結構的android包,就需要打出合適的jar包,無奈嘗試gradle makeJar出錯,待有時間再試試這種直接build jar包的方法。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,333評論 25 708
  • afinalAfinal是一個android的ioc,orm框架 https://github.com/yangf...
    passiontim閱讀 15,556評論 2 45
  • 小伙伴轉發了一篇劉潤“5分鐘商學院”中的文章《如何用20小時快速學習?》,并疑惑地問:笑來老師提倡只字不差地閱讀,...
    為自己出征閱讀 619評論 2 6
  • 隨筆集|魚非 【清、靜、淺、涼,我只悟透了它的三分之一】 流水, 你了解它幾分? 只是清與混? 還是淺和深? 亦或...
    魚非阿閱讀 186評論 2 3