Unity与Android(Android Studio)交互及

作者: 菲得更高 | 来源:发表于2017-05-11 10:11 被阅读1234次

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

    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调用unity可以么?
        万年场保安:@菲得更高 请教大神,我在实际使用中还遇到一个问题,unityPlayer不能与android控件、布局重叠,

        如果在unityPlayer上放置android的布局,布局会无法显示。我查资料是因为surfaceview不能与布局重叠的原因?
        请问大神遇到过这个问题没?请问你是怎么解决这个问题的?

        我是用的WindowManager,但是效果非常不理想,只能addView一个控件并且位置也有问题。请问还有其他解决这个问题的思路么?
        菲得更高:可以, UnityPlayer.UnitySendMessage("Manager", "ZoomIn", ""); 第一个参数是Game Object对象,所以需要在游戏对象上绑定脚本,第二个参数是unity中定义的方法名,第三个参数是定义方法的参数(可空)。

      本文标题:Unity与Android(Android Studio)交互及

      本文链接:https://www.haomeiwen.com/subject/hizntxtx.html