Unity Error: Unable to convert classes into dex format

Unity Error: Unable to convert classes into dex format

我创建了一个 Android Unity 插件(.aar 文件),它为我的 Unity 游戏提供了一些自定义定位数据。在我的 Unity 脚本中,我使用

var x = customClass.CallStatic<float>("getHeadX");

为了获取一些位置数据。每帧调用此方法以获取更新的数据(轮询方法),这使其效率低下。相反,我决定在更新数据准备就绪时从我的 java 代码(插件端)调用我的 Unity 脚本中的 C# 方法。为此,我在 java 插件中写道,

import com.unity3d.player.UnityPlayer;
...
UnityPlayer.UnitySendMessage("Manager", // gameObject name
                             "PluginCallback", // this is a callback in C# 
                             "Hello from android plugin"); // msg which is not needed actually

然而,编译器抱怨包 com.unity3d.player.UnityPlayer 不存在。所以我从

复制了 classes.jar 文件

C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes \classes.jar

进入我的 android 插件项目的 'libs' 文件夹。我成功构建它并将生成的 .aar 文件 (mylibrary-release.aar) 复制到我的 Unity 项目的 Assets\Plugins\Android 文件夹中。

当我构建 Unity 项目时(使用 'Internal' 构建系统),它给我这个错误:

IOException: Failed to Move File / Directory from 'Temp/StagingArea\android-libraries\mylibrary-release\classes.jar' to 'Temp/StagingArea\android-libraries\mylibrary-release\libs\classes.jar'. UnityEditor.Android.PostProcessor.Tasks.ProcessAAR.Execute ...

发生此错误是因为 classes.jar 依赖项与 classes.jar 名称冲突(由我的插件统一生成)。所以我将依赖项名称更改为 unity_classes.jar 这解决了问题但是现在我在构建我的统一应用程序时遇到了一个新错误:

CommandInvokationFailure: Unable to convert classes into dex format. C:/Program Files/Java/jdk1.8.0_102\bin\java.exe -Xmx2048M Dcom.android.sdkmanager.toolsdir="C:/Users/kamran.shamloo/AppData/Local/Android/Sdk\tools" -Dfile.encoding=UTF8 -jar "C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines\AndroidPlayer/Tools\sdktools.jar"

stderr[ Uncaught translation error: java.lang.IllegalArgumentException: already added: Lbitter/jnibridge/JNIBridge; Uncaught translation error: java.lang.IllegalArgumentException: already added: Lbitter/jnibridge/JNIBridge$a; Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/NativeLoader; Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/ReflectionHelper; Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/ReflectionHelper; Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/ReflectionHelper$a; Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/UnityPlayer; Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/UnityPlayer; Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/UnityPlayer; ...

Unityclasses.jar(您后来将其重命名为 'unity_classes.jar')自动包含到构建的 .apk 中,因此您不应该自己再次包含它(在您的 Android 插件中),即使使用不同的名称

换句话说,首先你的 android 插件 "embeds" 这个 .jar 文件本身。然后,当 Unity 将您的插件添加到游戏项目时,它还会添加自己的 .jar 文件副本(它对所有 android 项目都这样做)。因此,Unity 基本上最终在项目中拥有同一个 .jar 文件的 2 个副本,并通过 'unable to convert classes into dex format'.

来抱怨

所以虽然你必须在你的项目中使用这个库(.jar 文件)但是你不应该将这个库与你的项目捆绑在一起。怎么做?如果您正在使用 Android studio,您可以通过将 .jar 文件标记为 provided scope 的依赖项来实现此目的。

为此,您可以:

1) 转到模块的 'build.gradle' 并更改此内容:

compile files('libs/jars/unity_classes.jar')

对此:

provided files('libs/jars/unity_classes.jar')

2) 您可以右键单击模块(在 Android 窗格中)并选择 打开模块设置 。然后转到 Dependencies 选项卡。找到 Unity 模块(我将其重命名为 unity_classes.jar)并将其范围更改为 Provided.