【错误记录】Flutter 混合开发获取 BinaryMessenger 报错 ( FlutterActivityAndFragmentDelegate.getFlutterEngine() )

2023-03-29 15:55:16 浏览数 (1)

文章目录

  • 一、 报错信息
  • 二、 解决方案

一、 报错信息


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

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

代码语言:javascript复制
  public BasicMessageChannel(
      @NonNull BinaryMessenger messenger, @NonNull String name, @NonNull MessageCodec<T> codec) {

首先要获取 BinaryMessenger 实例对象 ;

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

获取流程如下 :

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

代码语言:javascript复制
mFlutterFragment = FlutterFragment.withNewEngine().
        initialRoute("嵌入 FlutterFragment").build();

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

代码语言:javascript复制
fragmentTransaction.replace(R.id.frame, mFlutterFragment);
fragmentTransaction.commit();

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

代码语言:javascript复制
mFlutterFragment.getFlutterEngine() ; 

报错信息如下 :

代码语言:javascript复制
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 方法相关代码如下 :

代码语言:javascript复制
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();
  }
}

报错信息是

代码语言:javascript复制
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 秒 , 再进行初始化 , 即可解决上述问题 ;

代码语言:javascript复制
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 传递消息成功 :

0 人点赞