Android Unity3D 相互交互,及退出继承UnityPlayerActivity的Crash问题

这是我第一次写博文,只是我做过项目的一些技术点,也就相当于自己的笔记,希望能对看到文章的你有用。
公司项目比较多使用AR,一般我们都是使用第三方SDK,使用的EasyAR。它有两种方式来实现AR功能,第一种是用JNI,使用NDK(自行百度google查找相关技术文章),第二种是Android和Unity3D的交互,Ar图形,模型视频等由Unity3D来完成,Android来处理 加载创建 扫描 脱卡等事件处理(着重讲这部分)。

Unity导出的项目:

我记录Android这部分的操作 不记录Unity3D的
首先你要让Unity的工程师导出一份Android项目给你,当然导出的AS项目(我没用过Eclipse的方式)

Unity导出项目结构.png

lib文件下面是要使用的Jar包
src中包括了assets,jniLibs和java文件夹下的UnityPlayerActivity,UnityPlayerNativeActivity,UnityPlayerProxyActivity.建议使用UnityPlayerActivity.java,assets文件中是unity的一些资源文件,包括了场景和渲染的一些文件,jniLibs当然是所用到的.so文件了

  • 如果你已经有Android的工程项目了,此时你只需要把assets的文件和lib中的文件,和jniLibs的文件拷贝到你的项目中去,然后把需要配置的类和权限在AndroidManifest.xml中配置一下(EasyAR需要用到摄像头的权限,在6.0以上的版本也无需去申请权限,SDK中有集成了。如果你不放心 可以再去申请)
  • 没有项目,那么只需要把unity的导出项目直接导入到你的Android Studio中即可。
    下面就是我导入完成后的项目结构图
项目结构.png

ArMapActivity的布局

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- unity3d layout -->
    <LinearLayout
        android:id="@+id/layout_unity"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    </LinearLayout>
    <!-- 这边可以加入覆盖到unity的layout -->
 </FrameLayout>
先介绍一下 两者之间的调用方法的方式:
Android调用Unity的方法

UnityPlayer.UnitySendMessage("ImageTargetManager", "LoadNativeAssetBundle", json);

  • 第一个参数"ImageTargetManager"是Unity Object对象,需要在Unity对象上绑定脚本】
  • 第二个参数"LoadNativeAssetBundle"是Unity 中定义的方法名 (这两个都是Unity工程师会提供给你的)
  • 第三个参数是定义方法的参数(可空)。
Unity调用Android的方法

先在Android自定义一个方法

Android代码
 /**
   * Unity调用此方法并把参数jsonString 调用给Android
   * @param jsonString
   */
 public void Unity3DSendMessage(String jsonString) {
        Log.i("TAG", "[Unity3DSendMessage] " + jsonString);
        final JsonRetrun entity = new Gson().fromJson(jsonString, JsonRetrun.class);
        switch (entity.getActionName()) {
            case "sceneLoaded":
                break;
            case "loadModelAssetCompleted":
                break;
            case "imageTargetBound":
                break;
            case "imageTargetBoundFail":
                break;
            case "TargetFound":
                break;
            case "TargetLost":
                break;
            default:
                break;
        }
    }
Unity代码
AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("ArMapActivity");
jo.Call ("Unity3DSendMessage","");

jo.call(String str1,String str2);第一个参数是Android的方法名,第二个参数是传递给Android的参数

到这边已经把Android交互Unity的方法方式介绍完成了

发现的一个坑

当你使用玩AR时 点击系统返回或者是自定义的ImageButton返回时, 如果你调用的是onDestroy方法,你会发现应用出现了Crash,如果你单单在点击事件中 finish();该Activity,也会出现Crash。
UnityPlayerActivity中onDestory方法是这么写的

@Override  
protected void onDestroy()  
{  
       mUnityPlayer.quit();  
       super.onDestroy();          
}  

这样写 会使后面的代码不执行了,从而造成Crash
对mUnityPlayer.quit()方法的反编译之后 发现quit方法是这样的

public void quit() {
    this.k = true;
    if(!this.e.e()) {
        this.pause();
    }

    this.a.a();

    try {
        this.a.join(4000L);
    } catch (InterruptedException var1) {
        this.a.interrupt();
    }

    if(this.g != null) {
        this.h.unregisterReceiver(this.g);
    }

    this.g = null;
    if(l.c()) {
        this.removeAllViews();
    }

    if(i.b) {
        i.g.a(this.h);
    }

    this.kill();
    h();
}

注意倒数第二行的this.kill()方法,不看实现可以猜出应该是杀进程的。所以...

我google百度了不少时间发现了 可以在该Activity的AndroidManifest.xml中设置一个新的进程。这样,就不会影响你本身项目的进程

AndroidManifest设置.png

这样设置之后,虽然解决了不会崩溃问题,但是有时候退出Activity时会卡住一段时间。
我在搜索mUnityPlayer.quit()的时候还看到别人针对这个问题做了另外一种解决,就是重写UnityPlayer类的kill方法(就是上面提到的kill方法,然后再去调用自己重写的方法即可
重写的例子如下:

public class MyUnityPlayer extends UnityPlayer {

    public MyUnityPlayer(ContextWrapper contextWrapper) {
        super(contextWrapper);
    }

    //不执行父类的方法
    @Override
    protected void kill() {

    }
}

然后在有Unity的ArMapActivity中

@Override  
protected void onCreate(Bundle savedInstanceState)  
    {  
      super.onCreate(savedInstanceState);  
      mUnityPlayer = new MyUnityPlayer(this); 
      layoutUnity.addView(mUnityPlayer);
      mUnityPlayer.requestFocus();
    }  

这样子,就能解决退出Activity不Crash,并且响应速度也比较快。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容