当前位置: 移动技术网 > IT编程>移动开发>Android > Flutter启动流程的深入解析

Flutter启动流程的深入解析

2019年07月23日  | 移动技术网IT编程  | 我要评论

我的体育老师下载,媒体平台,张震将军简历

前言

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的启动流程图。

总结

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网