错误记录Flutter 混合开发获取 BinaryMessenger 报错 ( FlutterActivityAndFragmentDelegate.getFlutterEngine() )(代码片段

Posted 韩曙亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了错误记录Flutter 混合开发获取 BinaryMessenger 报错 ( FlutterActivityAndFragmentDelegate.getFlutterEngine() )(代码片段相关的知识,希望对你有一定的参考价值。





一、 报错信息



在 Flutter 混合开发中 , 开发 android 与 Flutter 信息交互功能 ;

创建 BasicMessageChannel 通道 , 其构造函数如下 :

  public BasicMessageChannel(
      @NonNull BinaryMessenger messenger, @NonNull String name, @NonNull MessageCodec<T> codec) {

首先要获取 BinaryMessenger 实例对象 ;

BinaryMessenger 实例对象需要从 FlutterEngine 中获取 ;


获取流程如下 :

首先 , 创建 FlutterFragment , 这是要嵌入到 Android 的 Activity 界面中的 Flutter 界面 ;

mFlutterFragment = FlutterFragment.withNewEngine().
        initialRoute("嵌入 FlutterFragment").build();

然后 , 显示该 Flutter 页面 , 这里直接将 Flutter 页面的 Fragment 设置到 Activity 中即可 ;

fragmentTransaction.replace(R.id.frame, mFlutterFragment);
fragmentTransaction.commit();

最后 , 获取 FlutterEngine , 但是在此处报错 ;

mFlutterFragment.getFlutterEngine() ; 

报错信息如下 :

2021-08-30 11:08:39.318 32433-32433/com.example.flutter_native E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.flutter_native, PID: 32433
    java.lang.NullPointerException: Attempt to invoke virtual method 'io.flutter.embedding.engine.FlutterEngine io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.getFlutterEngine()' on a null object reference
        at io.flutter.embedding.android.FlutterFragment.getFlutterEngine(FlutterFragment.java:986)
        at com.example.flutter_native.MainActivity.initEventChannel(MainActivity.java:104)
        at com.example.flutter_native.MainActivity.access$100(MainActivity.java:21)
        at com.example.flutter_native.MainActivity$1.onClick(MainActivity.java:63)
        at android.view.View.performClick(View.java:6597)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
        at android.view.View.performClickInternal(View.java:6574)
        at android.view.View.access$3100(View.java:778)
        at android.view.View$PerformClick.run(View.java:25885)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6718)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)





二、 解决方案



报错位置在 FlutterFragment 中 , 在调用 getFlutterEngine 方法时报错 , getFlutterEngine 方法相关代码如下 :

public class FlutterFragment extends Fragment
    implements FlutterActivityAndFragmentDelegate.Host, ComponentCallbacks2 {

  // Delegate that runs all lifecycle and OS hook logic that is common between
  // FlutterActivity and FlutterFragment. See the FlutterActivityAndFragmentDelegate
  // implementation for details about why it exists.
  @VisibleForTesting /* package */ FlutterActivityAndFragmentDelegate delegate;

  /**
   * Hook for subclasses to obtain a reference to the {@link FlutterEngine} that is owned by this
   * {@code FlutterActivity}.
   */
  @Nullable
  public FlutterEngine getFlutterEngine() {
    return delegate.getFlutterEngine();
  }
}

报错信息是

java.lang.NullPointerException: Attempt to invoke virtual method 'io.flutter.embedding.engine.FlutterEngine io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.getFlutterEngine()' on a null object reference

FlutterActivityAndFragmentDelegate delegate 为空 ;

在 FlutterFragment 显示成功后 , 该 delegate 才会进行初始化 ;

在 Android 中嵌入 Flutter 页面 , 比较慢 , 大概耗时 1 ~ 3 秒左右 ;

也就是说在 Flutter 页面显示成功之前 , FlutterActivityAndFragmentDelegate delegate 值都是 null , 此时通过 Fragment 获取 FlutterEngine() , 都会报空指针异常 ;


在启动 Flutter 页面后 , 延迟 5 秒 , 再进行初始化 , 即可解决上述问题 ;

mFlutterFragment = FlutterFragment.withNewEngine().
        initialRoute("嵌入 FlutterFragment").build();
        
Log.i(TAG, "mFlutterFragment : " + mFlutterFragment);

// 创建 FlutterFragment
fragmentTransaction.replace(R.id.frame, mFlutterFragment);
fragmentTransaction.commit();

//initEventChannel();

new Thread(){
    @Override
    public void run() {
        try {
            sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        initEventChannel();
        Log.i(TAG, "mFlutterFragment : " + mFlutterFragment);
    }
}.start();

从 Android 中向 Flutter 传递消息成功 :

以上是关于错误记录Flutter 混合开发获取 BinaryMessenger 报错 ( FlutterActivityAndFragmentDelegate.getFlutterEngine() )(代码片段的主要内容,如果未能解决你的问题,请参考以下文章

错误记录Flutter 混合开发报错 ( java.nio.file.FileSystemException: xxx/R.jar: 另一个程序正在使用此文件,进程无法访问。 )

原生(iOS)与Flutter混合开发步骤

Flutter-解决混合开发iOS脚本打包遇到的问题

FlutterFlutter 混合开发 ( 混合开发中 Flutter 的 热重启 / 热加载 )

iOS与Flutter混合开发

FlutterFlutter 混合开发 ( 简介 | Flutter 混合开发集成步骤 | 创建 Flutter Module )