前言
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的启动流程图。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对小牛知识库的支持。
本文向大家介绍Spring启动流程refresh()源码深入解析,包括了Spring启动流程refresh()源码深入解析的使用技巧和注意事项,需要的朋友参考一下 一、Spring容器的refresh() spring version:4.3.12 ,尚硅谷Spring注解驱动开发—源码部分 1 、prepareRefresh()刷新前的预处理; 2、 obtainFreshBeanFacto
本文的目的是分析 MOSN 的启动流程。基于 mosn 版本 v0.4.0,commit 为: dc35c8fc95435a47e6393db1c79dd9f60f7eb898 MOSN 简介 MOSN 是一款使用 Go 语言开发的网络代理软件,作为云原生的网络数据平面,旨在为服务提供多协议,模块化,智能化,安全的代理能力。 MOSN 在基于 Kubernetes 的 service mesh 中
系统启动时,引导管理器首先加载内核,内核被载入后执行以下操作: 内核自解压 初始化阶段 检测,初始化硬件 设置各种入口地址 初始化 IRQ 中断处理机制 启动 init 进程 初始化控制台、显示器 初始化 kernel_module init 阶段。init 进程启动后,执行当前运行级别的脚本: PCI总线初始化 网络初始化 文件系统初始化 加载文件系统 ……
我们知道 init 是 linux 的根进程,是所有进程的父进程。同样, xinit 是所有 Xwindow 进程的根进程 Startx startx 可以在命令行下启动图形界面。执行startx 命令时,实际执行这一命令: xinit /etc/X11/xinit/xinitrc -- /etc/X11/xinit/xserverrc 根据脚本 /etc/X11/xinit/xserver
读取 MBR 的信息,启动 Boot Manager第 22 章 Grub中向您介绍它的使用方式。 init进程 是 Linux 的根进程,所有的系统进程都是它的子进程。 通常情况下, /etc/rcS.d/ 目录下的启动脚本首先被执行,然后是 /etc/rcN.d/ 目录。例如您设定的运行级别为 3,那么它对应的启动目录为 /etc/rc3.d/ 。 Xwindow 为 Linux 下的图形用户
深入了解文本处理流程 用ElasticSearch进行开发时,你可能会被ElasticSearch提供的不同的搜索方式和查询类型所困扰。每种查询类型的运行机制都不尽相同,我们不能浮于表面,比如,比较区间查询和前缀查询之间的不同点。理解query的工作原理并知晓它们之间的区别是至关重要的,特别是基于ElasticSearch进行业务开发时,比如,处理多语言的文本。 不是所有的输入都会被分析 在探讨查