DJI SDK 4.7.1 crashes unceremoneously where 4.6 does not

Viewed 867

I'm trying to update my app to use the new 4.7.1 version, but as soon as I try to go to the activity where I'm using UXSDK Widgets, the app now crashes without additional log entries. After updating the SDK version, I made sure that my build.gradle, AndroidManifest.xml and proguard-rules.pro matched up in the relevant areas from the sample code at https://github.com/dji-sdk/Mobile-SDK-Android.

I noticed that across both versions of the SDK I receive very similar logcat errors:

E/DJISDKManager: can't find DJIEventBusIndex Class in SharedLib module
E/DJISDKManager: java.lang.ClassNotFoundException: dji.event3.sharelib.DJIEventBusIndex
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:453)
    at java.lang.Class.forName(Class.java:378)
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:43)
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0)
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95)
    at java.lang.Thread.run(Thread.java:764)
 Caused by: java.lang.ClassNotFoundException: Didn't find class "dji.event3.sharelib.DJIEventBusIndex" on path: DexPathList[[zip file "/data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/base.apk", zip file "/data/user/0/com.reportall.droneglide.fence/.cache_sdk/sdkclasses.jar"],nativeLibraryDirectories=[/data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/lib/arm64, /data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at java.lang.Class.classForName(Native Method) 
    at java.lang.Class.forName(Class.java:453) 
    at java.lang.Class.forName(Class.java:378) 
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:43) 
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0) 
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95) 
    at java.lang.Thread.run(Thread.java:764) 
E/DJISDKManager: can't find DJIEventBusIndex Class in MidWare module
E/DJISDKManager: java.lang.ClassNotFoundException: dji.event3.midware.DJIEventBusIndex
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:453)
    at java.lang.Class.forName(Class.java:378)
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:62)
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0)
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95)
    at java.lang.Thread.run(Thread.java:764)
 Caused by: java.lang.ClassNotFoundException: Didn't find class "dji.event3.midware.DJIEventBusIndex" on path: DexPathList[[zip file "/data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/base.apk", zip file "/data/user/0/com.reportall.droneglide.fence/.cache_sdk/sdkclasses.jar"],nativeLibraryDirectories=[/data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/lib/arm64, /data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at java.lang.Class.classForName(Native Method) 
    at java.lang.Class.forName(Class.java:453) 
    at java.lang.Class.forName(Class.java:378) 
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:62) 
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0) 
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95) 
    at java.lang.Thread.run(Thread.java:764) 
E/DJISDKManager: can't find DJIEventBusIndex Class in FlyForbid module
E/DJISDKManager: java.lang.ClassNotFoundException: dji.event3.flyforbid.DJIEventBusIndex
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:453)
    at java.lang.Class.forName(Class.java:378)
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:81)
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0)
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95)
    at java.lang.Thread.run(Thread.java:764)
 Caused by: java.lang.ClassNotFoundException: Didn't find class "dji.event3.flyforbid.DJIEventBusIndex" on path: DexPathList[[zip file "/data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/base.apk", zip file "/data/user/0/com.reportall.droneglide.fence/.cache_sdk/sdkclasses.jar"],nativeLibraryDirectories=[/data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/lib/arm64, /data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at java.lang.Class.classForName(Native Method) 
    at java.lang.Class.forName(Class.java:453) 
    at java.lang.Class.forName(Class.java:378) 
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:81) 
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0) 
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95) 
    at java.lang.Thread.run(Thread.java:764) 
E/DJISDKManager: can't find DJIEventBusIndex Class in service module
E/DJISDKManager: java.lang.ClassNotFoundException: dji.event3.service.DJIEventBusIndex
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:453)
    at java.lang.Class.forName(Class.java:378)
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:100)
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0)
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95)
    at java.lang.Thread.run(Thread.java:764)
 Caused by: java.lang.ClassNotFoundException: Didn't find class "dji.event3.service.DJIEventBusIndex" on path: DexPathList[[zip file "/data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/base.apk", zip file "/data/user/0/com.reportall.droneglide.fence/.cache_sdk/sdkclasses.jar"],nativeLibraryDirectories=[/data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/lib/arm64, /data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at java.lang.Class.classForName(Native Method) 
    at java.lang.Class.forName(Class.java:453) 
    at java.lang.Class.forName(Class.java:378) 
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:100) 
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0) 
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95) 
    at java.lang.Thread.run(Thread.java:764) 
