0%

Flutter Android 初始化流程

Flutter UI容器

承载Flutter的Android容器

Flutter容器包含有FlutterActivity和FlutterFragmentActivity。他们分别实现了Provider, PluginRegistry, ViewFactory,二者的方法主要通过FlutterActivityDelegate 代理出去

FlutterActivityDelegateFlutterActivityEventsProviderPluginRegistryFlutterActivityActivityViewFactoryFlutterFragmentActivityFragmentActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class FlutterActivity extends Activity implements Provider, PluginRegistry, ViewFactory{
private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this);
private final FlutterActivityEvents eventDelegate;
private final Provider viewProvider;
private final PluginRegistry pluginRegistry;
public FlutterActivity() {
this.eventDelegate = this.delegate;
this.viewProvider = this.delegate;
this.pluginRegistry = this.delegate;
}
}
public class FlutterFragmentActivity extends FragmentActivity implements Provider, PluginRegistry, ViewFactory {
private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this);
private final FlutterActivityEvents eventDelegate;
private final Provider viewProvider;
private final PluginRegistry pluginRegistry;

public FlutterFragmentActivity() {
this.eventDelegate = this.delegate;
this.viewProvider = this.delegate;
this.pluginRegistry = this.delegate;
}
}

其中 Provider 负责提供FlutterView

ProviderFlutterView getFlutterView()

PluginRegistry负责插件管理

PluginRegistryPluginRegistry.Registrar registrarFor(String var1);boolean hasPlugin(String var1);<T> T valuePublishedByPlugin(String var1);

ViewFactory 负责管理FlutterView和FlutterNative

ViewFactoryFlutterView createFlutterView(Context var1);FlutterNativeView createFlutterNativeView();boolean retainFlutterNativeView();
Flutter容器代理类 FlutterActivityDelegate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

public final class FlutterActivityDelegate implements FlutterActivityEvents, Provider, PluginRegistry {
public void onCreate(Bundle savedInstanceState) {
// 设置全屏
if (VERSION.SDK_INT >= 21) {
Window window = this.activity.getWindow();
window.addFlags(-2147483648);
window.setStatusBarColor(1073741824);
window.getDecorView().setSystemUiVisibility(1280);
}
// 获取activity入参
String[] args = getArgsFromIntent(this.activity.getIntent());
// 确认Flutter Engine初始化完成,详细见后面
FlutterMain.ensureInitializationComplete(this.activity.getApplicationContext(), args);

// 创建FlutterView

// 这里实际上调用的是FlutterActivity或FlutterFragmentActivity中的createFlutterView,默认返回null
this.flutterView = this.viewFactory.createFlutterView(this.activity);
if (this.flutterView == null) {
FlutterNativeView nativeView = this.viewFactory.createFlutterNativeView();

// 新建FlutterView
this.flutterView = new FlutterView(this.activity, (AttributeSet)null, nativeView);
this.flutterView.setLayoutParams(matchParent);
// activity 的ContentView设置为flutterView
this.activity.setContentView(this.flutterView);
// 创建并添加launchView
this.launchView = this.createLaunchView();
if (this.launchView != null) {
this.addLaunchView();
}
}

// 运行Flutter appBundle,也就是加载Flutter代码
if (!this.loadIntent(this.activity.getIntent())) {
String appBundlePath = FlutterMain.findAppBundlePath();
if (appBundlePath != null) {
this.runBundle(appBundlePath);
}

}
}
}
FlutterView

FlutterView 是Flutter在Native上实际的绘制视图。

FlutterViewSurfaceViewBinaryMessengerTextureRegistry

BinaryMessenger 是Flutter与Native同学的通道,后面会详细讲到
TextureRegistry 用于管理SurfaceTexture

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class FlutterView extends SurfaceView implements BinaryMessenger, TextureRegistry {

public FlutterView(Context context, AttributeSet attrs, FlutterNativeView nativeView) {


// 创建FlutterNativeView
if (nativeView == null) {
this.mNativeView = new FlutterNativeView(activity.getApplicationContext());
} else {
this.mNativeView = nativeView;
}

// 设置dartExecutor
this.dartExecutor = this.mNativeView.getDartExecutor();
// 设置flutterRenderer
this.flutterRenderer = new FlutterRenderer(this.mNativeView.getFlutterJNI());

// 设置渲染和视图大小信息
this.mIsSoftwareRenderingEnabled = FlutterJNI.nativeGetIsSoftwareRenderingEnabled();
this.mMetrics = new FlutterView.ViewportMetrics();
this.mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density;
this.setFocusable(true);
this.setFocusableInTouchMode(true);

// attachViewAndActivity
this.mNativeView.attachViewAndActivity(this, activity);

// 设置SurfaceCallback
this.mSurfaceCallback = new Callback() {
public void surfaceCreated(SurfaceHolder holder) {
FlutterView.this.assertAttached();
FlutterView.this.mNativeView.getFlutterJNI().onSurfaceCreated(holder.getSurface());
}

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
FlutterView.this.assertAttached();
FlutterView.this.mNativeView.getFlutterJNI().onSurfaceChanged(width, height);
}

public void surfaceDestroyed(SurfaceHolder holder) {
FlutterView.this.assertAttached();
FlutterView.this.mNativeView.getFlutterJNI().onSurfaceDestroyed();
}
};
this.getHolder().addCallback(this.mSurfaceCallback);

// 设置内置Channel
this.mActivityLifecycleListeners = new ArrayList();
this.mFirstFrameListeners = new ArrayList();
this.navigationChannel = new NavigationChannel(this.dartExecutor);
this.keyEventChannel = new KeyEventChannel(this.dartExecutor);
this.lifecycleChannel = new LifecycleChannel(this.dartExecutor);
this.localizationChannel = new LocalizationChannel(this.dartExecutor);
this.platformChannel = new PlatformChannel(this.dartExecutor);
this.systemChannel = new SystemChannel(this.dartExecutor);
this.settingsChannel = new SettingsChannel(this.dartExecutor);


final PlatformPlugin platformPlugin = new PlatformPlugin(activity, this.platformChannel);
this.addActivityLifecycleListener(new ActivityLifecycleListener() {
public void onPostResume() {
platformPlugin.updateSystemUiOverlays();
}
});
this.mImm = (InputMethodManager)this.getContext().getSystemService("input_method");
PlatformViewsController platformViewsController = this.mNativeView.getPluginRegistry().getPlatformViewsController();
this.mTextInputPlugin = new TextInputPlugin(this, this.dartExecutor, platformViewsController);
this.androidKeyProcessor = new AndroidKeyProcessor(this.keyEventChannel, this.mTextInputPlugin);
this.androidTouchProcessor = new AndroidTouchProcessor(this.flutterRenderer);
this.mNativeView.getPluginRegistry().getPlatformViewsController().attachTextInputPlugin(this.mTextInputPlugin);
this.sendLocalesToDart(this.getResources().getConfiguration());
this.sendUserPlatformSettingsToDart();

}
}

FlutterActivityDelegate 中我们知道,加载dart执行的是FlutterViewrunFromBundle

1
2
3
4
5
6
 public void runFromBundle(FlutterRunArguments args) {
this.assertAttached();
this.preRun();
this.mNativeView.runFromBundle(args);
this.postRun();
}

实际上调用的是mNativeView.runFromBundle(args)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class FlutterNativeView implements BinaryMessenger {
public void runFromBundle(FlutterRunArguments args) {
if (args.entrypoint == null) {
throw new AssertionError("An entrypoint must be specified");
} else {
this.assertAttached();
if (this.applicationIsRunning) {
throw new AssertionError("This Flutter engine instance is already running an application");
} else {
this.mFlutterJNI.runBundleAndSnapshotFromLibrary(args.bundlePath, args.entrypoint, args.libraryPath, this.mContext.getResources().getAssets());
this.applicationIsRunning = true;
}
}
}
}

可以看到,最后调用的是mFlutterJNI。

FlutterNativeView与FlutterJNI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class FlutterNativeView implements BinaryMessenger {
public FlutterNativeView(@NonNull Context context, boolean isBackgroundView) {
this.mContext = context;
// 创建FlutterPluginRegistry,插件注册器
this.mPluginRegistry = new FlutterPluginRegistry(this, context);
// 创建FlutterJNI
this.mFlutterJNI = new FlutterJNI();
// 将
this.mFlutterJNI.setRenderSurface(new FlutterNativeView.RenderSurfaceImpl());
// 创建DartExecutor
this.dartExecutor = new DartExecutor(this.mFlutterJNI, context.getAssets());
// addEngineLifecycleListener
this.mFlutterJNI.addEngineLifecycleListener(new FlutterNativeView.EngineLifecycleListenerImpl());
this.attach(this, isBackgroundView);
this.assertAttached();
}
// 加载Flutter Bundle
public void runFromBundle(FlutterRunArguments args) {
if (args.entrypoint == null) {
throw new AssertionError("An entrypoint must be specified");
} else {
this.assertAttached();
if (this.applicationIsRunning) {
throw new AssertionError("This Flutter engine instance is already running an application");
} else {
this.mFlutterJNI.runBundleAndSnapshotFromLibrary(args.bundlePath, args.entrypoint, args.libraryPath, this.mContext.getResources().getAssets());
this.applicationIsRunning = true;
}
}
}
}
小结
FlutterActivityFlutterActivityDelegateFlutterActivity 是主要承载页面,具体的实现由FlutterActivityDelegate代理FlutterActivityDelegate 创建FlutterView,并加载Flutter bundleFlutterViewFlutterView 继承于SurfaceView,为实际渲染的native viewFlutterView初始化时会设置UI相关的信息以及内置的Channel,FlutterView与FlutterNativeView相互绑定FlutterNativeViewFlutterNativeView继承于BinaryMessenger,并持有FlutterJNI,而FlutterJNI是Android与FlutterEngine交互的桥梁FlutterJNI大部分是jni的native方法,与Flutter Engine交互

