Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NPE 'void io.flutter.plugin.common.MethodChannel.invokeMethod(java.lang.String, java.lang.Object)' on a null object reference #649

Open
keehoo opened this issue Aug 10, 2020 · 7 comments

Comments

@keehoo
Copy link

keehoo commented Aug 10, 2020

I'm starting to have doubts whether choosing this library was the right thigh to do.

`Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void io.flutter.plugin.common.MethodChannel.invokeMethod(java.lang.String, java.lang.Object)' on a null object reference
   at com.pauldemarco.flutter_blue.FlutterBluePlugin$5.run(FlutterBluePlugin.java:973)
   at android.os.Handler.handleCallback(Handler.java:883)
   at android.os.Handler.dispatchMessage(Handler.java:100)
   at android.os.Looper.loop(Looper.java:237)
   at android.app.ActivityThread.main(ActivityThread.java:8016)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076)`

I've zero idea even where to look for debugging here.

@jeroen1602
Copy link

jeroen1602 commented Aug 27, 2020

I have something similar, it seems to happen for me when you close the app (using the back button) while a scan is running.

java.lang.NullPointerException: Attempt to invoke virtual method 'void io.flutter.plugin.common.MethodChannel.invokeMethod(java.lang.String, java.lang.Object)' on a null object reference
        at com.pauldemarco.flutter_blue.FlutterBluePlugin$5.run(FlutterBluePlugin.java:1004)
        at android.app.Activity.runOnUiThread(Activity.java:6917)
        at com.pauldemarco.flutter_blue.FlutterBluePlugin.invokeMethodUIThread(FlutterBluePlugin.java:1000)
        at com.pauldemarco.flutter_blue.FlutterBluePlugin.access$400(FlutterBluePlugin.java:64)
        at com.pauldemarco.flutter_blue.FlutterBluePlugin$2.onScanResult(FlutterBluePlugin.java:782)
        at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:498)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7682)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

@jeroen1602
Copy link

jeroen1602 commented Aug 27, 2020

I got a simple workaround that may be useful. All it does is stop the currently running scan and add a bit of time to wait for the scan to actually stop.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';

class MainPage extends StatelessWidget {
  Future<bool> _onWillPop() async {
    // A little workaround for issue https://github.com/pauldemarco/flutter_blue/issues/649
    if (Platform.isAndroid) {
      if (await FlutterBlue.instance.isScanning.first) {
        // Also close any open connections you may have.
        await FlutterBlue.instance.stopScan();
        // not sure if 200 milliseconds is enough on every device. Slower devices may need more time.
        await Future.delayed(Duration(milliseconds: 200));
      }
    }
    return true;
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: _onWillPop,
      child: // Your body goes here
    );
  }
}

@ZhangZeQiao
Copy link

I have something similar,This problem should have occurred during the scan~

Back traces starts.
java.lang.NullPointerException: Attempt to invoke virtual method 'void io.flutter.plugin.common.MethodChannel.invokeMethod(java.lang.String, java.lang.Object)' on a null object reference
	at com.pauldemarco.flutter_blue.FlutterBluePlugin$5.run(SourceFile:1)
	at android.app.Activity.runOnUiThread(Activity.java:7152)
	at com.pauldemarco.flutter_blue.FlutterBluePlugin.invokeMethodUIThread(SourceFile:1)
	at com.pauldemarco.flutter_blue.FlutterBluePlugin.access$400(SourceFile:1)
	at com.pauldemarco.flutter_blue.FlutterBluePlugin$2.onScanResult(SourceFile:6)
	at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:524)
	at android.os.Handler.handleCallback(Handler.java:938)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:236)
	at android.app.ActivityThread.main(ActivityThread.java:7896)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
Back traces ends.

@ZhangZeQiao
Copy link

I got a simple workaround that may be useful. All it does is stop the currently running scan and add a bit of time to wait for the scan to actually stop.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';

