Flutter 应用运行的本质还是原生应用的运行。那么在 Android 上, Flutter 框架是如何运行起来的呢?
本文基于 Flutter v1.10.5 版本源码
先回想下编写一个纯 Flutter 应用的场景:
- 创建项目,
flutter create
命令会生成 IOS, Android, Dart 三个项目结构
- 在 Dart 项目目录的
lib
文件夹下编写 Dart 代码
- 执行
flutter run
在 IOS 或 Android 上运行应用
这套流程下了,感觉完全不用接触 IOS 和 Android 的原生开发了。但是, 我们知道 Flutter 其实只是一个 UI 框架, 它是基于 IOS 和 Android 已有的机制运行的。所以 Flutter 应用运行的本质还是原生应用的运行。那么在 Android 上, Flutter 框架是如何运行起来的呢。
Android 应用的启动
首先, 简单来说. Android 应用的启动可以在 AndroidManifest
中配置, 启动使用的 Application
类(可不单独配置)和启动之后打开的第一个 Activity. 这个规则外部应该是不能干涉的. 所以, Flutter 应用首先肯定会打开一个 Activity
, 可能会使用自己单独的 Application
类.
flutter create
看下使用 flutter create
命令生成的项目中的 Android 部分:
android
├── app
│ ├── build.gradle
│ └── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── io
│ │ ├── flutter
│ │ │ └── plugins
│ │ │ └── GeneratedPluginRegistrant.java
│ │ └── github
│ │ └── stefanji
│ │ └── fluttergitlab
│ │ └── MainActivity.java
创建了一个 Activity: MainActivity.java
.
再看下 AndroidManifest
文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.stefanji.fluttergitlab">
<application
android:name="io.flutter.app.FlutterApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
|
不出所料, 应用启动之后, 首先会打开 MainActivity
. 而且 manifest
里还单独声明了一个 Application
类: FlutterApplication
. 这就说明, 应用启动的将会是这个类.
再看下 flutter build apk --debug
生成的 apk 文件:
├── assets
│ └── flutter_assets
│ ├── AssetManifest.json
│ ├── FontManifest.json
│ ├── LICENSE
│ ├── fonts
│ ├── isolate_snapshot_data
│ ├── kernel_blob.bin
│ ├── packages
│ └── vm_snapshot_data
├── classes.dex
├── lib
│ ├── arm64-v8a
│ │ └── libflutter.so
│ ├── armeabi-v7a
│ │ └── libflutter.so
│ ├── x86
│ │ └── libflutter.so
│ └── x86_64
│ └── libflutter.so
再对比下 flutter build apk --release
生成的:
├── assets
│ └── flutter_assets
│ ├── AssetManifest.json
│ ├── FontManifest.json
│ ├── LICENSE
│ ├── fonts
│ └── packages
├── classes.dex
├── lib
│ ├── arm64-v8a
│ │ ├── libapp.so
│ │ └── libflutter.so
│ └── armeabi-v7a
│ ├── libapp.so
│ └── libflutter.so
对比 release 打包和 debug 打包能发现, bebug 模式下 assets/flutter_assets 目录里会多出 isolate_snapshot_data
kernel_blob.bin
vm_snapshot_data
三个文件, 而 release 模式下打包则在 lib 目录下多出一个 libapp.so
动态链接库. 这些文件的区别, 现在还没清楚, 后面可能会遇到.
看了文件结构和打包的差异之后, 先从应用启动开始梳理.
应用启动
io.flutter.app.FlutterApplication
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class FlutterApplication extends Application {
@Override
@CallSuper
public void onCreate() {
super.onCreate();
FlutterMain.startInitialization(this);
}
private Activity mCurrentActivity = null;
public Activity getCurrentActivity() {
return mCurrentActivity;
}
public void setCurrentActivity(Activity mCurrentActivity) {
this.mCurrentActivity = mCurrentActivity;
}
}
|
没有特别多的代码, 但是有一行代码(FlutterMain.startInitialization
), 应该和 Flutter 框架的初始化有关.
Flutter 框架初始化
io.flutter.view.FlutterMain#startInitialization(android.content.Context, io.flutter.view.FlutterMain.Settings)
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
|
public static void startInitialization(@NonNull Context applicationContext, @NonNull Settings settings) {
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("startInitialization must be called on the main thread");
}
// Do not run startInitialization more than once.
if (sSettings != null) {
return;
}
sSettings = settings;
long initStartTimestampMillis = SystemClock.uptimeMillis();
initConfig(applicationContext);
initResources(applicationContext);
// 加载 libflutter.so
System.loadLibrary("flutter");
VsyncWaiter
.getInstance((WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE))
.init();
// We record the initialization time using SystemClock because at the start of the
// initialization we have not yet loaded the native library to call into dart_tools_api.h.
// To get Timeline timestamp of the start of initialization we simply subtract the delta
// from the Timeline timestamp at the current moment (the assumption is that the overhead
// of the JNI call is negligible).
long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis;
FlutterJNI.nativeRecordStartTimestamp(initTimeMillis);
}
|
initConfig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
private static void initConfig(@NonNull Context applicationContext) {
Bundle metadata = getApplicationInfo(applicationContext).metaData;
if (metadata == null) {
return;
}
// 读取一些文件名配置, 其对应的默认值就是上面打包的文件名
//libapp.so
sAotSharedLibraryName = metadata.getString(PUBLIC_AOT_SHARED_LIBRARY_NAME, DEFAULT_AOT_SHARED_LIBRARY_NAME);
//flutter_assets
sFlutterAssetsDir = metadata.getString(PUBLIC_FLUTTER_ASSETS_DIR_KEY, DEFAULT_FLUTTER_ASSETS_DIR);
//vm_snapshot_data
sVmSnapshotData = metadata.getString(PUBLIC_VM_SNAPSHOT_DATA_KEY, DEFAULT_VM_SNAPSHOT_DATA);
//isolate_snapshot_data
sIsolateSnapshotData = metadata.getString(PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY, DEFAULT_ISOLATE_SNAPSHOT_DATA);
}
|
initResources
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
private static void initResources(@NonNull Context applicationContext) {
new ResourceCleaner(applicationContext).start();
// 如果是 Debug 模式则把下面的文件从 assets/flutter_assets 目录中拷到 /data/data/packageName/app_flutter 目录中
if (BuildConfig.DEBUG) {
final String dataDirPath = PathUtils.getDataDirectory(applicationContext);
final String packageName = applicationContext.getPackageName();
final PackageManager packageManager = applicationContext.getPackageManager();
final AssetManager assetManager = applicationContext.getResources().getAssets();
sResourceExtractor = new ResourceExtractor(dataDirPath, packageName, packageManager, assetManager);
// 拷贝的刚好是 debug 模式下打包多出的 3 个文件
sResourceExtractor
.addResource(fromFlutterAssets(sVmSnapshotData))
.addResource(fromFlutterAssets(sIsolateSnapshotData))
.addResource(fromFlutterAssets(DEFAULT_KERNEL_BLOB));
sResourceExtractor.start();
}
}
|
libflutter.so 被加载时会运行的源码 shell/platform/android/library_loader.cc
其在 JNI_OnLoad 中做了两件事:
- 为
FlutterJNI
类注册 JNI 方法签名
- 把 cpp 代码要用到的 Java 方法, 在
FlutterJNI
类里找到 jmethodID, 并用 static 变量存起来
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// This is called by the VM when the shared library is first loaded.
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
// Initialize the Java VM.
fml::jni::InitJavaVM(vm);
JNIEnv* env = fml::jni::AttachCurrentThread();
bool result = false;
// Register FlutterMain.
result = flutter::FlutterMain::Register(env);
FML_CHECK(result);
// Register PlatformView
result = flutter::PlatformViewAndroid::Register(env);
FML_CHECK(result);
// Register VSyncWaiter.
result = flutter::VsyncWaiterAndroid::Register(env);
FML_CHECK(result);
return JNI_VERSION_1_4;
}
|
FlutterMain::Register 方法
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
|
bool FlutterMain::Register(JNIEnv* env) {
// 注册了两个方法:
// void nativeInit(Context, String, String, String, String)
// void nativeRecordStartTimestamp(long)
static const JNINativeMethod methods[] = {
{
.name = "nativeInit",
.signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
"lang/String;Ljava/lang/String;Ljava/lang/String;)V",
.fnPtr = reinterpret_cast<void*>(&Init),
},
{
.name = "nativeRecordStartTimestamp",
.signature = "(J)V",
.fnPtr = reinterpret_cast<void*>(&RecordStartTimestamp),
},
};
jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");
if (clazz == nullptr) {
return false;
}
return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0;
}
|
PlatformViewAndroid::Register
和 VsyncWaiterAndroid::Register
与上面类似.
回到 startInitialization 的 VsyncWaiter init
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
|
public class VsyncWaiter {
private static VsyncWaiter instance;
@NonNull
private final WindowManager windowManager;
public void init() {
// 把 this.asyncWaitForVsyncDelegate 存到 FlutterJNI 的 static 变量 asyncWaitForVsyncDelegate 中
// 当 FlutterJNI 的 asyncWaitForVsync 方法被 native 层调用时就会回调 asyncWaitForVsyncDelegate 的 asyncWaitForVsync 方法
// asyncWaitForVsync 方法执行时会 post 一个在下一个 Vsync 信号来时的回调到 Choreographer
FlutterJNI.setAsyncWaitForVsyncDelegate(this.asyncWaitForVsyncDelegate);
float fps = this.windowManager.getDefaultDisplay().getRefreshRate();
FlutterJNI.setRefreshRateFPS(fps);
}
private final AsyncWaitForVsyncDelegate asyncWaitForVsyncDelegate = new AsyncWaitForVsyncDelegate() {
public void asyncWaitForVsync(final long cookie) {
Choreographer.getInstance().postFrameCallback(new FrameCallback() {
// doFrame 将在下一个 Vsync 信号来时被调用
public void doFrame(long frameTimeNanos) {
float fps = VsyncWaiter.this.windowManager.getDefaultDisplay().getRefreshRate();
long refreshPeriodNanos = (long)(1.0E9D / (double)fps);
// 调用 shell/platform/android/vsync_waiter_android.cc#OnNativeVsync
FlutterJNI.nativeOnVsync(frameTimeNanos, frameTimeNanos + refreshPeriodNanos, cookie);
}
});
}
};
@NonNull
public static VsyncWaiter getInstance(@NonNull WindowManager windowManager) {
if (instance == null) {
instance = new VsyncWaiter(windowManager);
}
return instance;
}
private VsyncWaiter(@NonNull WindowManager windowManager) {
this.windowManager = windowManager;
}
}
|
至此, FlutterApplication onCreate
执行完毕, 主要做了:
- 加载
libflutter.so
- 如果是 debug 模式, 一些资源文件会被写到外部
- 注册了 Vsync 监听.
MainActivity 启动
接着看下 MainActivity
的代码:
1
2
3
4
5
6
7
8
|
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 一些自己创建的 plugin 的注册
GeneratedPluginRegistrant.registerWith(this);
}
}
|
没有特殊逻辑, 但是也没有 Android 开发中常见的 setContentView
. 进入父类 FlutterActivity
看下:
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
|
public class FlutterActivity extends Activity implements Provider, PluginRegistry, ViewFactory {
private static final String TAG = "FlutterActivity";
// 创建 FlutterActivityDelegate 对象
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 FlutterView getFlutterView() {
return this.viewProvider.getFlutterView();
}
public FlutterView createFlutterView(Context context) {
return null;
}
public FlutterNativeView createFlutterNativeView() {
return null;
}
public boolean retainFlutterNativeView() {
return false;
}
//...
public final Registrar registrarFor(String pluginKey) {
return this.pluginRegistry.registrarFor(pluginKey);
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.eventDelegate.onCreate(savedInstanceState);
}
protected void onStart() {
super.onStart();
this.eventDelegate.onStart();
}
public void onBackPressed() {
if (!this.eventDelegate.onBackPressed()) {
super.onBackPressed();
}
}
protected void onPostResume() {
super.onPostResume();
this.eventDelegate.onPostResume();
}
//... 省略其他几个回调
}
|
FlutterActivity
继承了 Android 原生的 Activity
, 实现了 3 个接口 Provider
PluginRegistry
ViewFactory
.
- 将
Activity
的生命周期回调都代理给 FlutterActivityDelegate
处理
- 涉及
FlutterView
的, 则交给 viewProvider
处理
- 涉及
Plugin
的, 交给 pluginRegistry
处理
onCreate
既然 onCreate
交给了 FlutterActivityDelegate
处理, 就看下这个 onCreate
里做了什么:
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
|
public void onCreate(Bundle savedInstanceState) {
//...
String[] args = getArgsFromIntent(this.activity.getIntent());
FlutterMain.ensureInitializationComplete(this.activity.getApplicationContext(), args);
// viewFactory 即是 FlutterActivity, FlutterActivity 中 createFlutterView 返回的是 null
this.flutterView = this.viewFactory.createFlutterView(this.activity);
if (this.flutterView == null) {
// FlutterActivity 中 createFlutterNativeView 返回的是 null
FlutterNativeView nativeView = this.viewFactory.createFlutterNativeView();
// 构造一个 FlutterView
this.flutterView = new FlutterView(this.activity, (AttributeSet)null, nativeView);
// matchParent: 一个静态 LayoutParams 变量, 宽高都 MATCH_PARENT
this.flutterView.setLayoutParams(matchParent);
// 熟悉的味道: 调用 FlutterActivity 的 setContentView, 将 FlutterView 添加到 Activity 的 ANDROID_CONTENT 布局里
this.activity.setContentView(this.flutterView);
// 创建闪屏
this.launchView = this.createLaunchView();
if (this.launchView != null) {
// 将闪屏添加到布局最上层, 闪屏结束之后, 会 remove launchView. 具体见 addLaunchView()
this.addLaunchView();
}
}
//...
}
|
通过 FlutterActivityDelegate
的 onCreate
, 看到了 FlutterActivity
是怎样显示出来的, 以及闪屏是怎样添加的. 但是还没有看到 Flutter 框架是怎么开始运行的.
ensureInitializationComplete
注意在 setContentView
之前, 有个调用 FlutterMain.ensureInitializationComplete
, 貌似与 Flutter 的初始化有关.
io.flutter.view.FlutterMain#ensureInitializationComplete
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
|
public static void ensureInitializationComplete(@NonNull Context applicationContext, @Nullable String[] args) {
if (!isRunningInRobolectricTest) {
//...
} else if (!sInitialized) {
// sInitialized 初始值是 false, 开始肯定走到这里
try {
// 添加一些参数
List<String> shellArgs = new ArrayList<>();
shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat");
ApplicationInfo applicationInfo = getApplicationInfo(applicationContext);
// libflutter.so
shellArgs.add("--icu-native-lib-path=" + applicationInfo.nativeLibraryDir + File.separator + DEFAULT_LIBRARY);
if (args != null) {
Collections.addAll(shellArgs, args);
}
String kernelPath = null;
if (BuildConfig.DEBUG) {
// DEBUG 下把多出的 3 个文件也添加
String snapshotAssetPath = PathUtils.getDataDirectory(applicationContext) + File.separator + sFlutterAssetsDir;
kernelPath = snapshotAssetPath + File.separator + DEFAULT_KERNEL_BLOB;
shellArgs.add("--" + SNAPSHOT_ASSET_PATH_KEY + "=" + snapshotAssetPath);
shellArgs.add("--" + VM_SNAPSHOT_DATA_KEY + "=" + sVmSnapshotData);
shellArgs.add("--" + ISOLATE_SNAPSHOT_DATA_KEY + "=" + sIsolateSnapshotData);
} else {
// Relase 下则把 libapp.so 添加
shellArgs.add("--" + AOT_SHARED_LIBRARY_NAME + "=" + sAotSharedLibraryName);
// Most devices can load the AOT shared library based on the library name
// with no directory path. Provide a fully qualified path to the library
// as a workaround for devices where that fails.
shellArgs.add("--" + AOT_SHARED_LIBRARY_NAME + "=" + applicationInfo.nativeLibraryDir + File.separator + sAotSharedLibraryName);
}
shellArgs.add("--cache-dir-path=" + PathUtils.getCacheDirectory(applicationContext));
if (sSettings.getLogTag() != null) {
shellArgs.add("--log-tag=" + sSettings.getLogTag());
}
// 调用 FlutterJNI nativeInit
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);
}
}
}
}
|
FlutterJNI.nativeInit 对应的 native 方法为 FlutterMain::Init
:
shell/platform/android/flutter_main.cc
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
|
void FlutterMain::Init(JNIEnv* env,
jclass clazz,
jobject context,
jobjectArray jargs,
jstring kernelPath,
jstring appStoragePath,
jstring engineCachesPath) {
std::vector<std::string> args;
args.push_back("flutter");
for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
args.push_back(std::move(arg));
}
auto command_line = fml::CommandLineFromIterators(args.begin(), args.end());
// 根据传递的 args 创建 Settings 对象
auto settings = SettingsFromCommandLine(command_line);
flutter::DartCallbackCache::SetCachePath(fml::jni::JavaStringToString(env, appStoragePath));
fml::paths::InitializeAndroidCachesPath(fml::jni::JavaStringToString(env, engineCachesPath));
flutter::DartCallbackCache::LoadCacheFromDisk();
if (!flutter::DartVM::IsRunningPrecompiledCode() && kernelPath) {
auto application_kernel_path =
fml::jni::JavaStringToString(env, kernelPath);
if (fml::IsFile(application_kernel_path)) {
settings.application_kernel_asset = application_kernel_path;
}
}
// 创建一个新的 FlutterMain 对象, 赋给 g_flutter_main 这个全局对象
g_flutter_main.reset(new FlutterMain(std::move(settings)));
// 调用 FlutterMain 的 SetupObservatoryUriCallback 方法
g_flutter_main->SetupObservatoryUriCallback(env);
}
|
FlutterMain 的构造函数, 使用初始化列表方式
1
2
|
FlutterMain::FlutterMain(flutter::Settings settings)
: settings_(std::move(settings)), observatory_uri_callback_() {}
|
SetupObservatoryUriCallback
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
|
void FlutterMain::SetupObservatoryUriCallback(JNIEnv* env) {
g_flutter_jni_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
env, env->FindClass("io/flutter/embedding/engine/FlutterJNI"));
if (g_flutter_jni_class->is_null()) {
return;
}
jfieldID uri_field = env->GetStaticFieldID(
g_flutter_jni_class->obj(), "observatoryUri", "Ljava/lang/String;");
if (uri_field == nullptr) {
return;
}
auto set_uri = [env, uri_field](std::string uri) {
fml::jni::ScopedJavaLocalRef<jstring> java_uri =
fml::jni::StringToJavaString(env, uri);
env->SetStaticObjectField(g_flutter_jni_class->obj(), uri_field,
java_uri.obj());
};
fml::MessageLoop::EnsureInitializedForCurrentThread();
fml::RefPtr<fml::TaskRunner> platform_runner =
fml::MessageLoop::GetCurrent().GetTaskRunner();
// 为 observatory_uri_callback_ 赋值
observatory_uri_callback_ = DartServiceIsolate::AddServerStatusCallback(
[platform_runner, set_uri](std::string uri) {
platform_runner->PostTask([uri, set_uri] { set_uri(uri); });
});
}
|
至此, ensureInitializationComplete
流程结束, 只是为全局指针 g_flutter_main 赋了一个 FlutterMain 对象, 还没发现与 Flutter 或 Dart 运行相关的流程. 所以, 回到 onCreate
中, 进入 FlutterView
看下.
FlutterView
由上文可知, FlutterView 是在 FlutterActivity onCreate
时创建的, FlutterView 的构造函数:
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 FlutterView(Context context, AttributeSet attrs, FlutterNativeView nativeView) {
super(context, attrs);
Activity activity = getActivity(getContext());
if (activity == null) {
throw new IllegalArgumentException("Bad context");
}
if (nativeView == null) {
// FlutterActivity 默认传递的 null
mNativeView = new FlutterNativeView(activity.getApplicationContext());
} else {
mNativeView = nativeView;
}
// 从 FlutterNativeView 中获取 DartExecutor
// 暂且把 DartExecutor 看做 Dart 的执行器 ?
dartExecutor = mNativeView.getDartExecutor();
// 创建 FlutterRenderer
flutterRenderer = new FlutterRenderer(mNativeView.getFlutterJNI());
mIsSoftwareRenderingEnabled = mNativeView.getFlutterJNI().nativeGetIsSoftwareRenderingEnabled();
mMetrics = new ViewportMetrics();
mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density;
setFocusable(true);
setFocusableInTouchMode(true);
mNativeView.attachViewAndActivity(this, activity);
mSurfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
assertAttached();
// 调到 platform_view_anroid_jni.cc#SurfaceCreated
mNativeView.getFlutterJNI().onSurfaceCreated(holder.getSurface());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
assertAttached();
// 调到 platform_view_anroid_jni.cc#SurfaceChanged
mNativeView.getFlutterJNI().onSurfaceChanged(width, height);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
assertAttached();
// 调到 platform_view_anroid_jni.cc#SurfaceDestroyed
mNativeView.getFlutterJNI().onSurfaceDestroyed();
}
};
// FlutterView 继承了 SurfaceView, 所以有 SurfaceHolder, 注册 mSurfaceCallback
getHolder().addCallback(mSurfaceCallback);
mActivityLifecycleListeners = new ArrayList<>();
mFirstFrameListeners = new ArrayList<>();
// Create all platform channels
navigationChannel = new NavigationChannel(dartExecutor);
keyEventChannel = new KeyEventChannel(dartExecutor);
lifecycleChannel = new LifecycleChannel(dartExecutor);
localizationChannel = new LocalizationChannel(dartExecutor);
platformChannel = new PlatformChannel(dartExecutor);
systemChannel = new SystemChannel(dartExecutor);
settingsChannel = new SettingsChannel(dartExecutor);
// Create and setup plugins
PlatformPlugin platformPlugin = new PlatformPlugin(activity, platformChannel);
addActivityLifecycleListener(new ActivityLifecycleListener() {
@Override
public void onPostResume() {
platformPlugin.updateSystemUiOverlays();
}
});
mImm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
PlatformViewsController platformViewsController = mNativeView.getPluginRegistry().getPlatformViewsController();
// 以下几位顾名思义一下?
mTextInputPlugin = new TextInputPlugin(this, dartExecutor, platformViewsController);
androidKeyProcessor = new AndroidKeyProcessor(keyEventChannel, mTextInputPlugin);
androidTouchProcessor = new AndroidTouchProcessor(flutterRenderer);
mNativeView.getPluginRegistry().getPlatformViewsController().attachTextInputPlugin(mTextInputPlugin);
// Send initial platform information to Dart
sendLocalesToDart(getResources().getConfiguration());
sendUserPlatformSettingsToDart();
}
|
可见在 FlutterView 创建时进行了许多工作, 其中 FlutterNativeView 负责了许多, 而且在这里终于见到 Dart 的影子了.
FlutterNativeView
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
|
// Flutter UI Display 回调
private final FlutterUiDisplayListener flutterUiDisplayListener = new FlutterUiDisplayListener() {
@Override
public void onFlutterUiDisplayed() {
if (mFlutterView == null) {
return;
}
mFlutterView.onFirstFrame();
}
@Override
public void onFlutterUiNoLongerDisplayed() {
// no-op
}
};
public FlutterNativeView(@NonNull Context context, boolean isBackgroundView) {
mContext = context;
mPluginRegistry = new FlutterPluginRegistry(this, context);
mFlutterJNI = new FlutterJNI();
// 将 flutterUiDisplayListener 添加到 FlutterJNI 的 flutterUiDisplayListeners 中, native 会在 Flutter 第一帧渲染时回调
mFlutterJNI.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);
this.dartExecutor = new DartExecutor(mFlutterJNI, context.getAssets());
// FlutterJNI 中的 EngineLifecycleListener 会被 native 在 FlutterEngine 重启时回调
mFlutterJNI.addEngineLifecycleListener(new EngineLifecycleListenerImpl());
attach(this, isBackgroundView);
assertAttached();
}
private void attach(FlutterNativeView view, boolean isBackgroundView) {
// 调用 platform_view_anroid_jni.cc#AttachJNI
mFlutterJNI.attachToNative(isBackgroundView);
// 注册 platform message handler 到 Dart 的执行上下文中
dartExecutor.onAttachedToJNI();
}
|
AttachJNI
platform_view_anroid_jni.cc#AttachJNI
1
2
3
4
5
6
7
8
9
10
11
|
static jlong AttachJNI(JNIEnv* env, jclass clazz, jobject flutterJNI, jboolean is_background_view) {
// 为 flutterJNI 对象创建一个 WeakGlobalRef
fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
// 构造一个 AndroidShellHolder 对象, 由 FlutterView.java 构造 FlutterNativeView 可知, is_background_view 为 false
auto shell_holder = std::make_unique<AndroidShellHolder>(FlutterMain::Get().GetSettings(), java_object, is_background_view);
if (shell_holder->IsValid()) {
return reinterpret_cast<jlong>(shell_holder.release());
} else {
return 0;
}
}
|
shell/platform/android/android_shell_holder.cc#AndroidShellHolder
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
AndroidShellHolder::AndroidShellHolder(
flutter::Settings settings,
fml::jni::JavaObjectWeakGlobalRef java_object,
bool is_background_view)
: settings_(std::move(settings)), java_object_(java_object) {
static size_t shell_count = 1;
auto thread_label = std::to_string(shell_count++);
// 调用 pthread_key_create 创建一个线程本地变量, 当线程释放是会调用 ThreadDestructCallback
// FML_CHECK 是一个工具方法, 当传递的 condition 为 false 时会打印日志
FML_CHECK(pthread_key_create(&thread_destruct_key_, ThreadDestructCallback) == 0);
if (is_background_view) {
} else {
// 创建 UI,GPU,IO 线程
// thread_label.ui thread_label.gpu thread_label.io
thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU | ThreadHost::Type::IO};
}
// Detach from JNI when the UI and GPU threads exit.
// 创建一个 closure, 执行时把 thread_destruct_key_ 存储的值设为 void
auto jni_exit_task([key = thread_destruct_key_]() {
FML_CHECK(pthread_setspecific(key, reinterpret_cast<void*>(1)) == 0);
});
thread_host_.ui_thread->GetTaskRunner()->PostTask(jni_exit_task);
if (!is_background_view) {
thread_host_.gpu_thread->GetTaskRunner()->PostTask(jni_exit_task);
}
// WeakPtr 的空构造函数相当于赋值 nullptr
fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
// on_create_platform_view 回调
Shell::CreateCallback<PlatformView> on_create_platform_view =
[is_background_view, java_object, &weak_platform_view](Shell& shell) {
std::unique_ptr<PlatformViewAndroid> platform_view_android;
if (is_background_view) {
} else {
// 构造一个 PlatformViewAndroid
platform_view_android = std::make_unique<PlatformViewAndroid>(
shell, // delegate
shell.GetTaskRunners(), // task runners
java_object, // java object handle for JNI interop
shell.GetSettings()
.enable_software_rendering // use software rendering
);
}
// 赋给 weak_platform_view
weak_platform_view = platform_view_android->GetWeakPtr();
return platform_view_android;
};
Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
};
// The current thread will be used as the platform thread. Ensure that the message loop is initialized.
// 确保当前线程的 MessageLoop 已经创建
fml::MessageLoop::EnsureInitializedForCurrentThread();
fml::RefPtr<fml::TaskRunner> gpu_runner;
fml::RefPtr<fml::TaskRunner> ui_runner;
fml::RefPtr<fml::TaskRunner> io_runner;
fml::RefPtr<fml::TaskRunner> platform_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();
if (is_background_view) {
} else {
// 获取每个线程的 TaskRunner, 通过 TaskRunner 可以传递 task 到线程的 MessageLoop 中
gpu_runner = thread_host_.gpu_thread->GetTaskRunner();
ui_runner = thread_host_.ui_thread->GetTaskRunner();
io_runner = thread_host_.io_thread->GetTaskRunner();
}
flutter::TaskRunners task_runners(thread_label, // label
platform_runner, // platform
gpu_runner, // gpu
ui_runner, // ui
io_runner // io
);
// 创建 Shell
shell_ = Shell::Create(task_runners, // task runners
settings_, // settings
on_create_platform_view, // platform view create callback
on_create_rasterizer // rasterizer create callback
);
platform_view_ = weak_platform_view;
FML_DCHECK(platform_view_);
is_valid_ = shell_ != nullptr;
if (is_valid_) {
task_runners.GetGPUTaskRunner()->PostTask([]() {
// Android describes -8 as "most important display threads, for
// compositing the screen and retrieving input events". Conservatively
// set the GPU thread to slightly lower priority than it.
if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
// Defensive fallback. Depending on the OEM, it may not be possible
// to set priority to -5.
if (::setpriority(PRIO_PROCESS, gettid(), -2) != 0) {
FML_LOG(ERROR) << "Failed to set GPU task runner priority";
}
}
});
task_runners.GetUITaskRunner()->PostTask([]() {
if (::setpriority(PRIO_PROCESS, gettid(), -1) != 0) {
FML_LOG(ERROR) << "Failed to set UI task runner priority";
}
});
}
}
|
ThreadHost
engine 使用到的所有线程的集合, 从中能看出 engine 一共使用了 4 个线程.
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
|
struct ThreadHost {
enum Type {
Platform = 1 << 0,
UI = 1 << 1,
GPU = 1 << 2,
IO = 1 << 3,
};
std::unique_ptr<fml::Thread> platform_thread;
std::unique_ptr<fml::Thread> ui_thread;
std::unique_ptr<fml::Thread> gpu_thread;
std::unique_ptr<fml::Thread> io_thread;
};
// 实现
ThreadHost::ThreadHost(std::string name_prefix, uint64_t mask) {
if (mask & ThreadHost::Type::Platform) {
platform_thread = std::make_unique<fml::Thread>(name_prefix + ".platform");
}
if (mask & ThreadHost::Type::UI) {
ui_thread = std::make_unique<fml::Thread>(name_prefix + ".ui");
}
if (mask & ThreadHost::Type::GPU) {
gpu_thread = std::make_unique<fml::Thread>(name_prefix + ".gpu");
}
if (mask & ThreadHost::Type::IO) {
io_thread = std::make_unique<fml::Thread>(name_prefix + ".io");
}
}
|
shell/common/shell.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
std::unique_ptr<Shell> Shell::Create(
TaskRunners task_runners,
Settings settings,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
// 创建 DartVM
auto vm = DartVMRef::Create(settings);
auto vm_data = vm->GetVMData();
return Shell::Create(std::move(task_runners), //
std::move(settings), //
vm_data->GetIsolateSnapshot(), // isolate snapshot
DartSnapshot::Empty(), // shared snapshot
std::move(on_create_platform_view), //
std::move(on_create_rasterizer), //
std::move(vm) //
);
}
|
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
|
std::unique_ptr<Shell> Shell::Create(
TaskRunners task_runners,
Settings settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer,
DartVMRef vm) {
if (!task_runners.IsValid() || !on_create_platform_view || !on_create_rasterizer) {
return nullptr;
}
fml::AutoResetWaitableEvent latch;
std::unique_ptr<Shell> shell;
// 立即运行或者将 task post 到 MessageLoop 中
fml::TaskRunner::RunNowOrPostTask(
task_runners.GetPlatformTaskRunner(),
{ shell = CreateShellOnPlatformThread(std::move(vm),
std::move(task_runners),
settings,
std::move(isolate_snapshot),
std::move(shared_snapshot),
on_create_platform_view,
on_create_rasterizer);
latch.Signal();
});
// 等待, 直到 CreateShellOnPlatformThread 完成
latch.Wait();
return shell;
}
|
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
DartVMRef vm,
TaskRunners task_runners,
Settings settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
if (!task_runners.IsValid()) {
return nullptr;
}
auto shell = std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings));
// 在 GPU 线程创建 光栅化器 Rasterizer
std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
auto rasterizer_future = rasterizer_promise.get_future();
fml::TaskRunner::RunNowOrPostTask(
task_runners.GetGPUTaskRunner(), [&rasterizer_promise, //
on_create_rasterizer, //
shell = shell.get() //
]() {
rasterizer_promise.set_value(on_create_rasterizer(*shell));
});
// 创建 PlatformViewAndroid 在 platform 线程(当前线程)
auto platform_view = on_create_platform_view(*shell.get());
if (!platform_view || !platform_view->GetWeakPtr()) {
return nullptr;
}
// Ask the platform view for the vsync waiter. This will be used by the engine
// to create the animator.
auto vsync_waiter = platform_view->CreateVSyncWaiter();
if (!vsync_waiter) {
return nullptr;
}
// Create the IO manager on the IO thread. The IO manager must be initialized
// first because it has state that the other subsystems depend on. It must
// first be booted and the necessary references obtained to initialize the
// other subsystems.
std::promise<std::unique_ptr<ShellIOManager>> io_manager_promise;
auto io_manager_future = io_manager_promise.get_future();
std::promise<fml::WeakPtr<ShellIOManager>> weak_io_manager_promise;
auto weak_io_manager_future = weak_io_manager_promise.get_future();
auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();
// TODO(gw280): The WeakPtr here asserts that we are derefing it on the
// same thread as it was created on. We are currently on the IO thread
// inside this lambda but we need to deref the PlatformView, which was
// constructed on the platform thread.
//
// https://github.com/flutter/flutter/issues/42948
fml::TaskRunner::RunNowOrPostTask(
io_task_runner,
[&io_manager_promise, //
&weak_io_manager_promise, //
platform_view = platform_view->GetWeakPtr(), //
io_task_runner //
]() {
auto io_manager = std::make_unique<ShellIOManager>(
platform_view.getUnsafe()->CreateResourceContext(), io_task_runner);
weak_io_manager_promise.set_value(io_manager->GetWeakPtr());
io_manager_promise.set_value(std::move(io_manager));
});
// Send dispatcher_maker to the engine constructor because shell won't have
// platform_view set until Shell::Setup is called later.
auto dispatcher_maker = platform_view->GetDispatcherMaker();
// Create the engine on the UI thread.
std::promise<std::unique_ptr<Engine>> engine_promise;
auto engine_future = engine_promise.get_future();
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetUITaskRunner(),
fml::MakeCopyable([&engine_promise, //
shell = shell.get(), //
&dispatcher_maker, //
isolate_snapshot = std::move(isolate_snapshot), //
shared_snapshot = std::move(shared_snapshot), //
vsync_waiter = std::move(vsync_waiter), //
&weak_io_manager_future //
]() mutable {
const auto& task_runners = shell->GetTaskRunners();
// The animator is owned by the UI thread but it gets its vsync pulses
// from the platform.
auto animator = std::make_unique<Animator>(*shell, task_runners,
std::move(vsync_waiter));
// 构造 Engine 对象
engine_promise.set_value(std::make_unique<Engine>(
*shell,
dispatcher_maker,
*shell->GetDartVM(),
std::move(isolate_snapshot),
std::move(shared_snapshot),
task_runners,
shell->GetSettings(),
std::move(animator),
weak_io_manager_future.get()
));
}));
if (!shell->Setup(std::move(platform_view),
engine_future.get(),
rasterizer_future.get(),
io_manager_future.get())
) {
return nullptr;
}
return shell;
}
|
shell/common/engine.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
runtime_controller_ = std::make_unique<RuntimeController>(
*this, // runtime delegate
&vm, // VM
std::move(isolate_snapshot), // isolate snapshot
std::move(shared_snapshot), // shared snapshot
task_runners_, // task runners
std::move(io_manager), // io manager
image_decoder_.GetWeakPtr(), // image decoder
settings_.advisory_script_uri, // advisory script uri 在 Setting 对象默认为 main.dart
settings_.advisory_script_entrypoint, // advisory script entrypoint 在 Setting 对象默认为 main
settings_.idle_notification_callback, // idle notification callback
settings_.isolate_create_callback, // isolate create callback
settings_.isolate_shutdown_callback, // isolate shutdown callback
settings_.persistent_isolate_data // persistent isolate data
);
|