Android与flutter生命周期交互

以下说明均基于io.flutter.embedding包下的flutter类

关于flutterengine和flutterview:

flutter界面用flutterengine加载,flutter界面用flutterview展示。

Engine使用前需要调用getDartExecutor().executeDartEntrypoint预热,设置initialRoute只能在预热之前(initialRoute是string类型,可用于传递初始化信息给flutter模块)。

一个engine只能加载一次flutter界面,且同一时间同一个engine加载的界面只能显示在一个fluterview上面.(flutterview调用attachToFlutterEngine依附于engine从而显示engine加载的界面,同一个engine的界面只会显示在最后一个调用attachToFlutterEngine的flutterview上面)。


FlutterEngine flutterEngine =new FlutterEngine(this);

//初始化路由信息

flutterEngine.getNavigationChannel().setInitialRoute("test");

//预热

flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());

FlutterView flutterView =new FlutterView(this);

flutterView.attachToFlutterEngine(flutterEngine);

关于flutteractivity:

flutteractivity使用一个flutterview来作为“ContentView”。

一个flutteractivity需要一个flutterengine来加载flutter界面,可以指定activity初始化flutterengine的模式:使用缓存新建

缓存模式:需要事先初始化一个engine并放入FlutterEngineCache的map中,并将key值传给flutteractivity,再由flutteractivity根据key值从FlutterEngineCache中取出来,请注意如果key值对应的engine并没有在cache中找到,那么会抛异常,所以使用缓存模式一定要事先初始化一个engine,该模式适用于展示一些常用页面。


FlutterEngineCache.getInstance().put("key",flutterEngine);

Intent intent = io.flutter.embedding.android.FlutterActivity.withCachedEngine("key").build(this);

startActivity(intent);

新建模式:每次都会新建一个engine,跟activity的standard启动模式类似。


Intent intent = io.flutter.embedding.android.FlutterActivity.withNewEngine().initialRoute("test").build(this);

startActivity(intent);

注意:FlutterEngineCache是非线程安全的单例模式,且内部的map也是非线程安全的hashmap,所以请确保在单一线程中使用cache。

关于flutterfragment:

与flutteractivity类似。

关于自定义flutteractivity:

如果仅是直接使用flutteractivity或者flutterfragment,知道以上信息已足够。若要自定义使用flutter的activity(不继承flutteractivity)来使用,请注意以下几点。

flutterengine内置有一个ActivityControlSurface实例,主要用来处理activity的onactivityresult、onnewintent等回调函数,官方源码的使用方法如下:

首先,在activity的oncreate时,flutterengine需要调用getActivityControlSurface().attachToActivity来使ActivityControlSurface依附于activity。


@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

    //getEngine()为自定义的获取engine的方法

    getEngine().getActivityControlSurface().attachToActivity(this, getLifecycle());

}

在activity的onDestroy()时,需分两种情况,一种是activity真的销毁,这时需调用ActivityControlSurface的detachFromActivity(),另一种是屏幕旋转等ConfigChanges带来的销毁,这时调用detachFromActivityForConfigChanges()。


@Override

protected void onDestroy() {

super.onDestroy();

/*...dosomething*/

    if (isChangingConfigurations()) {

getEngine().getActivityControlSurface().detachFromActivityForConfigChanges();

    }else {

getEngine().getActivityControlSurface().detachFromActivity();

    }

}

在activity的onactivityresult、onnewintent等方法里面还需要手动调用ActivityControlSurface的相应方法,以此来让flutter处理onactivityresult、onnewintent等。


@Override

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

super.onActivityResult(requestCode, resultCode, data);

    getEngine().getActivityControlSurface().onActivityResult(requestCode, resultCode, data);

}

除此之外,在activity onresume、onpause、onstop、ondestory时,flutterengine需用内置的lifecyclechannel来手动分别调用appIsResumed()、appIsInactive、appIsPaused、appIsDetached以通知flutter界面进入相应状态,如果不使用这些flutter界面将无法正常展示。


@Override

protected void onResume() {

super.onResume();

/*...dosomething*/

    getEngine().getLifecycleChannel().appIsResumed();

}

@Override

protected void onPause() {

super.onPause();

/*...dosomething*/

    getEngine().getLifecycleChannel().appIsInactive();

}

@Override

protected void onDestroy() {

super.onDestroy();

/*...dosomething*/

    getEngine().getLifecycleChannel().appIsDetached();

}

小结:

基于此,自定义flutteractivity适用于即有原生界面又有flutter界面、或者flutter界面需要与原生实时交互的场景,需开发者同时调控原生界面和flutter界面的生命周期和相关回调。官方flutteractivity只能展示flutter界面,如果一个界面仅需要有flutter界面,使用它准没错。

关于flutter与android进行实时交互需通过MethodChannel、MessageChannel等channel来进行,这个之后再做探讨。

你可能感兴趣的:(Android与flutter生命周期交互)