添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

友盟崩溃日志报了这样一个问题,说是扫描蓝牙设备回调时 MethodChannel 为空:

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)

理了一遍,发现 flutter_blue 的 MethodChannel 会在 MainActivity 的 onCreate 中初始化,这个时候还没有开启蓝牙扫描,这就奇怪了:
[ com.pauldemarco.flutter_blue.FlutterBluePlugin ]

private void invokeMethodUIThread(final String name, final byte[] byteArray)
        activity.runOnUiThread(
                new Runnable() {
                    @Override
                    public void run() {
                        channel.invokeMethod(name, byteArray);
                });
    private void setup(
            final BinaryMessenger messenger,
            final Application application,
            final Activity activity,
            final PluginRegistry.Registrar registrar,
            final ActivityPluginBinding activityBinding) {
        synchronized (initializationLock) {
            Log.i(TAG, "setup");
            this.activity = activity;
            this.application = application;
            this.context = application;
            channel = new MethodChannel(messenger, NAMESPACE + "/methods");
            channel.setMethodCallHandler(this);
            stateChannel = new EventChannel(messenger, NAMESPACE + "/state");
            stateChannel.setStreamHandler(stateHandler);
            mBluetoothManager = (BluetoothManager) application.getSystemService(Context.BLUETOOTH_SERVICE);
            mBluetoothAdapter = mBluetoothManager.getAdapter();
            if (registrar != null) {
                // V1 embedding setup for activity listeners.
                registrar.addRequestPermissionsResultListener(this);
            } else {
                // V2 embedding setup for activity listeners.
                activityBinding.addRequestPermissionsResultListener(this);
    @Override
    public void onAttachedToActivity(ActivityPluginBinding binding) {
        activityBinding = binding;
        setup(
                pluginBinding.getBinaryMessenger(),
                (Application) pluginBinding.getApplicationContext(),
                activityBinding.getActivity(),
                null,
                activityBinding);


所以找了一下官网 issues:https://github.com/pauldemarco/flutter_blue/issues/649
按照上面答友的方案试了一下,果然不会了:

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

通过对事件日志的分析,发现在退出应用后,再马上进来很容易复现这个问题,所以做了以下猜想:

是否有这样的可能:当第一次进入后,MethodChannel 初始化完成调用系统蓝牙扫描,这时退出,再马上进来,蓝牙还在扫描,而这一次 MethodChannel 还没初始化,就报这个错误?

线上观测后,这个问题还是会出现,特别是在华为手机,崩溃率特别高。

原先以为是升级版本带来的问题(0.7.x),那就恢复到旧版本(0.6.x),还是会有问题。

既然官方迟迟没有修复,那就自己改源码:直接修改 flutter_blue 的 Android 模块代码,在 FlutterBluePlugin.java 中发生空指针异常的地方,加上非空判断,why not ~

友盟崩溃日志报了这样一个问题,说是扫描蓝牙设备回调时 MethodChannel 为空: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.flut
* 实现 Flutter 调用 Android 、iOS 原生的方法并回调Flutter * 实现 Flutter 调用 Android 、iOS 原生并打开Android 原生的一个Activity页面,iOS原生的一个ViewController 页面 * 实现 Android 、iOS 原生主动发送消息到 Flutter 中 * 实现 Android 、iOS 原生中的 TestActivity 页面主动发送消息到Flutter
https://blog.csdn.net/zl18603543572/article/details/96049359 2019-07-16 00:58:13早起的年轻人阅读数 187收藏更多 分类专栏:flutterflutter 从入门 到精通 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。 本文链接:ht...
Exception in thread "main" java.lang.NullPointerException at org.gradle.wrapper.BootstrapMainStarter.findLauncherJar(BootstrapMainStarter.java:34) at org.gradle.wrapper.Bootstr...
Attempt to invoke virtual methodjava.lang.String java.lang.Object.toString()‘ on a null object
毕业论文中项目需要用到心电图的绘制,所以先学习了一下饼图账单的项目,在获取json格式并解析时出现以下报错,说有空指针E/AndroidRuntime: FATAL EXCEPTION: main Process: com.administrator.piechart, PID: 3783 java.lang.NullPoint
首先NullPointerException是RuntimeException的一个子类,这是运行时,在编译时期不会触发,所以这是最最最容易出现的线上bug; 容易出现空指针异常的场景 在调用对象方法时 比如处理字符串常用的replace方法,数组的length方法,map的size方法等等; str.replace(…) 如果str为null,这里就直接空指针了 判断一个str是否等于"test",你直接str.equals(“test”) 还有像map.forEach()、list.stream()
问题java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.avatar_03.OkMa-2020-4-7 报错 2020-04-07 14:54:33.148 10868-10868/com.example.avatar_03 E/AndroidRuntime: FATAL EXCEP...
flutter_bluetooth_serial 和 flutter_blue 是两种在 Flutter 中用于蓝牙通信的插件。 flutter_bluetooth_serial 是一个较早的插件,它提供了与蓝牙设备的基本通信功能,如连接、断开连接、发送和接收数据。 flutter_blue 是一个更加全面的插件,它提供了更多的功能,例如扫描周围的蓝牙设备、获取设备的详细信息、连接到 GATT 服务器等。同时,flutter_blue 还支持蓝牙 Low Energy(BLE),因此可以用于与支持 BLE 的设备进行通信。 总的来说,flutter_blueflutter_bluetooth_serial 更加全面,但如果您只需要简单的蓝牙通信功能,则 flutter_bluetooth_serial 也可能是一个不错的选择。
_Anonymous_.: Android Activity管理类可能会导致内存泄漏,具体取决于实现方式和使用方式。如果Activity管理类持有Activity的引用,并且在Activity销毁时没有及时释放引用,就会导致内存泄漏。此外,如果Activity管理类在Activity销毁后仍然持有对Activity的引用,也会导致内存泄漏。 为了避免内存泄漏,可以使用弱引用或者软引用来持有Activity的引用,或者在Activity销毁时及时释放引用。 对于静态变量、静态方法、内存泄漏的思考 Nocancel: 如果一个方法与他所在类的实例对象无关,那么它就应该是静态的,受益匪浅 Android 常用代码整理:Activity 管理类(ActivityManager) MrSun110: 请问您这样写,静态引用activity,不会造成内存泄漏吗 Android 九宫格图片展示的实现 linkkkhhh: 源码呢请问 Android 九宫格图片展示的实现 没头脑&不高兴: SizeUtil搁nm哪呢