现在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.jianshu.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,重启模拟器,再不行,换另一个模拟器就好了,有其他小伙伴遇到这个问题吗?告诉我解决方法,谢谢!
- 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,需要以下条件:
- 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包的方法。