Flutter Engine

Flutter 初始化

在使用Flutter前需要初始化Flutter

1
FlutterMain.startInitialization(applicationContext);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class FlutterMain {
public static void startInitialization(@NonNull Context applicationContext) {
if (!isRunningInRobolectricTest) {
startInitialization(applicationContext, new FlutterMain.Settings());
}
}
public static void startInitialization(@NonNull Context applicationContext, @NonNull FlutterMain.Settings settings) {
if (!isRunningInRobolectricTest) {
// 初始化必须在主线程
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("startInitialization must be called on the main thread");
} else if (sSettings == null) {
sSettings = settings;
long initStartTimestampMillis = SystemClock.uptimeMillis();
// 初始化配置,主要是读取metadata中自定义的libapp.so、flutter_assets、vm_snapshot_data和isolate_snapshot_data对于的路径
// 一般可以不是自行设置
initConfig(applicationContext);
// 初始化Flutter资源,从flutter_assets读取并加载资源
// 包含vm_snapshot_data,isolate_snapshot_data、kernel_blob.bin
initResources(applicationContext);
// 记载flutter.so
System.loadLibrary("flutter");
// 初始化Vsync工具
VsyncWaiter.getInstance((WindowManager)applicationContext.getSystemService("window")).init();
// 记录初始化耗时
long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis;
FlutterJNI.nativeRecordStartTimestamp(initTimeMillis);
}
}
}
}

android assets目录下flutter_assets

1
2
3
4
5
6
7
8
9
10
11
12
13
14
assets
└── flutter_assets
├── AssetManifest.json
├── FontManifest.json
├── LICENSE
├── fonts
│   └── MaterialIcons-Regular.ttf
├── isolate_snapshot_data
├── kernel_blob.bin
├── packages
│   └── cupertino_icons
│   └── assets
│   └── CupertinoIcons.ttf
└── vm_snapshot_data

FlutterActivityDelegate中,onCreate时,

1
2
3
4
5
public final class FlutterActivityDelegate{
public void onCreate(Bundle savedInstanceState) {
FlutterMain.ensureInitializationComplete(this.activity.getApplicationContext(), args);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class FlutterMain {
public static void ensureInitializationComplete(@NonNull Context applicationContext, @Nullable String[] args) {
if (!isRunningInRobolectricTest) {
// 确认在主线程,且sSettings不为空,sSettings在startInitialization中设置
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("ensureInitializationComplete must be called on the main thread");
} else if (sSettings == null) {
throw new IllegalStateException("ensureInitializationComplete must be called after startInitialization");
} else if (!sInitialized) {
try {

// 等待资源加载完成,在startInitialization中设置
if (sResourceExtractor != null) {
sResourceExtractor.waitForCompletion();
}

// 设置flutter参数
// icu-symbol-prefix, icu-native-lib-path,snapshot-asset-path,
// vm-snapshot-data,isolate-snapshot-data,cache-dir-path,log-tag
List<String> shellArgs = new ArrayList();
shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat");
ApplicationInfo applicationInfo = getApplicationInfo(applicationContext);
shellArgs.add("--icu-native-lib-path=" + applicationInfo.nativeLibraryDir + File.separator + "libflutter.so");
if (args != null) {
Collections.addAll(shellArgs, args);
}

String kernelPath = null;
String appStoragePath = PathUtils.getDataDirectory(applicationContext) + File.separator + sFlutterAssetsDir;
kernelPath = appStoragePath + File.separator + "kernel_blob.bin";
shellArgs.add("--snapshot-asset-path=" + appStoragePath);
shellArgs.add("--vm-snapshot-data=" + sVmSnapshotData);
shellArgs.add("--isolate-snapshot-data=" + sIsolateSnapshotData);
shellArgs.add("--cache-dir-path=" + PathUtils.getCacheDirectory(applicationContext));
if (sSettings.getLogTag() != null) {
shellArgs.add("--log-tag=" + sSettings.getLogTag());
}

appStoragePath = PathUtils.getFilesDir(applicationContext);
String engineCachesPath = PathUtils.getCacheDirectory(applicationContext);

// FlutterJNI 初始化Flutter Engine
FlutterJNI.nativeInit(applicationContext, (String[])shellArgs.toArray(new String[0]), kernelPath, appStoragePath, engineCachesPath);
sInitialized = true;
} catch (Exception var7) {
Log.e("FlutterMain", "Flutter initialization failed.", var7);
throw new RuntimeException(var7);
}
}
}
}
}

可以看到,所有与Flutter Engine相关的操作都是用过FlutterJNI来交互的

小结

Flutter Engine初始化主要是加载flutter.so,设置flutter_assets,并通过FlutterJNI设置到Flutter Engine中。

关于FlutterJNI相关的内容,再后面关于Flutter Engine定制中会详细介绍到。