欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Flutter启动流程的深入解析

程序员文章站 2022-06-14 17:45:03
前言 flutter是怎么启动起来的,是在android的activity的启动之后吗?等等这样的问题,在这个文章中将被解答。 从mainactivity开始...

前言

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启动流程的深入解析

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。