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的启动流程图。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
上一篇: PHP数组遍历的几种常见方式总结
下一篇: Android开发菜单布局之表格布局示例