Flutter启动流程的深入解析

发布时间:2019-08-08 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Flutter启动流程的深入解析脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

Flutter是怎么启动起来的,是在AndROId的ActivITy的启动之后吗?等等这样的问题,在这个文章中将被解答。

从MainActivity开始

新创建一个Flutter项目,在清单文件中默认被启动的Activity是MainActivity,而MainActivity继承的是FlutterActivity。那么问题好像简单了,我们分析一下FlutterActivity,下面是MainActivity的代码。

 public class MainActivity extends FlutterActivity {  @override  PRotected void onCreate(Bundle savedInstancestate) {  suPEr.onCreate(savedInstanceState);  GeneratedPluginRegistrant.registerWith(this);  } }

上面的码很简单,有两个点需要关注,第一个就是在MainActivity.onCreate()中调用了GeneratedPluginRegistrant.registerWith()这个方法,第二个是MainActivity继承自FlutterActivity,我们对这两个关注点依次进行分析。

GeneratedPluginRegistrant.registerWith()分析

我们查看GeneratedPluginRegistrant,发现这个类是Android Studio自动生成的,并且不建议修改,这个类也非常简单,下面是GeneratedPluginRegistrant的代码。

 public final class GeneratedPluginRegistrant {  public static void registerWith(PluginRegistry registry) {  if (alreadyRegisteredWith(registry)) {  return;  }  }   private static boolean alreadyRegisteredWith(PluginRegistry registry) {  final String key = GeneratedPluginRegistrant.class.getcanonicalName();  if (registry.hasPlugin(key)) {  return true;  }  registry.registrarFor(key);  return false;  } }

如果PluginRegistry已经包含了GeneratedPluginRegistrant就直接返回true,如没有就调用PluginRegistry.registrarFor()进行注册。

我们分析一下PluginRegistry,看看是怎么注册的,发现PluginRegistry是一个接口,下面是PluginRegistry的代码。

 public interface PluginRegistry {  Registrar registrarFor(String pluginKey); }

PluginRegistry的实现是谁呢?是FlutterActivity,下面开发分析FlutterActivity,暂时看FlutterActivity比较重要,因为这个类是MainActivity的父类,还是PluginRegistry的具体实现类。

FlutterActivity分析

下面是FlutterActivity的代码。

 public class FlutterActivity extends Activity implements FlutterView.Provider, PluginRegistry, ViewFactory {  private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this);    private final FlutterActivityEvents eventDelegate = delegate;  private final FlutterView.Provider viewProvider = delegate;  private final PluginRegistry pluginRegistry = delegate;    @Override  public final boolean hasPlugin(String key) {  return pluginRegistry.hasPlugin(key);  }   @Override  public final Registrar registrarFor(String pluginKey) {  return pluginRegistry.registrarFor(pluginKey);  }   @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  eventDelegate.onCreate(savedInstanceState);  }   @Override  protected void onDestroy() {  eventDelegate.onDestroy();  super.onDestroy();  }     @Override  protected void onStop() {  eventDelegate.onStop();  super.onStop();  }  //省略了一些代码 }

从上面的代码中可以看出来,FlutterActivity是继承Activity和实现了PluginRegistry。分析一下onCreate,onStop,onDestroy这些生命周期方法被FlutterActivity.eventDelegate代理了,这个时候我们明白了,FlutterActivity就是一个空壳,真正实现是代理类FlutterActivityDelegate。

我们具体看一下,下面是FlutterActivity.onCreate()的代码。

  @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  eventDelegate.onCreate(savedInstanceState);  }

FlutterActivity.$onCreate()比较简单,调用了super的onCreate()eventDelegate.onCreate() ,也就是调用了代理类的onCreate方法,下面分析FlutterActivityDelegate。

FlutterActivityDelegate分析

从上面的分析可以得出结论,FlutterActivity什么都没有做,都交个了FlutterActivityDelegate去干,这里类实现了PluginRegistry,下面是FlutterActivityDelegate的代码。

 public final class FlutterActivityDelegate  implements FlutterActivityEvents,    FlutterView.Provider,    PluginRegistry {   @Override  public void onCreate(Bundle savedInstanceState) {    }    }

