rmtmckenzie/flutter_qr_mobile_vision

NullPointerException when destroying activity (onDetachedFromEngine)

mauriziopinotti opened this issue · 2 comments

I am using qr_mobile_vision 5.0.0 with Flutter stable 3.16.9 and I see a lot of reports in Crashlytics with this error:

Fatal Exception: java.lang.RuntimeException: Unable to destroy activity {it.easyhour.app/it.easyhour.app.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void oo.k.e(oo.k$c)' on a null object reference
       at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:5741)
       at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:5774)
       at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:47)
       at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
       at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2462)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:240)
       at android.os.Looper.loop(Looper.java:351)
       at android.app.ActivityThread.main(ActivityThread.java:8377)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'void oo.k.e(oo.k$c)' on a null object reference
       at com.github.rmtmckenzie.qr_mobile_vision.QrMobileVisionPlugin.onDetachedFromEngine(QrMobileVisionPlugin.java:1)
       at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.remove(FlutterEngineConnectionRegistry.java:1)
       at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.remove(FlutterEngineConnectionRegistry.java:1)
       at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.removeAll(FlutterEngineConnectionRegistry.java:1)
       at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.destroy(FlutterEngineConnectionRegistry.java:1)
       at io.flutter.embedding.engine.FlutterEngine.destroy(FlutterEngine.java:1)
       at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.onDetach(FlutterActivityAndFragmentDelegate.java:1)
       at io.flutter.embedding.android.FlutterFragment.onDetach(FlutterFragment.java:1)
       at androidx.fragment.app.Fragment.performDetach(Fragment.java:1)
       at androidx.fragment.app.FragmentStateManager.detach(FragmentStateManager.java:1)
       at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:1)
       at androidx.fragment.app.SpecialEffectsController$FragmentStateManagerOperation.complete(SpecialEffectsController.java:1)
       at androidx.fragment.app.SpecialEffectsController$Operation.cancel(SpecialEffectsController.java:1)
       at androidx.fragment.app.SpecialEffectsController.forceCompleteAllOperations(SpecialEffectsController.java:1)
       at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:1)
       at androidx.fragment.app.FragmentManager.dispatchDestroy(FragmentManager.java:1)
       at androidx.fragment.app.FragmentController.dispatchDestroy(FragmentController.java:1)
       at androidx.fragment.app.FragmentActivity.onDestroy(FragmentActivity.java:5)
       at android.app.Activity.performDestroy(Activity.java:8665)
       at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1438)
       at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:5728)
       at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:5774)
       at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:47)
       at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
       at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2462)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:240)
       at android.os.Looper.loop(Looper.java:351)
       at android.app.ActivityThread.main(ActivityThread.java:8377)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)

The crash seems to only happen in Android, although my user base is strongly biased so maybe it's just a coincidence:

image

I don't have steps to reproduce but since QrMobileVisionPlugin.onDetachedFromEngine() only has one line of code I suspect that channel is null here:

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }

I added a PR with a fix for this, #232

This should be fixed in 5.0.1.