can't find DJIEventBusIndex Class in FrLib module
E/DJISDKManager: java.lang.ClassNotFoundException: com.dji.frlib.DJIEventBusIndex
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:453)
    at java.lang.Class.forName(Class.java:378)
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:119)
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0)
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95)
    at java.lang.Thread.run(Thread.java:764)
 Caused by: java.lang.ClassNotFoundException: Didn't find class "com.dji.frlib.DJIEventBusIndex" on path: DexPathList[[zip file "/data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/base.apk", zip file "/data/user/0/com.reportall.droneglide.fence/.cache_sdk/sdkclasses.jar"],nativeLibraryDirectories=[/data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/lib/arm64, /data/app/com.reportall.droneglide.fence-OGmqnjtacp7079L76urIHA==/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at java.lang.Class.classForName(Native Method) 
    at java.lang.Class.forName(Class.java:453) 
    at java.lang.Class.forName(Class.java:378) 
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:119) 
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0) 
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95) 
    at java.lang.Thread.run(Thread.java:764)

In 4.7.1, there is an additional preceding message that comes immediately before the above block:

E/DJISDKManager: Failed to load license file /storage/emulated/0/DJI/license.dlf (No such file or directory)

Which I assume must have something to do with a new storage mechanism of the license. Later I get:

W/System.err: java.util.concurrent.TimeoutException
    at dji.midware.util.t.a(Unknown Source:40)
    at dji.midware.broadcastReceivers.DJINetWorkReceiver.b(Unknown Source:30)
W/System.err:     at dji.midware.broadcastReceivers.DJINetWorkReceiver.f(Unknown Source:88)
    at dji.midware.broadcastReceivers.DJINetWorkReceiver.<init>(Unknown Source:10)
    at dji.sdk.sdkmanager.DJISDKManager.initParams(Unknown Source:189)
    at dji.sdk.sdkmanager.DJISDKManager.initSDKManager(Unknown Source:146)
    at dji.sdk.sdkmanager.DJISDKManager.access$1100(Unknown Source:0)
    at dji.sdk.sdkmanager.DJISDKManager$5.run(Unknown Source:95)
    at java.lang.Thread.run(Thread.java:764)

Despite these errors, in both versions of the SDK, my logs return Returned from registerApp, we got: API Key successfully registered but in 4.7.1 the app simply crashes when I try to access the UXSDK elements after. I do grant storage permissions to the app, so I don't know why it's failing with that license file either.

For reference, my build.gradle lists the following relevant block for the SDK:

// DJI SDK
implementation 'com.dji:dji-sdk:4.7.1'
implementation 'com.dji:dji-uxsdk:4.7.1'
compileOnly 'com.dji:dji-sdk-provided:4.7.1'
implementation 'com.squareup:otto:1.3.8'

UPDATE: I attached an Exception handler to the class where the crash happens so I can get a real stack trace. The actual app crash is caused by:

E/ExceptionHandler: java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add `onError` handling.
    at dji.thirdparty.rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:60)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
 Caused by: dji.thirdparty.rx.exceptions.OnErrorNotImplementedException: Attempt to invoke virtual method 'void dji.ux.model.c.b(java.lang.String)' on a null object reference
    at dji.thirdparty.rx.Observable$26.onError(Observable.java:8524)
    at dji.thirdparty.rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157)
    at dji.thirdparty.rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120)
    at dji.thirdparty.rx.observers.SerializedObserver.onError(SerializedObserver.java:158)
    at dji.thirdparty.rx.observers.SerializedSubscriber.onError(SerializedSubscriber.java:79)
    at dji.thirdparty.rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.innerError(OnSubscribeConcatMap.java:192)
    at dji.thirdparty.rx.internal.operators.OnSubscribeConcatMap$ConcatMapInnerSubscriber.onError(OnSubscribeConcatMap.java:340)
    at dji.thirdparty.rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:264)
    at dji.thirdparty.rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:207)
    at dji.thirdparty.rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
    at android.os.Handler.handleCallback(Handler.java:790) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6494) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void dji.ux.model.c.b(java.lang.String)' on a null object reference
    at dji.ux.panel.PreFlightCheckListPanel.addItemsOnDisconnect(Unknown Source:152)
    at dji.ux.panel.PreFlightCheckListPanel.transformValue(Unknown Source:245)
    at dji.ux.base.SimpleFrameLayoutWidget$1.a(Unknown Source:6)
    at dji.ux.base.SimpleFrameLayoutWidget$1.call(Unknown Source:2)
    at dji.thirdparty.rx.internal.util.ScalarSynchronousObservable$4.call(ScalarSynchronousObservable.java:223)
    at dji.thirdparty.rx.internal.util.ScalarSynchronousObservable$4.call(ScalarSynchronousObservable.java:220)
    at dji.thirdparty.rx.Observable$2.call(Observable.java:233)
    at dji.thirdparty.rx.Observable$2.call(Observable.java:225)
    at dji.thirdparty.rx.Observable.unsafeSubscribe(Observable.java:8741)
    at dji.thirdparty.rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.drain(OnSubscribeConcatMap.java:286)
    at dji.thirdparty.rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.onNext(OnSubscribeConcatMap.java:144)
    at dji.thirdparty.rx.internal.operators.OnSubscribeFromArray$FromArrayProducer.slowPath(OnSubscribeFromArray.java:100)
    at dji.thirdparty.rx.internal.operators.OnSubscribeFromArray$FromArrayProducer.request(OnSubscribeFromArray.java:63)
    at dji.thirdparty.rx.Subscriber.setProducer(Subscriber.java:211)
    at dji.thirdparty.rx.internal.operators.OnSubscribeFromArray.call(OnSubscribeFromArray.java:32)
    at dji.thirdparty.rx.internal.operators.OnSubscribeFromArray.call(OnSubscribeFromArray.java:24)
    at dji.thirdparty.rx.Observable.unsafeSubscribe(Observable.java:8741)
    at dji.thirdparty.rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94)
    at dji.thirdparty.rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42)
    at dji.thirdparty.rx.Observable.subscribe(Observable.java:8834)
    at dji.thirdparty.rx.Observable.subscribe(Observable.java:8801)
    at dji.thirdparty.rx.Observable.subscribe(Observable.java:8515)
    at dji.ux.c.h$3$1.onSuccess(Unknown Source:34)
    at dji.keysdk.KeyManager$1.onSuccess(Unknown Source:14)
    at dji.sdksharedlib.DJISDKCache.getValue(Unknown Source:14)
    at dji.keysdk.KeyManager.getValue(Unknown Source:18)
    at dji.ux.c.h$3.a
2 Answers

I ended up fixing this issue by copying over the contents of the example widget layout.xml (activity_default_widgets.xml) file. The only changes I noticed outside of element ordering between the two versions was:

-custom:excludeItem="aircraftBatteryTemperature|ESCStatus"
+custom:excludeItem="ESCStatus"

and in a couple of places:

-android:visibility="invisible"
+android:visibility="gone"

I have no idea why these changes would have crashed the app with the stack trace from my question update, but only changing this XML file allowed the activity to load again.

Change

implementation 'com.dji:dji-sdk:4.7.1'
implementation 'com.dji:dji-uxsdk:4.7.1'
compileOnly 'com.dji:dji-sdk-provided:4.7.1'
implementation 'com.squareup:otto:1.3.8'

to

implementation 'com.dji:dji-uxsdk:4.7.1'
compileOnly 'com.dji:dji-sdk-provided:4.7.1'
implementation 'com.squareup:otto:1.3.8'

The UXSDK depends on SDK and hence the SDK need not be included. Hope that helps!

Related