还是先分析FlutterActivityDelegate.onCreate() ,这个真正干活的onCreate方法还是比较复杂的,下面是FlutterActivityDelegate.onCreate()的代码。

 @Override public void onCreate(Bundle savedInstanceState) {  String[] args = getArgsFromIntent(activity.getIntent());//1  FlutterMain.ensureinitializationcomplete(activity.getApplicationContext(), args);//2  flutterView = viewFactory.createFlutterView(activity);//3  if (flutterView == null) {  FlutterNativeView nativeView = viewFactory.createFlutterNativeView();  flutterView = new FlutterView(activity, null, nativeView);//4  flutterView.setLayoutParams(matchParent);  activity.setContentView(flutterView);//5  launchView = createLaunchView();  if (launchView != null) {   addLaunchView();  }  }  if (loadIntent(activity.getIntent())) {  return;  }  String appBundlePath = FlutterMain.findAppBundlePath(activity.getApplicationContext());  if (appBundlePath != null) {  runBundle(appBundlePath);  } }

注释1

得到了一些参数,这些参数是干啥用的?我们拿一个trace-startup参数为例进行简单介绍下面是FlutterActivityDelegate.getArgsFromIntent()的代码。

 private static String[] getArgsFromIntent(Intent intent) {  ArrayList<String> args = new ArrayList<>();  if (intent.getBooleanExtra("trace-startup", false)) {  args.add("--trace-startup");  }  if (intent.getBooleanExtra("start-paused", false)) {  args.add("--start-paused");  }    if (!args.iSEMpty()) {  String[] argsArray = new String[args.size()];  return args.toArray(argsArray);  }  return null; }

当你安装一个App的时候,可以用下面这个命令,

 flutter run --trace-startup --profile

安装完之后会生下面这个json,

 {  "engineEnterTimestampMicros": 273508186457,  "timeToFrameworkInitMicros": 271420,  "timeToFirstFrameMicros": 469796,  "timeAfterFrameworkInitMicros": 198376 }

这个json会显示进入Flutter引擎的时间和展示应用第一帧的时间等等。

注释2

调用 FlutterMain.ensureInitializationComplete() ,这方法初始化了Flutter,下面是ensureInitializationComplete的代码。

  public static void ensureInitializationComplete(Context applicationContext, String[] args) {  if (Looper.myLooper() != Looper.getMainLooper()) {   throw new IllegalStateException("ensureInitializationComplete must be called on the main thread");  }  try {   sResourceExtractor.waitForCompletion();   List<String> shellArgs = new ArrayList<>();   shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat");     String appBundlePath = findAppBundlePath(applicationContext);   String appStoragePath = PathUtils.getFilesDir(applicationContext);      nativeInit(applicationContext, shellArgs.toArray(new String[0]),   appBundlePath, appStoragePath, engineCachesPath);//1  } catch (Exception e) {   LOG.e(TAG, "Flutter initialization failed.", e);   throw new RuntimeException(e);  }  }    //native方法  private static native void nativeInit(Context context, String[] args, String     bundlePath, String appStoragePath, String engineCachesPath);

先判断是不是主线程,如果不是主线程直接抛出异常。初始化参数调用 FlutterMain.nativeInit()方法,这个方法是native方法,主要的用途是初始化Flutter。

注释3

ViewFactory是一个接口,ViewFactory.createFlutterView()的具体实现有两个,分别是FlutterActivity.createFlutterView()FlutterFragmentActivity.createFlutterView()现在这个两个具体实现都返回null,也就是一定会走到注释4。

注释4

创建FlutterView,那么FlutterView是什么呢?看一下类的声明,下面是FlutterView的声明的代码,

 public class FlutterView extends SurfaceView implements BinaryMessenger, TextureRegistry   }

原来是一 SurfaceView,这个就很容易理解了。

注释5

关键来了,下面是调用setContentView的代码,

  activity.setContentView(flutterView);

把FlutterView加载到Activity中,折腾了天,就是做了这样一件事,说白了就是创建了一个FlutterView,并且把这个view显示到屏幕上。

下面是Flutter的启动流程图。

Flutter启动流程的深入解析

总结

android教程
脚本网站
android studio

脚本宝典总结

以上是脚本宝典为你收集整理的Flutter启动流程的深入解析全部内容,希望文章能够帮你解决Flutter启动流程的深入解析所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。