Unity 调用activity及其布局方法 如果 仅仅是调用android里面的方法 不涉及到布局,仅需要导出相关的Jar包就可以,但是如果我想调用android的activity以及相关的布局,仅仅导出Jar是不够的。如果我们想android布局和unity布局混杂使用,设想一个需求,用户需要在Unity渲染图片,而图片列表和选择需要在android里面做,然后将选中的路径传递给unity。 按照此需求 进行说明:前提是按照常规的jar的方法,将unity下的android的 class复制到android下。 1. 首先完成Unity场景 ChoiceScene,此场景添加两个button,视频选择,图片选择。 2. 每当点击这两个按钮,调用android 里面的方法: public static void StartPanoramaActivity(Context context) { Intent intent = new Intent(context, PanoramaImageListActivity.class); context.startActivity(intent); } public static void StartLocalVideoActivity(Context context) { Intent intent = new Intent(context, FullViewVideoListActivity.class); context.startActivity(intent); } 通过代码我们可以看到 这是启动两个android 下的activity,上述两个方法 放在CommonUtil这个静态类下面,unity调用 : public static void StartPanoramaActivity() { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); AndroidJavaClass CommonUtil = new AndroidJavaClass("com.goertek.play360.CommonUtil"); CommonUtil.CallStatic("StartPanoramaActivity", jo); } public static void StartLocalVideoActivity() { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); AndroidJavaClass CommonUtil = new AndroidJavaClass("com.goertek.play360.CommonUtil"); CommonUtil.CallStatic("StartLocalVideoActivity", jo); } 这里和普通jar包没有区别,但是如果你仅仅通过jar包方式调用的话,当点击按钮的时候程序崩溃,因为在activy里面listview=(ListView) findViewById(R.id.list); listview.setAdapter(mImageListAdapter); 这时候说对象为空,如果仅仅运行android的程序,完全是正常的。这时候把res 也复制到unity里面,这个问题就解决了,但是找不到R.layout.这个时候我在生成jar包的时候把res和gen都选,又报错。或者我直接把bin直接导成jar,因为bin下面包含了res和class,可是还没有解决。也就是说 通过export 导出jar,在导出的时候 选择不同的选项 或者全选都通不过。 3. 我经过测试 通过的方法是:将程序 android 属性中IsLibrary 打勾,然后clean(不clean没测试过,这是我的习惯),然后run,这个时候就会在bin下面生成一个jar,我觉得这个方法,比我们自己导要好一些,毕竟是系统做的,然后将gen和res,jar包同时放到unity android中。测试通过。 4. 这里最好每次生成新jar的时候,将新的gen也换掉,我没有测试过没换的情况,如果你仅仅添加方法,而没有增删布局。 5. 这里还发现一个问题 unity下manifest.xml: <activity android:name="com.google.unity.GoogleUnityActivity" android:label="@string/app_name" android:screenOrientation="landscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="com.google.intent.category.CARDBOARD" /> </intent-filter> <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> </activity> Android manifest: <activity android:name="com.goertek.play360.MainActivity" android:screenOrientation="portrait" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> MainActivity 也是继承了UnityActivity,我并没有将android下的此xml复制到unity下,仅仅将unity需要启动的两个activity添加到unity下的xml,这个时候程序一样运行,即使我在unityxml里面没有添加 android:name="com.goertek.play360.MainActivity",这个还是优先于GoogleUnityActivity启动,GoogleUnityActivity没有启动。所以android 下的xml没有必要和unity一致,仅仅需要将用到的权限,启动的activity等加入即可,通过上面可以观察到unity自己会去寻找启动相关的UnityActivity。 如果在android 使用 UnityPlayer.UnitySendMessage("Sphere360", "RefreshParanaFilePath", imagePath); 他是告诉一个场景下叫Sphere360的对象,去执行RefreshParanaFilePath这个方法,但是即使我这个场景编辑到了unity运行环境中,但是没有运行过,那么就接收不到android传来的信息。这点类似于android的动态广播机制,不执行不接收。
附件和上面的一样,没有测试代码,因为我是在实际工程中测试的