DragonX-cloud / dji_flutter_plugin

A Flutter plugin for DJI SDK.
BSD 3-Clause "New" or "Revised" License
34 stars 8 forks source link

Platform exception PlatformException(NoClassDefFoundError, java.lang.NoClassDefFoundError #22

Closed DanielZelei closed 1 year ago

DanielZelei commented 1 year ago

Hello @orenagiv,

First of all, thank you for this project !

I tried to build & run the example project from Android Studio to my Android device (Samsung Galaxy S20). The app is running, but when I try to press "Register" I get the following error (basically I always get this error if I press any button in the example app):

Launching lib/main.dart on SM G781B in debug mode...
Running Gradle task 'assembleDebug'...
✓  Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app-debug.apk...
W/FlutterActivityAndFragmentDelegate(10176): A splash screen was provided to Flutter, but this is deprecated. See flutter.dev/go/android-splash-migration for migration steps.
Debug service listening on ws://127.0.0.1:44529/tbgZmYAIMLA=/ws
Syncing files to device SM G781B...
I/BLASTBufferQueue(10176): [SurfaceView[cloud.dragonx.plugin.flutter.djiExample/cloud.dragonx.plugin.flutter.dji_example.MainActivity]@0#1](f:0,a:0) onFrameAvailable the first frame is available
D/SurfaceView@39fb67a(10176):  setAlpha: mUseAlpha = false alpha=1.0
D/SurfaceView@39fb67a(10176):  updateSurfaceAlpha: setUseAlpha() is not called, ignored.
I/tter.djiExample(10176): Compiler allocated 6133KB to compile void android.view.ViewRootImpl.performTraversals()
I/ViewRootImpl@572ad64[MainActivity](10176): ViewPostIme pointer 0
I/ViewRootImpl@572ad64[MainActivity](10176): ViewPostIme pointer 1
I/flutter (10176): This is a debug message
I/flutter (10176): Registering app ...
D/=== DjiPlugin Android(10176): Register App Started
[dji.flutter] registerApp requested
W/tter.djiExample(10176): Accessing hidden method Lcom/android/org/conscrypt/OpenSSLProvider;-><init>()V (unsupported,core-platform-api, reflection, allowed)
W/tter.djiExample(10176): Accessing hidden method Lcom/android/org/conscrypt/OpenSSLRandom;-><init>()V (unsupported, reflection, allowed)
W/tter.djiExample(10176): Accessing hidden method Landroid/app/ActivityThread;->currentActivityThread()Landroid/app/ActivityThread; (unsupported, reflection, allowed)
W/tter.djiExample(10176): Accessing hidden method Landroid/app/ActivityThread;->getApplication()Landroid/app/Application; (unsupported, reflection, allowed)
I/flutter (10176): Platform exception PlatformException(NoClassDefFoundError, java.lang.NoClassDefFoundError: Failed resolution of: Ldji/sdk/sdkmanager/DJISDKManager$SDKManagerCallback;, Cause: java.lang.ClassNotFoundException: Didn't find class "dji.sdk.sdkmanager.DJISDKManager$SDKManagerCallback" on path: DexPathList[[zip file "/data/app/~~lriWWfQIhkZ9hX_Tp7mpPQ==/cloud.dragonx.plugin.flutter.djiExample-9HouSjVEpQTB_Vp3VznKiQ==/base.apk"],nativeLibraryDirectories=[/data/app/~~lriWWfQIhkZ9hX_Tp7mpPQ==/cloud.dragonx.plugin.flutter.djiExample-9HouSjVEpQTB_Vp3VznKiQ==/lib/arm64, /data/app/~~lriWWfQIhkZ9hX_Tp7mpPQ==/cloud.dragonx.plugin.flutter.djiExample-9HouSjVEpQTB_Vp3VznKiQ==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]], Stacktrace: java.lang.NoClassDefFoundError: Failed resolution of: Ldji/sdk/sdkmanager/DJISDKManager$SDKManagerCallback;
I/flutter (10176):  at io.flutter.plugins.GeneratedPluginRegistrant.registerWith(GeneratedPluginRegistrant.java:24)
[dji.flutter] registerApp PlatformException Error
I/flutter (10176):  at java.lang.reflect.Method.invoke(Native Method)
I/flutter (10176):  at io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister.registerGeneratedPlugins(GeneratedPluginRegister.java:80)
I/flutter (10176):  at io.flutter.embedding.android.FlutterActivity.configureFlutterEngine(FlutterActivity.java:1302)
I/flutter (10176):  at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.onAttach(FlutterActivityAndFragmentDelegate.java:214)
I/flutter (10176):  at io.flutter.embedding.android.FlutterActivity.onCreate(FlutterActivity.java:641)
I/flutter (10176):  at android.app.Activity.performCreate(Activity.java:8591)
I/flutter (10176):  at android.app.Activity.performCreate(Activity.java:8570)
I/flutter (10176):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
I/flutter (10176):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4150)
I/flutter (10176):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4325)
I/flutter (10176):  at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
I/flutter (10176):  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
I/flutter (10176):  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
I/flutter (10176):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2574)
I/flutter (10176):  at android.os.Handler.dispatchMessage(Handler.java:106)
I/flutter (10176):  at android.os.Looper.loopOnce(Looper.java:226)
I/flutter (10176):  at android.os.Looper.loop(Looper.java:313)
I/flutter (10176):  at android.app.ActivityThread.main(ActivityThread.java:8757)
I/flutter (10176):  at java.lang.reflect.Method.invoke(Native Method)
I/flutter (10176):  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
I/flutter (10176):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
I/flutter (10176): Caused by: java.lang.ClassNotFoundException: Didn't find class "dji.sdk.sdkmanager.DJISDKManager$SDKManagerCallback" on path: DexPathList[[zip file "/data/app/~~lriWWfQIhkZ9hX_Tp7mpPQ==/cloud.dragonx.plugin.flutter.djiExample-9HouSjVEpQTB_Vp3VznKiQ==/base.apk"],nativeLibraryDirectories=[/data/app/~~lriWWfQIhkZ9hX_Tp7mpPQ==/cloud.dragonx.plugin.flutter.djiExample-9HouSjVEpQTB_Vp3VznKiQ==/lib/arm64, /data/app/~~lriWWfQIhkZ9hX_Tp7mpPQ==/cloud.dragonx.plugin.flutter.djiExample-9HouSjVEpQTB_Vp3VznKiQ==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]
I/flutter (10176):  at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
I/flutter (10176):  at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
I/flutter (10176):  at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
I/flutter (10176):  ... 22 more
I/flutter (10176): , null)
              PlatformException(NoClassDefFoundError, java.lang.NoClassDefFoundError: Failed resolution of: Ldji/sdk/sdkmanager/DJISDKManager$...

What I did: First I created a new app under my DJI developer account with the package name cloud.dragonx.plugin.flutter.djiExample and then I copied the API key to android:value under com.dji.sdk.API_KEY.

I tried multiple way to test:

With the official DJI Fly app it is working well, but now I removed it for having only 1 app which would control my drone.

Other notes:

Could you please help me here ?

Thank you in advance for any help !

orenagiv commented 1 year ago

Hey @DanielZelei Can you please share your .gradle files from the /android platform folder? (Just mask any sensitive properties there).

P.S. Did you follow the instructions here? https://github.com/DragonX-cloud/dji_flutter_plugin#configuring-the-dji-sdk-on-your-flutter-android-kotlin-project

zohaib1313 commented 1 year ago

@orenagiv this issue comes in android 13 , i am also getting class not found exception, although same apk works fine below android 13

orenagiv commented 1 year ago

Hey @zohaib1313 Thanks for your input!

I'll check and let you know.

FYI @DanielZelei

orenagiv commented 1 year ago

Hey @zohaib1313 @DanielZelei

I've pushed a branch called feature/android-13. Please pull it and follow these steps:

  1. Upgrade your Android Studio to the latest version.
  2. Run dart pub get to update all the Flutter dependencies.
  3. Open the Android workspace of the Example project in Android Studio and let it "sync" the Gradle stuff.
  4. Connect your Android 13 device via USB.
  5. Run the Example project from Android Studio first.
  6. Once the app loads - Make sure that if click the "Register" - then the status on the right side of the screen becomes "Registered" after a few seconds (could take up to 1 minute if it's the first time).
  7. Exit, and run the Example app as usual from your Flutter IDE (e.g. VScode).

Note When you're on Android Studio and trying to compile - If you get errors about a "namespace" missing in the build.gradles files of the dependencies, then you will need to manually edit the build.grade file of the relevant package and add the "namespace" based on the same package-id from the AndroidManifest.xml file of that package.

For example, the package path_provider build.gradle file should have the namespace like so:

android {
    namespace "io.flutter.plugins.pathprovider"
    compileSdk 31
    ...

And it was taken from the path_provider_android package > manifests > AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="io.flutter.plugins.pathprovider">
</manifest>

And I also had to edit the AndroidManifest.xml and remove the "package" attribute, so the result is:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

I had to do this manually in my Android project, to every dependency that is used by the Example project:

All these packages can be found by going into the .pub-cache folder:

cd ~/.pub-cache/hostes/pub.dev/

Please note I have only tested that the Example app compiles on Android 13 and launches properly, and that the "Register" function works (and the status becomes "registered"). I have not yet tested all the functionalities of the package and the Example app.

Let me know how it goes and if you managed to get it to run properly.

orenagiv commented 1 year ago

Hey @zohaib1313 @DanielZelei

I've published an update to the package (v1.0.12) which resolves the Android 13 issues without the need to upgrade Gradle and the packages as described in my previous message.

Update your pubspec.yaml with v1.0.12 to fetch the latest update:

dependencies:
  dji: ^1.0.12

Bottom line - the required changes are to update the list of permissions in the AndroidManifest.xml and to change the targetSdkVersion in the build.gradle file to 31.

Give it a shot and let me know how it goes :)

orenagiv commented 1 year ago

Hey @zohaib1313 Per my comment here:

https://github.com/dji-sdk/Mobile-SDK-Android/issues/1242#issuecomment-1700539618

Let's continue the progress here, as it seems it can be resolved at the DJI Flutter plugin level itself.

orenagiv commented 1 year ago

@zohaib1313 Please note there's a branch called feature/android-13 with upgraded packages, including the upgraded Pigeon plugin.

In the DjiPlugin.kt - there is the onAttachedToAcitivity which triggers the Multidex and the Helper.install:

  override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    this.djiPluginActivity = binding.activity

    // [ ! ] DJI SDK Must be "installed" using this function, before any method of DJI SDK is used.
    MultiDex.install(this.djiPluginContext)
    Helper.install(this.djiPluginActivity.application)
  }

I've validated that it gets triggered when the Example application launches. So I'm not yet sure why with targetSdk 33 it doesn't work, and we get the class-not-found exception (with but targetSdk 31 it does work).

Please describe where exactly did you add the Helper.install in your project - and I'd like to do the same on the Example application and see if it works.

orenagiv commented 1 year ago

Hey @zohaib1313 Did you get a chance to read my last message above?

orenagiv commented 1 year ago

Hey @zohaib1313 I'm closing this issue for now. If you can share your insights per my comment above, that would be great.