NordicSemiconductor / Android-DFU-Library

Device Firmware Update library and Android app
http://www.nordicsemi.com/dfu
BSD 3-Clause "New" or "Revised" License
753 stars 263 forks source link

[Unity] NoClassDefFoundError: LocalBroadcastManager #224

Open SunSailor75 opened 4 years ago

SunSailor75 commented 4 years ago

Device information (please complete the following information):

Describe the bug Starting with Android 8.1, the LocalBroadcastManager used within the library has been moved to AndroidX. Due to reasons, we had to raise the minimal platform, so we ran into this. I had some issues to get the project compiling again, but that works now. Currently, I'm using a download of the archive from today (25.03.2020, 12:00). After putting the resulted dfu library and our wrapper library into the Unity project and building the project, I now get an exception, that the LocalBroadcastManager class can not be found. Which seems to be true, because it is not contained in any of the AARs. I'm using the unmodified project from this project, so I guess, this is at least a first step for the solution. I read about a lot of this porting issue, where in most cases it was enough to add

implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'

but this is already contained in the project now. In a previous download, a few weeks ago, I still had to convert the project with Android Studio. But still, the problem remains.

Logs

03-24 12:59:55.650  3675  3711 E Unity   : AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/localbroadcastmanager/content/LocalBroadcastManager;
03-24 12:59:55.650  3675  3711 E Unity   : java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/localbroadcastmanager/content/LocalBroadcastManager;
03-24 12:59:55.650  3675  3711 E Unity   :      at no.nordicsemi.android.dfu.DfuServiceListenerHelper.unregisterProgressListener(DfuServiceListenerHelper.java:329)
03-24 12:59:55.650  3675  3711 E Unity   :      at com.nukklear.drift_dfu_lib.DriftDFU.StopDFU(DriftDFU.java:100)
03-24 12:59:55.650  3675  3711 E Unity   :      at com.nukklear.drift_dfu_lib.drift_dfu_static.StopDFU(drift_dfu_static.java:32)
03-24 12:59:55.650  3675  3711 E Unity   :      at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
03-24 12:59:55.650  3675  3711 E Unity   :      at com.unity3d.player.UnityPlayer.c(Unknown Source:0)
03-24 12:59:55.650  3675  3711 E Unity   :      at com.unity3d.player.UnityPlayer$e$2.queueIdle(Unknown Source:72)
03-24 12:59:55.650  3675  3711 E Unity   :      at android.os.MessageQueue.next(MessageQueue.java:395)
03-24 12:59:55.650  3675  3711 E Unity   :      at android.os.Looper.loop(Looper.java:181)
03-24 12:59:55.650  3675  3711 E Unity   :      at com.unity3d.player.UnityPlayer$e.run(Unknown Source:32)
03-24 12:59:55.650  3675  3711 E Unity   : Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.localbroadcastmanager.content.LocalBroadcastManager" on path: DexPathList[[zip fil

Edit: This was opened and ment to be a question, somehow the bug label is set. Currently trying to find out, how to change that, sorry.

philips77 commented 4 years ago

After adding dependency to local broadcast manager 1.0.0 you should have it in the APK. If you are using DFU in a library, try changing implementation to api, so that your app can see internal dependencies. We have no experience with Unity. Sorry. Try asking on StackOverflow.

SunSailor75 commented 4 years ago

What I did now - to bring it down to a more Android level - was to export the Unity project into Android Studio, so we have a plain android project from here. Still, had the same problem, even with the api change. What I did then was to add the implementations under the projects dependencies. This brought the whole thing a bit further, as I don't get the LocalBroadcaster exception anymore. Instead, the app crashes hard, which was the issue from the beginning. Reading the system logs, it shows, that now I get this exception, which seems to be not caught properly:

03-26 14:14:40.439  7882  8490 E AndroidRuntime: FATAL EXCEPTION: IntentService[DfuBaseService]
03-26 14:14:40.439  7882  8490 E AndroidRuntime: Process: com.sturmkind.drift, PID: 7882
03-26 14:14:40.439  7882  8490 E AndroidRuntime: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/core/app/NotificationCompat$Builder;
03-26 14:14:40.439  7882  8490 E AndroidRuntime:    at no.nordicsemi.android.dfu.DfuBaseService.startForeground(DfuBaseService.java:1805)
03-26 14:14:40.439  7882  8490 E AndroidRuntime:    at no.nordicsemi.android.dfu.DfuBaseService.onHandleIntent(DfuBaseService.java:1121)
03-26 14:14:40.439  7882  8490 E AndroidRuntime:    at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:76)
03-26 14:14:40.439  7882  8490 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:106)
03-26 14:14:40.439  7882  8490 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:214)
03-26 14:14:40.439  7882  8490 E AndroidRuntime:    at android.os.HandlerThread.run(HandlerThread.java:65)
03-26 14:14:40.439  7882  8490 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.NotificationCompat$Builder" on path: DexPathList[[zip file "/data/app/com.sturmkind.drift-h4F2nEwKFtmc05lsS2pAog==/base.apk"],nativeLibraryDirectories=[/data/app/com.sturmkind.drift-h4F2nEwKFtmc05lsS2pAog==/lib/arm64, /data/app/com.sturmkind.drift-h4F2nEwKFtmc05lsS2pAog==/base.apk!/lib/arm64-v8a, /system/lib64]]

This worries me a lot now, because the NotificationCompat is part of

implementation 'androidx.core:core:1.3.0-alpha01'

Any ideas? This is becoming a mission critical issue for my client.

philips77 commented 4 years ago

Is your project migrated to AndroidX? I found this page: https://stackoverflow.com/questions/53141800/java-lang-noclassdeffounderror-failed-resolution-of-landroidx-core-app-activit

philips77 commented 4 years ago

Also, this one: https://forum.unity.com/threads/unity-android-plugin-error-java-lang-noclassdeffounderror-failed-resolution-of-java-class.344715/

SunSailor75 commented 4 years ago

Funny, I already had answered this, but somehow my reply is gone. So second try.

That is the way I already went, the whole project has been upgraded to AndroidX and

android.enableJetifier=true
android.useAndroidX=true

are set in gradle.properties.

I now tried to create a fat aar, with the library not being self-compiled, but referenced to the marven repository. But the same problem persists, it seems to be impossible for the DFULibrary to find the NotificationCompat$Builder class. I can verify, that it is contained in the Fat-AAR, as well as in the APK, in both cases in the classes.jar. This brings me down, that this must be an issue with the DFULibrary not being able to read the classpath correctly.

For the sake of completeness, we even added the follwing:

// Enable Notification Channel for Android OREO
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Context ctx = getApplicationContext();
            DfuServiceInitiator.createDfuNotificationChannel(ctx);
        }

as the problems originally occured with the pre-AndroidX build crashing from Android 8.1 upwards.

philips77 commented 4 years ago

Hello, did you manager to solve the issue? Can we close it here?

knightLin0211 commented 3 years ago

I have the same problem. I use DFU Library,but Unity give me an error

UnityEngine.AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Lno/nordicsemi/android/dfu/DfuProgressListenerAdapter;

Later, I transplanted all the java files of the DFU Library to my project, and the package name was also changed to my package name. Yes Unity dosen't give me UnityEngine.AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Lno/nordicsemi/android/dfu/DfuProgressListenerAdapter; but it gave me the same error message

AndroidPlayer(ADB@127.0.0.1:34999) AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/localbroadcastmanager/content/LocalBroadcastManager;

My targetSdkVersion is 30 and I use implementation

androidx.localbroadcastmanager:localbroadcastmanager:1.0.0

gradle.properties also have

android.useAndroidX=true
android.enableJetifier=true

Is there any solution?

philips77 commented 3 years ago

Hi, did you manager to solve your problem? We don't have any experience with Unity. Did you try asking your question on StackOverflow or some Unity forum?

knightLin0211 commented 3 years ago

No, I haven't solved this problem. I searched the forum and didn't see similar problems. So that's why I came here.