class MainPage extends StatelessWidget {
  Future<bool> _onWillPop() async {
    // A little workaround for issue https://github.com/pauldemarco/flutter_blue/issues/649
    if (Platform.isAndroid) {
      if (await FlutterBlue.instance.isScanning.first) {
        // Also close any open connections you may have.
        await FlutterBlue.instance.stopScan();
        // not sure if 200 milliseconds is enough on every device. Slower devices may need more time.
        await Future.delayed(Duration(milliseconds: 200));
      }
    }
    return true;
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: _onWillPop,
      child: // Your body goes here
    );
  }
}

When I go into the app, exit, and click into the app right away, that's where the error is reported, whereas it wouldn't be the case with your approach.Is it possible that the first time I get in, the MethodChannel initializes and calls the system bluetooth scan, exits, comes in right away, the Bluetooth is still scanning, and this time the MethodChannel isn't initialized, it reports this error?
【当我进入应用后,退出,再马上点击进入应用,这种情况下就会报这个错误,而采用你这种方式后就不会出现这样的情况。是否有这样的可能:当我第一次进入后,MethodChannel 初始化完成调用系统蓝牙扫描,这时退出,再马上进来,蓝牙还在扫描,而这一次 MethodChannel 还没初始化,就报这个错误??】

@jeroen1602
Copy link

So what I think happens is this.

  1. An active asynchronous call is happening (for example scanning)
  2. The user closes the app (be it locking the screen, using the back button, the home buttons, the system decides it needs it's resources)
  3. The member variables in the activity get set to null. This is something Android does to minimize ram usage for apps that are now in the background. To avoid this you should save your activity state into a bundle.
  4. The async function which was never stopped comes back with a result and calls the callback function that has been provided.
  5. The callback function tries to access a member variable, or call a function of a member variable, but because of step 3 this member variable is now null.
  6. NullpointerException's all the way!

All that my workaround does is it tells the FlutterBlue library to stop it's scanning await FlutterBlue.instance.stopScan(); And then waits a set amount of time for the library to actually stop the scanning. This way there won't be any dangling async functions that may try to call a callback that doesn't have a valid Activity anymore (hopefully).
This is also why the comment says that you should close any open connections you may still have, as these connections will cause the same problems if left open.

@adenisyuk
Copy link

At FlutterBluePlugin the tearDown() method is called on the Android main thread by the onDetachedFromActivity().
And the tearDown() method is where the cannel var is cleared (channel = null;).

Later, the invokeMethodUIThread() method is called on some different thread (actually the thread does not matter here) and the Runnable is posted on the main thread: activity.runOnUiThread which, when executes, tries to access the channel, which is already null.

This is the commit where the issue was introduced:
419c17b#diff-f60ed5fb761e93140571beb974ac7859241e6765d2de29aed1f79515e19539ae

It might be worth at least check if the channel isn't null (not sure this is the right way to fix it).

For testing purposes, the issue can be reproduced easily if the app is brought to the background (when scanning is in the progress) while the Don't keep activities developer option is on.

@dudizimber
Copy link

I have the same issue but when killing/reopening the app when a device was connected on the first run.

D/AndroidRuntime( 6984): Shutting down VM
E/AndroidRuntime( 6984): FATAL EXCEPTION: main
E/AndroidRuntime( 6984): Process: com.example.flutter, PID: 6984
E/AndroidRuntime( 6984): java.lang.NullPointerException: Attempt to invoke virtual method 'void io.flutter.plugin.common.MethodChannel.invokeMethod(java.lang.String, java.lang.Object)' on a null object reference
E/AndroidRuntime( 6984): 	at com.pauldemarco.flutter_blue.FlutterBluePlugin$5.run(FlutterBluePlugin.java:1002)
E/AndroidRuntime( 6984): 	at android.os.Handler.handleCallback(Handler.java:938)
E/AndroidRuntime( 6984): 	at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 6984): 	at android.os.Looper.loop(Looper.java:233)
E/AndroidRuntime( 6984): 	at android.app.ActivityThread.main(ActivityThread.java:8010)
E/AndroidRuntime( 6984): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 6984): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
E/AndroidRuntime( 6984): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants