【问题标题】:Problems merging multiple AndroidManifest.xml合并多个 AndroidManifest.xml 的问题
【发布时间】:2017-07-21 07:14:35
【问题描述】:

我正在开发一个在 Android 上运行的 Unity 应用程序(我们称之为 App A)。我必须将一些代码从另一个 Android Unity 应用(应用 B)移动到我的 Unity 应用中。

我需要移动到 App A 的这段代码负责查询 IMU(内部测量单元)。这是App B中存在的相关代码

AndroidJavaObject ActivityObject;
AndroidJavaClass ActivityClass;

AndroidJNI.AttachCurrentThread();
ActivityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
ActivityObject = ActivityClass.GetStatic<AndroidJavaObject>("currentActivity");

tagID = ActivityObject.Call<string>("getTAGID");

这是应用 B 的清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.indotraq.rtls" android:versionName="1.0.0" android:versionCode="1">

  <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
  <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" android:debuggable="false">

    <meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>

    <activity
            android:name="com.indotraq.android.rtls.MainActivity"
            android:screenOrientation="landscape" 
            android:launchMode="singleTask"
            android:configChanges="screenSize|orientation|keyboardHidden|keyboard"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                 <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/> 
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
            <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
             <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" /> 
    </activity>

  </application>

  <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
  <uses-feature android:glEsVersion="0x00020000" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.BLUETOOTH" />
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
</manifest>

这是来自 App A 的清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.sensics.palace" android:versionName="1.0" android:versionCode="1" android:installLocation="preferExternal">
  <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
  <application android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="false">
    <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="@string/app_name" android:screenOrientation="sensorLandscape" 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="android.intent.category.LEANBACK_LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
      <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
    </activity>
  </application>
  <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="25" />
  <uses-feature android:glEsVersion="0x00020000" />
  <supports-gl-texture android:name="GL_AMD_compressed_ATC_texture" />
  <supports-gl-texture android:name="GL_ATI_texture_compression_atitc" />
  <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <uses-permission android:name="android.permission.INTERNET" /> 
</manifest>

我需要将应用 B 的清单的相关部分复制到应用 A 的清单中,这就是我卡住的地方。

所以在 App A 中,有一个辅助线程。这个线程的存在是为了让我们的应用程序可以在应用程序进入后台时进行一些处理。这个线程已经存在了很长时间,当App A进入后台时,尽职尽责的运行继续执行。

我确实尝试了各种方法来将清单文件合并在一起。我尝试的第一件事是将活动合并为一个。我发现,除非活动被命名为“com.unity3d.player.UnityPlayerNativeActivity”,否则当应用程序进入后台时,我的后台线程不会运行。

这是我最近尝试的清单。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.indotraq.rtls" android:versionName="1.0.0" android:versionCode="1">

  <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
  <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" android:debuggable="false">

    <meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
    <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="@string/app_name" android:screenOrientation="sensorLandscape" 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="android.intent.category.LEANBACK_LAUNCHER" />
            <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
        </intent-filter>
        <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
        <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" />
    </activity> 
    <activity
            android:name="com.indotraq.android.rtls.MainActivity"
            android:screenOrientation="landscape" 
            android:launchMode="singleTask"
            android:configChanges="screenSize|orientation|keyboardHidden|keyboard"
            android:label="@string/app_name" >
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
            <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
    </activity>
  </application>

  <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
  <uses-feature android:glEsVersion="0x00020000" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.BLUETOOTH" />
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
</manifest>

有了这个清单,我的线程在后台运行得很好,但是这段代码

  LogManager.Log("At pos 1");
  AndroidJNI.AttachCurrentThread();
  LogManager.Log("At pos 2");
  ActivityClass = new AndroidJavaClass("com.indotraq.android.rtls.MainActivity");

  if(ActivityClass == null) {
    LogManager.Log("ActivityClass == null");
  }
  else {
    LogManager.Log("ActivityClass != null");
  }

  LogManager.Log("At pos 3");
  ActivityObject = ActivityClass.GetStatic<AndroidJavaObject>("currentActivity");
  LogManager.Log("At pos 4");

  tagID = ActivityObject.Call<string>("getTAGID");
  LogManager.Log("At pos 5");

产生这个输出。

位置 1 位置 2 ActivityClass != null 位置 3
AndroidJavaException:java.lang.NoSuchFieldError:否 “Ljava/语言/对象;”类中的字段“currentActivity” “Lcom/indotraq/android/rtls/MainActivity;”或其超类
java.lang.NoSuchFieldError:没有“Ljava/lang/Object;”场地 “Lcom/indotraq/android/rtls/MainActivity;”类中的“currentActivity” 或其超类 在 com.unity3d.player.UnityPlayer.nativeRender(本机方法) 在 com.unity3d.player.UnityPlayer.c(未知来源) 在 com.unity3d.player.UnityPlayer$c$1.handleMessage(未知来源) 在 android.os.Handler.dispatchMessage(Handler.java:98) 在 android.os.Looper.loop(Looper.java:145) 在 com.unity3d.player.UnityPlayer$c.run(未知来源) 在 UnityEngine.AndroidJNISafe.CheckException () [0x00000] in :0 在 UnityEngine.AndroidJNISafe.GetStaticFieldID (IntPtr clazz, System.String name, System.String sig) [0x00000] in :0 在 UnityEngine._AndroidJNIHelper.GetFieldID (IntPtr jclass,System.String 字段名,System.String 签名,布尔值 isStatic) [0x00000]

如果我能深入了解我需要做些什么来完成这项工作,我们将不胜感激。

谢谢 约翰·劳里

【问题讨论】:

  • 可能是因为 android:minSdkVersion="xx" android:targetSdkVersion="xx"。我以前也有类似的。我使这些版本号在两者中都相等,我的意思是你有 2 个清单文件。我为它们使用了较低的值。瞧!我的问题解决了。不知道您的线索,但这可能会有所帮助

标签: c# android multithreading unity3d


【解决方案1】:

正如错误所述,您的com.indotraq.android.rtls.MainActivity 类中没有“currentActivity”字段。 currentActivitycom.unity3d.player.UnityPlayer 的成员。您可以在类中创建一个静态字段并在 MainActivity 的构造函数中自己分配它。这样的事情就可以了

public class MainActivity extends AppCompatActivity
{
  static public MainActivity currentActivity;
  MainActivity()
  {
    currentActivity = this;
  }

}  

那么就可以成功调用非静态方法tagID = ActivityObject.Call&lt;string&gt;("getTAGID");

PS:它实际上并没有获得“活动”,只是类的实例,所以currentInstance会更合适。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2013-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-13
相关资源
最近更新 更多