这篇文章主要给大家介绍了关于Flutter启动流程的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用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实现短信验证码输入框 2023-04-29
- IOS获取系统相册中照片的示例代码 2023-01-03
- iOS Crash常规跟踪方法及Bugly集成运用详细介绍 2023-01-18
- MVVMLight项目Model View结构及全局视图模型注入器 2023-05-07
- iOS开发 全机型适配解决方法 2023-01-14
- Android Compose自定义TextField实现自定义的输入框 2023-05-13
- iOS中如何判断当前网络环境是2G/3G/4G/5G/WiFi 2023-06-18
- Flutter进阶之实现动画效果(三) 2022-10-28
- Android开发Compose集成高德地图实例 2023-06-15
- iOS开发使用XML解析网络数据 2022-11-12