文章内容基于 flutter 1.17.5 分析
一、FlutterApplication的初始化
在Flutter项目的AndrodManifest.xml配置了FutterApplication和MainActivity,所以先看在应用启动时FlutterApplication中做了什么事情。
FlutterApplication->onCreate
FlutterMain.startInitialization
FlutterLoader.getInstance().startInitialization
public void startInitialization(@NonNull Context applicationContext, @NonNull FlutterLoader.Settings settings) {
if (this.settings == null) {
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("startInitialization must be called on the main thread");
} else {
applicationContext = applicationContext.getApplicationContext();
this.settings = settings;
long initStartTimestampMillis = SystemClock.uptimeMillis();
this.initConfig(applicationContext);
this.initResources(applicationContext);
System.loadLibrary("flutter");
VsyncWaiter.getInstance((WindowManager)applicationContext.getSystemService("window")).init();
long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis;
FlutterJNI.nativeRecordStartTimestamp(initTimeMillis);
}
}
}
FlutterApplication在初始化过程做了以下的事情:
- initConfig 初始化配置信息
- initResources 初始化资源信息
- System.loadLibrary("flutter"); 加载flutter native库,注册JNI方法
- VsyncWaiter.getInstance((WindowManager)applicationContext.getSystemService("window")).init() 通过WM初始化VsyncWatier
1.1 初始化配置
private void initConfig(@NonNull Context applicationContext) {
Bundle metadata = this.getApplicationInfo(applicationContext).metaData;
if (metadata != null) {
this.aotSharedLibraryName = metadata.getString(PUBLIC_AOT_SHARED_LIBRARY_NAME, "libapp.so");
this.flutterAssetsDir = metadata.getString(PUBLIC_FLUTTER_ASSETS_DIR_KEY, "flutter_assets");
this.vmSnapshotData = metadata.getString(PUBLIC_VM_SNAPSHOT_DATA_KEY, "vm_snapshot_data");
this.isolateSnapshotData = metadata.getString(PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY, "isolate_snapshot_data");
}
}
主要初始化一些变量,包括aot的共享库名称,flutter的Asscets目录,VM的快照数据名称,isolate的快照数据名称。
1.2 初始化资源信息
private void initResources(@NonNull Context applicationContext) {
(new ResourceCleaner(applicationContext)).start();
String dataDirPath = PathUtils.getDataDirectory(applicationContext);
String packageName = applicationContext.getPackageName();
PackageManager packageManager = applicationContext.getPackageManager();
AssetManager assetManager = applicationContext.getResources().getAssets();
this.resourceExtractor = new ResourceExtractor(dataDirPath, packageName, packageManager, assetManager);
this.resourceExtractor.addResource(this.fullAssetPathFrom(this.vmSnapshotData)).
addResource(this.fullAssetPathFrom(this.isolateSnapshotData)).addResource(this.fullAssetPathFrom("kernel_blob.bin"));
this.resourceExtractor.start();
}
这里首先拿到Android的包管理器,然后再获取AssetManager拿到资源管理器对象,最后通过ResourceExtractor的addResource将flutter的资源文件添加到资源管理其中。
1.3 flutter库加载
flutter native库部分的分析需要单独去下载engine部分的代码,so库加载时候会调用其内部的JNI_OnLoad方法,这里我们先看看在JNI层,flutter库都做了哪些工作。
// shell/platform/android/library_loader.cc
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;
}
可以看到在JNI_OnLoad中有以下操作:
- initJavaVM 初始化Java虚拟机
- 注册FlutterMain
- 注册PlatformViewAndroid
- 注册VsyncWaiter
1.3.1 初始化java虚拟机
// fml/platform/android/jni_util.cc
static JavaVM* g_jvm = nullptr;
void InitJavaVM(JavaVM* vm) {
FML_DCHECK(g_jvm == nullptr);
g_jvm = vm;
}
这里只是将JavaVm虚拟机实例对象保存在全局的g_jvm中,我们知道Android在创建应用进程时会通过Zygote的fork为其创建JavaVM对象,这里的JavaVM对象实例就是来自于此。
1.3.2 注册FlutterMain
bool FlutterMain::Register(JNIEnv* env) {
static const JNINativeMethod methods[] = {
{
.name = "nativeInit",
.signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
"lang/String;Ljava/lang/String;Ljava/lang/String;J)V",
.fnPtr = reinterpret_cast<void*>(&Init),
},
{
.name = "nativePrefetchDefaultFontManager",
.signature = "()V",
.fnPtr = reinterpret_cast<void*>(&PrefetchDefaultFontManager),
},
};
jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");
if (clazz == nullptr) {
return false;
}
return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0;
}
这里通过注册了两个jni native方法nativeInit和nativePrefetchDefaultFontManager,它们分别对应于FlutterMain的Init方法和PrefetchDefaultFontManager。
1.3.3 注册PlatformViewAndroid
// shell/platform/android/platform_view_android_jni_impl.cc
bool PlatformViewAndroid::Register(JNIEnv* env) {
...
g_flutter_callback_info_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
env, env->FindClass("io/flutter/view/FlutterCallbackInformation"));
if (g_flutter_callback_info_class->is_null()) {
FML_LOG(ERROR) << "Could not locate FlutterCallbackInformation class";
return false;
}
g_flutter_callback_info_constructor = env->GetMethodID(
g_flutter_callback_info_class->obj(), "<init>",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
if (g_flutter_callback_info_constructor == nullptr) {
FML_LOG(ERROR) << "Could not locate FlutterCallbackInformation constructor";
return false;
}
g_flutter_jni_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
env, env->FindClass("io/flutter/embedding/engine/FlutterJNI"));
if (g_flutter_jni_class->is_null()) {
FML_LOG(ERROR) << "Failed to find FlutterJNI Class.";
return false;
}
...
return RegisterApi(env);
}
bool RegisterApi(JNIEnv* env) {
static const JNINativeMethod flutter_jni_methods[] = {
// Start of methods from FlutterJNI
{
.name = "nativeAttach",
.signature = "(Lio/flutter/embedding/engine/FlutterJNI;Z)J",
.fnPtr = reinterpret_cast<void*>(&AttachJNI),
},
{
.name = "nativeDestroy",
.signature = "(J)V",
.fnPtr = reinterpret_cast<void*>(&DestroyJNI),
},
{
.name = "nativeRunBundleAndSnapshotFromLibrary",
.signature = "(JLjava/lang/String;Ljava/lang/String;"
"Ljava/lang/String;Landroid/content/res/AssetManager;)V",
.fnPtr = reinterpret_cast<void*>(&RunBundleAndSnapshotFromLibrary),
},
{
.name = "nativeDispatchEmptyPlatformMessage",
.signature = "(JLjava/lang/String;I)V",
.fnPtr = reinterpret_cast<void*>(&DispatchEmptyPlatformMessage),
},
{
.name = "nativeDispatchPlatformMessage",
.signature = "(JLjava/lang/String;Ljava/nio/ByteBuffer;II)V",
.fnPtr = reinterpret_cast<void*>(&DispatchPlatformMessage),
},
...
};
if (env->RegisterNatives(g_flutter_jni_class->obj(), flutter_jni_methods,
fml::size(flutter_jni_methods)) != 0) {
FML_LOG(ERROR) << "Failed to RegisterNatives with FlutterJNI";
return false;
}
g_handle_platform_message_method =
env->GetMethodID(g_flutter_jni_class->obj(), "handlePlatformMessage",
"(Ljava/lang/String;[BI)V");
...
g_handle_platform_message_response_method = env->GetMethodID(
g_flutter_jni_class->obj(), "handlePlatformMessageResponse", "(I[B)V");
...
g_on_first_frame_method =
env->GetMethodID(g_flutter_jni_class->obj(), "onFirstFrame", "()V");
...
g_on_engine_restart_method =
env->GetMethodID(g_flutter_jni_class->obj(), "onPreEngineRestart", "()V");
...
g_create_overlay_surface_method =
env->GetMethodID(g_flutter_jni_class->obj(), "createOverlaySurface",
"()Lio/flutter/embedding/engine/FlutterOverlaySurface;");
...
return true;
}
PlateformView通过Register初始化了一堆Java对象的方法以供c++调用Java层的方法,同时通过RegisterApi注册了一些类的的JNI方法以供Java层调用c++的方法。
1.3.4 注册VsyncWaiter
// shell/platform/android/vsync_waiter_android.cc
bool VsyncWaiterAndroid::Register(JNIEnv* env) {
static const JNINativeMethod methods[] = {{
.name = "nativeOnVsync",
.signature = "(JJJ)V",
.fnPtr = reinterpret_cast<void*>(&OnNativeVsync),
}};
jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");
if (clazz == nullptr) {
return false;
}
g_vsync_waiter_class = new fml::jni::ScopedJavaGlobalRef<jclass>(env, clazz);
FML_CHECK(!g_vsync_waiter_class->is_null());
g_async_wait_for_vsync_method_ = env->GetStaticMethodID(
g_vsync_waiter_class->obj(), "asyncWaitForVsync", "(J)V");
FML_CHECK(g_async_wait_for_vsync_method_ != nullptr);
return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0;
}
VsyncWaiter通过Register中在jni层注册了nativeOnVsync方法,这个方法对应的native方法为OnNativeVsync,同时获取到java层FlutterJNI类的asyncWaitForVsync方法。
二、FlutterActivity的初始化
AndrodManifest.xml中的MainActivity继承自FlutterActivity。
class MainActivity: FlutterActivity() {}
它的默认实现为空,所以我们重点关注FlutterActivity内部的实现。
public class FlutterActivity extends Activity implements Host, LifecycleOwner {
@VisibleForTesting
protected FlutterActivityAndFragmentDelegate delegate;
...
protected void onCreate(@Nullable Bundle savedInstanceState) {
this.switchLaunchThemeForNormalTheme();
super.onCreate(savedInstanceState);
this.lifecycle.handleLifecycleEvent(Event.ON_CREATE);
this.delegate = new FlutterActivityAndFragmentDelegate(this);
this.delegate.onAttach(this);
this.delegate.onActivityCreated(savedInstanceState);
this.configureWindowForTransparency();
this.setContentView(this.createFlutterView());
this.configureStatusBarForFullscreenFlutterExperience();
}
protected void onStart() {
super.onStart();
this.lifecycle.handleLifecycleEvent(Event.ON_START);
this.delegate.onStart();
}
protected void onResume() {
super.onResume();
this.lifecycle.handleLifecycleEvent(Event.ON_RESUME);
this.delegate.onResume();
}
....
protected void onStop() {
super.onStop();
this.delegate.onStop();
this.lifecycle.handleLifecycleEvent(Event.ON_STOP);
}
...
}
从代码结构上来看,FlutterActivity将生命周期委托给了一个叫做FlutterActivityAndFragmentDelegate的对象,它在onCreate方法中创建。同时在创建完成后进行了onAttach和onActivityCreated方法的调用。随后通过setContentView为Activity设置视图对象,这个视图对象是通过CreateFlutterView创建的。我们看看它的实现。
@NonNull
private View createFlutterView() {
return this.delegate.onCreateView((LayoutInflater)null, (ViewGroup)null, (Bundle)null);
}
内部还是通过FlutterActivityAndFragmentDelegate对象的onCreateView方法创建,所以接下来我们重点关注这个类内部的实现。
2.1 FlutterActivityAndFragmentDelegate
从名称上来看这个类是Flutter在Android端的Activity和Fragment的委托对象。那么可以猜测Flutter会将众多与的Activity和Fragment有关的事务委托给该类的对象进行处理。下面我们重点看这个delegate对象在FlutterActivity初始化时的主要功能。
- onAttach()
- onCreateView()
在这之前我们先看看它的构造方法和基本成员
final class FlutterActivityAndFragmentDelegate {
@NonNull
private FlutterActivityAndFragmentDelegate.Host host;
@Nullable
private FlutterEngine flutterEngine;
@Nullable
private FlutterSplashView flutterSplashView;
@Nullable
private FlutterView flutterView;
@Nullable
private PlatformPlugin platformPlugin;
private boolean isFlutterEngineFromHost;
FlutterActivityAndFragmentDelegate(@NonNull FlutterActivityAndFragmentDelegate.Host host) {
this.host = host;
}
interface Host extends SplashScreenProvider, FlutterEngineProvider, FlutterEngineConfigurator {
}
...
}
FlutterActivity实现了FlutterActivityAndFragmentDelegate.Host接口,这个接口对象负责FlutterActivity和delegate的相互通信。成员里还有
-
flutterEngine代表着Flutter的渲染引擎
-
flutterSplashView应该是闪屏页的视图对象
-
flutterView是FlutterActivity承载的flutter视图对象
-
platformPlugin是平台插件对象
2.1.1 onAttach
//FlutterActivityAndFragmentDelegate.java
void onAttach(@NonNull Context context) {
this.ensureAlive();
if (this.flutterEngine == null) {
this.setupFlutterEngine();
}
this.platformPlugin = this.host.providePlatformPlugin(this.host.getActivity(), this.flutterEngine);
if (this.host.shouldAttachEngineToActivity()) {
Log.v("FlutterActivityAndFragmentDelegate", "Attaching FlutterEngine to the Activity that owns this Fragment.");
this.flutterEngine.getActivityControlSurface().attachToActivity(this.host.getActivity(), this.host.getLifecycle());
}
this.host.configureFlutterEngine(this.flutterEngine);
}
在delegate的onAttach中,进行了以下事情:
- 通过setupFlutterEngine 创建Flutter引擎。
- 通过attachToActivity将当前FlutterActivity和flutter引擎关联上
- 通过configureFlutterEngine配置flutter引擎
2.1.1.1 创建FlutterEngine
@VisibleForTesting
void setupFlutterEngine() {
...
this.flutterEngine = new FlutterEngine(this.host.getContext(), this.host.getFlutterShellArgs().toArray(), false);
this.isFlutterEngineFromHost = false;
...
}
//FlutterEgine的构造方法
public FlutterEngine(@NonNull Context context, @NonNull FlutterLoader flutterLoader, @NonNull FlutterJNI flutterJNI, @NonNull PlatformViewsController platformViewsController, @Nullable String[] dartVmArgs, boolean automaticallyRegisterPlugins) {
this.engineLifecycleListeners = new HashSet();
this.engineLifecycleListener = new FlutterEngine.EngineLifecycleListener() {
public void onPreEngineRestart() {
Log.v("FlutterEngine", "onPreEngineRestart()");
Iterator var1 = FlutterEngine.this.engineLifecycleListeners.iterator();
while(var1.hasNext()) {
FlutterEngine.EngineLifecycleListener lifecycleListener = (FlutterEngine.EngineLifecycleListener)var1.next();
lifecycleListener.onPreEngineRestart();
}
FlutterEngine.this.platformViewsController.onPreEngineRestart();
}
};
this.flutterJNI = flutterJNI;
//初始化引擎
flutterLoader.startInitialization(context.getApplicationContext());
flutterLoader.ensureInitializationComplete(context, dartVmArgs);
flutterJNI.addEngineLifecycleListener(this.engineLifecycleListener);
this.attachToJni();
this.dartExecutor = new DartExecutor(flutterJNI, context.getAssets());
this.dartExecutor.onAttachedToJNI();
//创建flutter渲染对象
this.renderer = new FlutterRenderer(flutterJNI);
this.accessibilityChannel = new AccessibilityChannel(this.dartExecutor, flutterJNI);
//创建各种不同的通道
this.keyEventChannel = new KeyEventChannel(this.dartExecutor);
this.lifecycleChannel = new LifecycleChannel(this.dartExecutor);
this.localizationChannel = new LocalizationChannel(this.dartExecutor);
this.navigationChannel = new NavigationChannel(this.dartExecutor);
this.platformChannel = new PlatformChannel(this.dartExecutor);
this.settingsChannel = new SettingsChannel(this.dartExecutor);
this.systemChannel = new SystemChannel(this.dartExecutor);
this.textInputChannel = new TextInputChannel(this.dartExecutor);
this.platformViewsController = platformViewsController;
this.pluginRegistry = new FlutterEnginePluginRegistry(context.getApplicationContext(), this, flutterLoader);
if (automaticallyRegisterPlugins) {
this.registerPlugins(); //注册插件
}
}
这段代码负责创建FlutterEngine对象flutterEngine。在FlutterEngine的构造方法中调用startInitialization进行一些初始化工作,在FlutterApplication创建时已经通过该方法进行初始化,这里再次调用保证其被初始化。随后通过ensureInitializationComplete完成剩下的初始化工作,最后为引擎创建不同的Channel对象然后通过registerPlugins注册插件。
2.1.1.2 ensureInitializationComplete
public void ensureInitializationComplete(@NonNull Context applicationContext, @Nullable String[] args) {
if (!this.initialized) {
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("ensureInitializationComplete must be called on the main thread");
} else if (this.settings == null) {
throw new IllegalStateException("ensureInitializationComplete must be called after startInitialization");
} else {
try {
if (this.resourceExtractor != null) {
this.resourceExtractor.waitForCompletion();
}
List<String> shellArgs = new ArrayList();
shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat");
ApplicationInfo applicationInfo = this.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 + this.flutterAssetsDir;
kernelPath = appStoragePath + File.separator + "kernel_blob.bin";
shellArgs.add("--snapshot-asset-path=" + appStoragePath);
shellArgs.add("--vm-snapshot-data=" + this.vmSnapshotData);
shellArgs.add("--isolate-snapshot-data=" + this.isolateSnapshotData);
shellArgs.add("--cache-dir-path=" + PathUtils.getCacheDirectory(applicationContext));
if (this.settings.getLogTag() != null) {
shellArgs.add("--log-tag=" + this.settings.getLogTag());
}
appStoragePath = PathUtils.getFilesDir(applicationContext);
String engineCachesPath = PathUtils.getCacheDirectory(applicationContext);
FlutterJNI.nativeInit(applicationContext, (String[])shellArgs.toArray(new String[0]), kernelPath, appStoragePath, engineCachesPath);
this.initialized = true;
} catch (Exception var8) {
Log.e("FlutterLoader", "Flutter initialization failed.", var8);
throw new RuntimeException(var8);
}
}
}
}
引擎的初始化必须是在Main thread中进行的,随后为启动引擎准备启动参数,并通过FlutterJNI的nativeInit方法进行初始化,该方法在1.3.2节中通过FlutterMain的Register方法注册。我们继续看看其内部如何进行初始化。
void FlutterMain::Init(JNIEnv* env,
jclass clazz,
jobject context,
jobjectArray jargs,
jstring kernelPath,
jstring appStoragePath,
jstring engineCachesPath,
jlong initTimeMillis) {
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());
auto settings = SettingsFromCommandLine(command_line);
int64_t init_time_micros = initTimeMillis * 1000;
settings.engine_start_timestamp =
std::chrono::microseconds(Dart_TimelineGetMicros() - init_time_micros);
// Restore the callback cache.
// TODO(chinmaygarde): Route all cache file access through FML and remove this
// setter.
flutter::DartCallbackCache::SetCachePath(
fml::jni::JavaStringToString(env, appStoragePath));
fml::paths::InitializeAndroidCachesPath(
fml::jni::JavaStringToString(env, engineCachesPath));
flutter::DartCallbackCache::LoadCacheFromDisk();
if (!flutter::DartVM::IsRunningPrecompiledCode() && kernelPath) {
// Check to see if the appropriate kernel files are present and configure
// settings accordingly.
auto application_kernel_path =
fml::jni::JavaStringToString(env, kernelPath);
if (fml::IsFile(application_kernel_path)) {
settings.application_kernel_asset = application_kernel_path;
}
}
settings.task_observer_add = [](intptr_t key, fml::closure callback) {
fml::MessageLoop::GetCurrent().AddTaskObserver(key, std::move(callback));
};
settings.task_observer_remove = [](intptr_t key) {
fml::MessageLoop::GetCurrent().RemoveTaskObserver(key);
};
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
// There are no ownership concerns here as all mappings are owned by the
// embedder and not the engine.
auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
return [mapping, size]() {
return std::make_unique<fml::NonOwnedMapping>(mapping, size);
};
};
settings.dart_library_sources_kernel =
make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize);
#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
// Not thread safe. Will be removed when FlutterMain is refactored to no
// longer be a singleton.
g_flutter_main.reset(new FlutterMain(std::move(settings)));
g_flutter_main->SetupObservatoryUriCallback(env);
}
该方法将传递过来的命令参数args和一些资源路径保存在settings中,然后再通过其创建一个FlutterMain对象。
2.1.1.3 attachToJni
//FlutterEngine.java
private void attachToJni() {
Log.v("FlutterEngine", "Attaching to JNI.");
this.flutterJNI.attachToNative(false);
...
}
//FlutterJni.java
public void attachToNative(boolean isBackgroundView) {
this.ensureRunningOnMainThread();
this.ensureNotAttachedToNative();
this.nativePlatformViewId = this.nativeAttach(this, isBackgroundView);
}
java层的FlutterEngine只是一个壳它需要attach到native层的引擎对象才算真正的创建完引擎,这里通过attachToJni方法完成和native引擎对象的绑定,在这之前需要保证运行在main thread同时该对象之前未attach过。最后通过nativeAttach完成绑定,这个jni方法是在1.3.3节 注册PlatformViewAndroid 注册的,它对应的native方法为AttachJNI。我们回到PlatformViewAndroid中看看nativeAttach的具体实现。
//shell/platform/android/platform_view_android_jni_impl.cc
static jlong AttachJNI(JNIEnv* env,
jclass clazz,
jobject flutterJNI,
jboolean is_background_view) {
fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
std::shared_ptr<PlatformViewAndroidJNI> jni_facade =
std::make_shared<PlatformViewAndroidJNIImpl>(java_object);
auto shell_holder = std::make_unique<AndroidShellHolder>(
FlutterMain::Get().GetSettings(), jni_facade, is_background_view);
if (shell_holder->IsValid()) {
return reinterpret_cast<jlong>(shell_holder.release());
} else {
return 0;
}
}
在AttachJNI方法中它创建了一个AndroidShellHolder对象,注意AndroidShellHolder构造方法的三个参数:
- 从FlutterMain拿到之前初始化的Settings对象
- PlatformViewAndroidJNIImpl
- is_background_view默认为false
2.1.2 创建AndroidShellHolder
//shell/platform/android/android_shell_holder.cc
AndroidShellHolder::AndroidShellHolder(
flutter::Settings settings,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
bool is_background_view)
: settings_(std::move(settings)), jni_facade_(jni_facade) {
static size_t shell_count = 1;
auto thread_label = std::to_string(shell_count++);
//创建线程
FML_CHECK(pthread_key_create(&thread_destruct_key_, ThreadDestructCallback) ==0);
...
//创建ThreadHost
thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU |
ThreadHost::Type::IO};
thread_host_.ui_thread->GetTaskRunner()->PostTask(jni_exit_task);
if (!is_background_view) {
thread_host_.raster_thread->GetTaskRunner()->PostTask(jni_exit_task);
}
fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
//创建PlatformView的回调,回调里创建一个PlatformViewAndroid对象
Shell::CreateCallback<PlatformView> on_create_platform_view =
[is_background_view, &jni_facade, &weak_platform_view](Shell& shell) {
std::unique_ptr<PlatformViewAndroid> platform_view_android;
if (is_background_view) {
platform_view_android = std::make_unique<PlatformViewAndroid>(
shell, // delegate
shell.GetTaskRunners(), // task runners
jni_facade // JNI interop
);
} else {
platform_view_android = std::make_unique<PlatformViewAndroid>(
shell, // delegate
shell.GetTaskRunners(), // task runners
jni_facade, // JNI interop
shell.GetSettings()
.enable_software_rendering // use software rendering
);
}
weak_platform_view = platform_view_android->GetWeakPtr();
return platform_view_android;
};
//创建了一个Rasterizer
Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners(),
shell.GetIsGpuDisabledSyncSwitch());
};
// The current thread will be used as the platform thread. Ensure that the
// message loop is initialized.
//初始化当前线程,并初始化四个runner,gup/ui/io/platform,同时保证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();
...
gpu_runner = thread_host_.raster_thread->GetTaskRunner();
ui_runner = thread_host_.ui_thread->GetTaskRunner();
io_runner = thread_host_.io_thread->GetTaskRunner();
...
//创建task runners
flutter::TaskRunners task_runners(thread_label, // label
platform_runner, // platform
gpu_runner, // raster
ui_runner, // ui
io_runner // io
);
//创建Shell对象
shell_ =
Shell::Create(task_runners, // task runners
GetDefaultPlatformData(), // window data
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_) {
//raster和ui线程的优先级
shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask([]() {
if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
if (::setpriority(PRIO_PROCESS, gettid(), -2) != 0) {
FML_LOG(ERROR) << "Failed to set GPU task runner priority";
}
}
});
shell_->GetTaskRunners().GetUITaskRunner()->PostTask([]() {
if (::setpriority(PRIO_PROCESS, gettid(), -1) != 0) {
FML_LOG(ERROR) << "Failed to set UI task runner priority";
}
});
}
}
AndroidShellHolder的构造方法主要完成以下任务:
-
创建ThreadHost
-
创建PlatformView的回调,在这里为PlatformViewAndroid
-
初始化当前线程,并初始化四个runner,gup/ui/io/platform,同时保证MessageLoop初始化完成
-
创建task runners
-
创建Shell对象
2.1.2.1 ThreadHost
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) {
raster_thread = std::make_unique<fml::Thread>(name_prefix + ".raster");
}
if (mask & ThreadHost::Type::IO) {
io_thread = std::make_unique<fml::Thread>(name_prefix + ".io");
}
if (mask & ThreadHost::Type::Profiler) {
profiler_thread = std::make_unique<fml::Thread>(name_prefix + ".profiler");
}
}
这里的mask为ThreadHost::Type::UI | ThreadHost::Type::GPU | ThreadHost::Type::IO,所以会先创建ui,gpu,io这三个线程。
2.1.2.2 创建Shell对象
// shell/common/shell.cc
std::unique_ptr<Shell> Shell::Create(
TaskRunners task_runners,
const PlatformData platform_data,
Settings settings,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
//初始化任务
PerformInitializationTasks(settings);
PersistentCache::SetCacheSkSL(settings.cache_sksl);
TRACE_EVENT0("flutter", "Shell::Create");
//创建DartVm
auto vm = DartVMRef::Create(settings);
FML_CHECK(vm) << "Must be able to initialize the VM.";
auto vm_data = vm->GetVMData();
//继续Shell的创建
return Shell::Create(std::move(task_runners), //
std::move(platform_data), //
std::move(settings), //
vm_data->GetIsolateSnapshot(), // isolate snapshot
on_create_platform_view, //
on_create_rasterizer, //
std::move(vm) //
);
}
创建Shell对象之前创建一个Dart虚拟机DartVm
2.1.2.3 创建Dart虚拟机
// runtime/dart_vm_lifecycle.cc
DartVMRef DartVMRef::Create(Settings settings,
fml::RefPtr<DartSnapshot> vm_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot) {
std::scoped_lock lifecycle_lock(gVMMutex);
...
// If there is already a running VM in the process, grab a strong reference to
// it.
//如果进程已经运行了一个VM,则拿到它的强引用返回
if (auto vm = gVM.lock()) {
FML_DLOG(WARNING) << "Attempted to create a VM in a process where one was "
"already running. Ignoring arguments for current VM "
"create call and reusing the old VM.";
// There was already a running VM in the process,
return DartVMRef{std::move(vm)};
}
std::scoped_lock dependents_lock(gVMDependentsMutex);
...
// If there is no VM in the process. Initialize one, hold the weak reference
// and pass a strong reference to the caller.
auto isolate_name_server = std::make_shared<IsolateNameServer>();
//创建虚拟机
auto vm = DartVM::Create(std::move(settings), //
std::move(vm_snapshot), //
std::move(isolate_snapshot), //
isolate_name_server //
);
...
return DartVMRef{std::move(vm)};
}
这里主要创建Dart虚拟机
2.1.2.4 继续Shell的创建
// shell/common/shell.cc
std::unique_ptr<Shell> Shell::Create(
TaskRunners task_runners,
const PlatformData platform_data,
Settings settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
DartVMRef vm) {
PerformInitializationTasks(settings);
PersistentCache::SetCacheSkSL(settings.cache_sksl);
TRACE_EVENT0("flutter", "Shell::CreateWithSnapshots");
if (!task_runners.IsValid() || !on_create_platform_view ||
!on_create_rasterizer) {
return nullptr;
}
fml::AutoResetWaitableEvent latch;
std::unique_ptr<Shell> shell;
fml::TaskRunner::RunNowOrPostTask(
task_runners.GetPlatformTaskRunner(),
fml::MakeCopyable([&latch, //
vm = std::move(vm), //
&shell, //
task_runners = std::move(task_runners), //
platform_data, //
settings, //
isolate_snapshot = std::move(isolate_snapshot), //
on_create_platform_view, //
on_create_rasterizer //
]() mutable {
shell = CreateShellOnPlatformThread(std::move(vm),
std::move(task_runners), //
platform_data, //
settings, //
std::move(isolate_snapshot), //
on_create_platform_view, //
on_create_rasterizer //
);
latch.Signal();
}));
latch.Wait();
return shell;
}
通过CreateShellOnPlatformThread创建Shell,继续看其实现
// shell/common/shell.cc
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
DartVMRef vm,
TaskRunners task_runners,
const PlatformData platform_data,
Settings settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
...
//创建Shell对象
auto shell =
std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings));
// Create the rasterizer on the raster thread.
//在raster线程创建rasterizer
std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
auto rasterizer_future = rasterizer_promise.get_future();
std::promise<fml::WeakPtr<SnapshotDelegate>> snapshot_delegate_promise;
auto snapshot_delegate_future = snapshot_delegate_promise.get_future();
fml::TaskRunner::RunNowOrPostTask(
task_runners.GetRasterTaskRunner(), [&rasterizer_promise, //
&snapshot_delegate_promise,
on_create_rasterizer, //
shell = shell.get() //
]() {
TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem");
std::unique_ptr<Rasterizer> rasterizer(on_create_rasterizer(*shell));
snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate());
rasterizer_promise.set_value(std::move(rasterizer));
});
// Create the platform view on the platform thread (this thread).
//在platform线程上创建platfomeview(当前线程)
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.
//为platform请求VsyncWaiter,引擎将用这个对象创建动画
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();
std::promise<fml::RefPtr<SkiaUnrefQueue>> unref_queue_promise;
auto unref_queue_future = unref_queue_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, //
&unref_queue_promise, //
platform_view = platform_view->GetWeakPtr(), //
io_task_runner, //
is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch() //
]() {
TRACE_EVENT0("flutter", "ShellSetupIOSubsystem");
auto io_manager = std::make_unique<ShellIOManager>(
platform_view.getUnsafe()->CreateResourceContext(),
is_backgrounded_sync_switch, io_task_runner);
weak_io_manager_promise.set_value(io_manager->GetWeakPtr());
unref_queue_promise.set_value(io_manager->GetSkiaUnrefQueue());
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.
//在UI线程上创建引擎
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, //
&platform_data, //
isolate_snapshot = std::move(isolate_snapshot), //
vsync_waiter = std::move(vsync_waiter), //
&weak_io_manager_future, //
&snapshot_delegate_future, //
&unref_queue_future //
]() mutable {
TRACE_EVENT0("flutter", "ShellSetupUISubsystem");
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_promise.set_value(std::make_unique<Engine>(
*shell, //
dispatcher_maker, //
*shell->GetDartVM(), //
std::move(isolate_snapshot), //
task_runners, //
platform_data, //
shell->GetSettings(), //
std::move(animator), //
weak_io_manager_future.get(), //
unref_queue_future.get(), //
snapshot_delegate_future.get() //
));
}));
if (!shell->Setup(std::move(platform_view), //
engine_future.get(), //
rasterizer_future.get(), //
io_manager_future.get()) //
) {
return nullptr;
}
return shell;
}
CreateShellOnPlatformThread方法主要功能:
-
完成Shell对象的创建
-
在raster线程创建rasterizer
-
在platform线程上创建platfomeview,通过on_create_platform_view回调创建,在2.1.2 创建AndroidShellHolder一节中我们知道创建的PlatformView实际为PlatformViewAndroid
-
为platform请求VsyncWaiter,引擎将用这个对象创建动画
-
在UI线程上创建引擎
-
通过Shell的建立platform_view
2.1.2.5 Rasterizer初始化
Rasterizer::Rasterizer(
Delegate& delegate,
TaskRunners task_runners,
std::unique_ptr<flutter::CompositorContext> compositor_context,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch)
: delegate_(delegate),
task_runners_(std::move(task_runners)),
compositor_context_(std::move(compositor_context)),
user_override_resource_cache_bytes_(false),
weak_factory_(this),
is_gpu_disabled_sync_switch_(is_gpu_disabled_sync_switch) {
FML_DCHECK(compositor_context_);
}
2.1.2.6 PlatformViewAndroid创建
// shell/platform/android/platform_view_android.cc
PlatformViewAndroid::PlatformViewAndroid(
PlatformView::Delegate& delegate,
flutter::TaskRunners task_runners,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
bool use_software_rendering)
: PlatformView(delegate, std::move(task_runners)),
jni_facade_(jni_facade),
platform_view_android_delegate_(jni_facade) {
std::shared_ptr<AndroidContext> android_context;
if (use_software_rendering) {
android_context =
std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
} else {
#if SHELL_ENABLE_VULKAN
android_context =
std::make_shared<AndroidContext>(AndroidRenderingAPI::kVulkan);
#else // SHELL_ENABLE_VULKAN
android_context = std::make_shared<AndroidContextGL>(
AndroidRenderingAPI::kOpenGLES,
fml::MakeRefCounted<AndroidEnvironmentGL>());
#endif // SHELL_ENABLE_VULKAN
}
FML_CHECK(android_context && android_context->IsValid())
<< "Could not create an Android context.";
android_surface_ = SurfaceFactory(std::move(android_context), jni_facade);
FML_CHECK(android_surface_ && android_surface_->IsValid())
<< "Could not create an OpenGL, Vulkan or Software surface to setup "
"rendering.";
}
AndroidSurface有三种渲染方式:软件渲染,VULKAN渲染,GLES渲染。它通过SurfaceFactor创建。
2.1.2.7 创建Engine
Engine::Engine(Delegate& delegate,
const PointerDataDispatcherMaker& dispatcher_maker,
DartVM& vm,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
TaskRunners task_runners,
const PlatformData platform_data,
Settings settings,
std::unique_ptr<Animator> animator,
fml::WeakPtr<IOManager> io_manager,
fml::RefPtr<SkiaUnrefQueue> unref_queue,
fml::WeakPtr<SnapshotDelegate> snapshot_delegate)
: delegate_(delegate),
settings_(std::move(settings)),
animator_(std::move(animator)),
activity_running_(true),
have_surface_(false),
image_decoder_(task_runners,
vm.GetConcurrentWorkerTaskRunner(),
io_manager),
task_runners_(std::move(task_runners)),
weak_factory_(this) {
// Runtime controller is initialized here because it takes a reference to this
// object as its delegate. The delegate may be called in the constructor and
// we want to be fully initilazed by that point.
runtime_controller_ = std::make_unique<RuntimeController>(
*this, // runtime delegate
&vm, // VM
std::move(isolate_snapshot), // isolate snapshot
task_runners_, // task runners
std::move(snapshot_delegate),
std::move(io_manager), // io manager
std::move(unref_queue), // Skia unref queue
image_decoder_.GetWeakPtr(), // image decoder
settings_.advisory_script_uri, // advisory script uri
settings_.advisory_script_entrypoint, // advisory script entrypoint
settings_.idle_notification_callback, // idle notification callback
platform_data, // platform data
settings_.isolate_create_callback, // isolate create callback
settings_.isolate_shutdown_callback, // isolate shutdown callback
settings_.persistent_isolate_data // persistent isolate data
);
pointer_data_dispatcher_ = dispatcher_maker(*this);
}
在Engine构造方法中会创建RuntimeController,按名称应该叫做运行时控制器。
2.1.2.8 Shell::Setup
bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,
std::unique_ptr<Engine> engine,
std::unique_ptr<Rasterizer> rasterizer,
std::unique_ptr<ShellIOManager> io_manager) {
if (is_setup_) {
return false;
}
if (!platform_view || !engine || !rasterizer || !io_manager) {
return false;
}
platform_view_ = std::move(platform_view);
engine_ = std::move(engine);
rasterizer_ = std::move(rasterizer);
io_manager_ = std::move(io_manager);
// The weak ptr must be generated in the platform thread which owns the unique
// ptr.
weak_engine_ = engine_->GetWeakPtr();
weak_rasterizer_ = rasterizer_->GetWeakPtr();
weak_platform_view_ = platform_view_->GetWeakPtr();
// Setup the time-consuming default font manager right after engine created.
fml::TaskRunner::RunNowOrPostTask(task_runners_.GetUITaskRunner(),
[engine = weak_engine_] {
if (engine) {
engine->SetupDefaultFontManager();
}
});
is_setup_ = true;
vm_->GetServiceProtocol()->AddHandler(this, GetServiceProtocolDescription());
PersistentCache::GetCacheForProcess()->AddWorkerTaskRunner(
task_runners_.GetIOTaskRunner());
PersistentCache::GetCacheForProcess()->SetIsDumpingSkp(
settings_.dump_skp_on_shader_compilation);
if (settings_.purge_persistent_cache) {
PersistentCache::GetCacheForProcess()->Purge();
}
// TODO(gw280): The WeakPtr here asserts that we are derefing it on the
// same thread as it was created on. Shell is constructed on the platform
// thread but we need to call into the Engine on the UI thread, so we need
// to use getUnsafe() here to avoid failing the assertion.
//
// https://github.com/flutter/flutter/issues/42947
display_refresh_rate_ = weak_engine_.getUnsafe()->GetDisplayRefreshRate();
return true;
}
2.1.3 onCreateView
在FlutterActivity的onCreate中,delegate的onAttach方法完成了DartVm的创建,以及三个Thread(gup ,ui ,io),还创建了引擎对象Engine。随后通过CreateFlutterView来为FlutterActivity创建视图对象,最终它还是调用了delegate的onCreateView完成此任务。
View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.v("FlutterActivityAndFragmentDelegate", "Creating FlutterView.");
this.ensureAlive();
//创建flutter视图对象
if (this.host.getRenderMode() == RenderMode.surface) {
FlutterSurfaceView flutterSurfaceView = new FlutterSurfaceView(this.host.getActivity(), this.host.getTransparencyMode() == TransparencyMode.transparent);
this.host.onFlutterSurfaceViewCreated(flutterSurfaceView);
this.flutterView = new FlutterView(this.host.getActivity(), flutterSurfaceView);
} else {
FlutterTextureView flutterTextureView = new FlutterTextureView(this.host.getActivity());
this.host.onFlutterTextureViewCreated(flutterTextureView);
this.flutterView = new FlutterView(this.host.getActivity(), flutterTextureView);
}
this.flutterView.addOnFirstFrameRenderedListener(this.flutterUiDisplayListener);
this.flutterSplashView = new FlutterSplashView(this.host.getContext());
if (VERSION.SDK_INT >= 17) {
this.flutterSplashView.setId(View.generateViewId());
} else {
this.flutterSplashView.setId(486947586);
}
this.flutterSplashView.displayFlutterViewWithSplash(this.flutterView, this.host.provideSplashScreen());
Log.v("FlutterActivityAndFragmentDelegate", "Attaching FlutterEngine to FlutterView.");
//将Flutter视图attach 到FlutterEngine上
this.flutterView.attachToFlutterEngine(this.flutterEngine);
return this.flutterSplashView;
}
onCreateView负责为FlutterActivity创建视图对象。首先根据渲染模式决定创建何种视图,如果为RenderMode.surface则通过FlutterSurfaceView创建FlutterView,它内部实际上是SurfaceView实现。否则通过FlutterTextureView构建,内部通过TextureView实现。
在FlutterActivity中默认通过以下条件来判断渲染模式:
public RenderMode getRenderMode() {
return this.getBackgroundMode() == BackgroundMode.opaque ? RenderMode.surface : RenderMode.texture;
}
也就是说如果背景是不透明模式,则渲染模式就是RenderMode.surface。接下来创建一个FlutterSplashView(实际是个FrameLayout)并且返回这个闪屏View给Host Activity,因为闪屏页是页面的第一个视图,随后的内容通过FlutterEngine渲染到flutterView上,这里通过attachToFlutterEngine将其和引擎关联上。我们先看看FlutterView的构造方法
// FlutterView.java
public FlutterView(@NonNull Context context, @NonNull FlutterView.RenderMode renderMode) {
super(context, (AttributeSet)null);
this.flutterUiDisplayListeners = new HashSet();
this.flutterEngineAttachmentListeners = new HashSet();
this.viewportMetrics = new ViewportMetrics();
this.onAccessibilityChangeListener = new NamelessClass_2();
this.flutterUiDisplayListener = new NamelessClass_1();
if (renderMode == FlutterView.RenderMode.surface) {
this.flutterSurfaceView = new FlutterSurfaceView(context);
this.renderSurface = this.flutterSurfaceView;
} else {
this.flutterTextureView = new FlutterTextureView(context);
this.renderSurface = this.flutterTextureView;
}
this.init();
}
FlutterView构造方法通过FlutterSurfaceView 和FlutterTextView初始化RenderSurface,因为它们内部都实现了这个RenderSurface的接口。
//RenderSurface.java
public interface RenderSurface {
@Nullable
FlutterRenderer getAttachedRenderer();
void attachToRenderer(@NonNull FlutterRenderer var1);
void detachFromRenderer();
}
2.1.3.1 attachToFlutterEngine
接下来看看attachToFlutterEngine内部的实现
//FlutterView.class
public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) {
...
this.flutterEngine = flutterEngine;
//从引擎获取到渲染FlutterRenderer对象
FlutterRenderer flutterRenderer = this.flutterEngine.getRenderer();
this.isFlutterUiDisplayed = flutterRenderer.isDisplayingFlutterUi();
//将视图绑定到FlutterRenderer上
this.renderSurface.attachToRenderer(flutterRenderer);
flutterRenderer.addIsDisplayingFlutterUiListener(this.flutterUiDisplayListener);
this.textInputPlugin = new TextInputPlugin(this, this.flutterEngine.getDartExecutor(), this.flutterEngine.getPlatformViewsController());
this.androidKeyProcessor = new AndroidKeyProcessor(this.flutterEngine.getKeyEventChannel(), this.textInputPlugin);
this.androidTouchProcessor = new AndroidTouchProcessor(this.flutterEngine.getRenderer());
this.accessibilityBridge = new AccessibilityBridge(this, flutterEngine.getAccessibilityChannel(), (AccessibilityManager)this.getContext().getSystemService("accessibility"), this.getContext().getContentResolver(), this.flutterEngine.getPlatformViewsController());
this.accessibilityBridge.setOnAccessibilityChangeListener(this.onAccessibilityChangeListener);
this.resetWillNotDraw(this.accessibilityBridge.isAccessibilityEnabled(), this.accessibilityBridge.isTouchExplorationEnabled());
this.flutterEngine.getPlatformViewsController().attachAccessibilityBridge(this.accessibilityBridge);
this.textInputPlugin.getInputMethodManager().restartInput(this);
this.sendUserSettingsToFlutter();
this.sendLocalesToFlutter(this.getResources().getConfiguration());
this.sendViewportMetricsToFlutter();
//将视图绑定到引擎的PlatformViewsController上
flutterEngine.getPlatformViewsController().attachToView(this);
...
}
在attachToFlutterEngine中,先通过flutterEngine获取到一个FlutterRenderer,这个对象应该就是用来渲染视图的,随后将FlutterView的renderSurface attach到它上面。最后引擎还会获取到一个PlatFormViewController将其attach到当前view上。
2.1.3.2 attachToRenderer
// FlutterSurfaceView.java
public void attachToRenderer(@NonNull FlutterRenderer flutterRenderer) {
...
this.flutterRenderer = flutterRenderer;
this.isAttachedToFlutterRenderer = true;
this.flutterRenderer.addIsDisplayingFlutterUiListener(this.flutterUiDisplayListener);
if (this.isSurfaceAvailableForRendering) {
Log.v("FlutterSurfaceView", "Surface is available for rendering. Connecting FlutterRenderer to Android surface.");
this.connectSurfaceToRenderer();
}
}
private void connectSurfaceToRenderer() {
if (this.flutterRenderer != null && this.getHolder() != null) {
this.flutterRenderer.startRenderingToSurface(this.getHolder().getSurface());
} else {
throw new IllegalStateException("connectSurfaceToRenderer() should only be called when flutterRenderer and getHolder() are non-null.");
}
}
//FlutterRenderer.java
public void startRenderingToSurface(@NonNull Surface surface) {
if (this.surface != null) {
this.stopRenderingToSurface();
}
this.surface = surface;
this.flutterJNI.onSurfaceCreated(surface);
}
@UiThread
public void onSurfaceCreated(@NonNull Surface surface) {
this.ensureRunningOnMainThread();
this.ensureAttachedToNative();
this.nativeSurfaceCreated(this.nativePlatformViewId, surface);
}
这里我们看看FlutterSurfaceView中对于attachToRenderer的实现即可,FlutterTextView的留给读者自行分析,方法首先添加了一个flutter ui的listener监听,随后通过connectSurfaceToRenderer()连接到FlutterRenderer。FlutterRender 调用startRenderingToSurface并将当前FlutterSurfaceView的绘图表面对象Surface传递给它,最后通过flutterJNI.onSurfaceCreated调用到jni的nativeSurfaceCreated,这个jni方法在1.3.3 注册PlatformViewAndroid节RegisterApi中注册,它对应的native方法是SurfaceCreated。
2.1.3.3 SurfaceCreated
//shell/platform/android/platform_view_android_jni_impl.cc
static void SurfaceCreated(JNIEnv* env,
jobject jcaller,
jlong shell_holder,
jobject jsurface) {
// Note: This frame ensures that any local references used by
// ANativeWindow_fromSurface are released immediately. This is needed as a
// workaround for https://code.google.com/p/android/issues/detail?id=68174
fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);
auto window = fml::MakeRefCounted<AndroidNativeWindow>(
ANativeWindow_fromSurface(env, jsurface));
ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyCreated(std::move(window));
}
//shell/platform/android/platform_view_android.cc
void PlatformViewAndroid::NotifyCreated(
fml::RefPtr<AndroidNativeWindow> native_window) {
if (android_surface_) {
InstallFirstFrameCallback();
fml::AutoResetWaitableEvent latch;
fml::TaskRunner::RunNowOrPostTask(
task_runners_.GetRasterTaskRunner(),
[&latch, surface = android_surface_.get(),
native_window = std::move(native_window)]() {
surface->SetNativeWindow(native_window);
latch.Signal();
});
latch.Wait();
}
PlatformView::NotifyCreated();
}
可以看到ANativeWindow_fromSurface从surface创建一个ANativeWindow,这个ANativeWindow想必看过Android源码的都了解,它代表的是本地窗口,是GPU渲染到屏幕的桥接。后面使用ANDROID_SHELL_HOLDER获取到PlatformView,这里就是PlatformViewAndroid对象,通知窗口创建。
三、引擎的启动过程
在FlutterActivity中的onCreate中,通过委托类FlutterActivityAndFragmentDelegate完成了Flutter引擎初始化和视图的准备工作。那么接下来就是引擎的启动过程了,这部分是在onStart中进行的。
// FlutterActivityAndFragmentDelegate.java
void onStart() {
Log.v("FlutterActivityAndFragmentDelegate", "onStart()");
this.ensureAlive();
this.doInitialFlutterViewRun();
}
private void doInitialFlutterViewRun() {
if (this.host.getCachedEngineId() == null) {
if (!this.flutterEngine.getDartExecutor().isExecutingDart()) {
if (this.host.getInitialRoute() != null) {
this.flutterEngine.getNavigationChannel().setInitialRoute(this.host.getInitialRoute());
}
DartEntrypoint entrypoint = new DartEntrypoint(this.host.getAppBundlePath(), this.host.getDartEntrypointFunctionName());
this.flutterEngine.getDartExecutor().executeDartEntrypoint(entrypoint);
}
}
}
public String getDartEntrypointFunctionName() {
try {
ActivityInfo activityInfo = this.getPackageManager().getActivityInfo(this.getComponentName(), 128);
Bundle metadata = activityInfo.metaData;
String desiredDartEntrypoint = metadata != null ? metadata.getString("io.flutter.Entrypoint") : null;
return desiredDartEntrypoint != null ? desiredDartEntrypoint : "main";
} catch (NameNotFoundException var4) {
return "main";
}
}
在onStart方法中调用doInitialFlutterViewRun开始FlutterView的渲染工作,在该方法内部通过executeDartEntrypoint执行,这里会传递给其一个DartEntryPoint ,顾名思义Dart的接入点。这个对象通过getAppBundlePath和getDartEntrypointFunctionName两个方法获取到的变量来创建。getAppBundlePath获取到的是Dart文件的资源路径,getDartEntrypointFunctionName取到的是Dart文件运行的主方法,默认的方法名就是main.dart的main方法。
3.1 executeDartEntrypoint
//DartExecutor.java
public void executeDartEntrypoint(@NonNull DartExecutor.DartEntrypoint dartEntrypoint) {
if (this.isApplicationRunning) {
Log.w("DartExecutor", "Attempted to run a DartExecutor that is already running.");
} else {
Log.v("DartExecutor", "Executing Dart entrypoint: " + dartEntrypoint);
this.flutterJNI.runBundleAndSnapshotFromLibrary(dartEntrypoint.pathToBundle, dartEntrypoint.dartEntrypointFunctionName, (String)null, this.assetManager);
this.isApplicationRunning = true;
}
}
//FlutterJNI.java
@UiThread
public void runBundleAndSnapshotFromLibrary(
@NonNull String bundlePath,
@Nullable String entrypointFunctionName,
@Nullable String pathToEntrypointFunction,
@NonNull AssetManager assetManager) {
ensureRunningOnMainThread();
ensureAttachedToNative();
nativeRunBundleAndSnapshotFromLibrary(
nativePlatformViewId,
bundlePath,
entrypointFunctionName,
pathToEntrypointFunction,
assetManager);}
内部调用了FlutterJNI的runBundleAndSnapshotFromLibrary方法,该方法内部调用jni方法nativeRunBundleAndSnapshotFromLibrary,这个jni方法也是在1.3.3 注册PlatformViewAndroid的RegisterApi方法中进行注册的。
3.2 nativeRunBundleAndSnapshotFromLibrary
//shell/platform/android/platform_view_android_jni_impl.cc
static void RunBundleAndSnapshotFromLibrary(JNIEnv* env,
jobject jcaller,
jlong shell_holder,
jstring jBundlePath,
jstring jEntrypoint,
jstring jLibraryUrl,
jobject jAssetManager) {
auto asset_manager = std::make_shared<flutter::AssetManager>();
asset_manager->PushBack(std::make_unique<flutter::APKAssetProvider>(
env, // jni environment
jAssetManager, // asset manager
fml::jni::JavaStringToString(env, jBundlePath)) // apk asset dir
);
std::unique_ptr<IsolateConfiguration> isolate_configuration;
if (flutter::DartVM::IsRunningPrecompiledCode()) {
isolate_configuration = IsolateConfiguration::CreateForAppSnapshot();
} else {
std::unique_ptr<fml::Mapping> kernel_blob =
fml::FileMapping::CreateReadOnly(
ANDROID_SHELL_HOLDER->GetSettings().application_kernel_asset);
if (!kernel_blob) {
FML_DLOG(ERROR) << "Unable to load the kernel blob asset.";
return;
}
isolate_configuration =
IsolateConfiguration::CreateForKernel(std::move(kernel_blob));
}
//初始化RunConfiguration
RunConfiguration config(std::move(isolate_configuration),
std::move(asset_manager));
{
auto entrypoint = fml::jni::JavaStringToString(env, jEntrypoint);
auto libraryUrl = fml::jni::JavaStringToString(env, jLibraryUrl);
if ((entrypoint.size() > 0) && (libraryUrl.size() > 0)) {
config.SetEntrypointAndLibrary(std::move(entrypoint),
std::move(libraryUrl));
} else if (entrypoint.size() > 0) {
config.SetEntrypoint(std::move(entrypoint));
}
}
ANDROID_SHELL_HOLDER->Launch(std::move(config));
}
该方法为引擎启动创建一个RunConfiguration对象并通过ANDROID_SHELL_HOLDER的Launch进一步处理。
//shell/platform/android/android_shell_holder.cc
void AndroidShellHolder::Launch(RunConfiguration config) {
if (!IsValid()) {
return;
}
shell_->RunEngine(std::move(config));
}
这里可以看到通过Shell启动引擎
3.3 RunEngine
// shell/common/shell.cc
void Shell::RunEngine(
RunConfiguration run_configuration,
const std::function<void(Engine::RunStatus)>& result_callback) {
...
fml::TaskRunner::RunNowOrPostTask(
task_runners_.GetUITaskRunner(),
fml::MakeCopyable(
[run_configuration = std::move(run_configuration),
weak_engine = weak_engine_, result]() mutable {
if (!weak_engine) {
FML_LOG(ERROR)
<< "Could not launch engine with configuration - no engine.";
result(Engine::RunStatus::Failure);
return;
}
//启动引擎
auto run_result = weak_engine->Run(std::move(run_configuration));
if (run_result == flutter::Engine::RunStatus::Failure) {
FML_LOG(ERROR) << "Could not launch engine with configuration.";
}
result(run_result);
}));
}
在RunEngine内部通过Engine的Run方法进一步处理
// shell/common/engine.cc
Engine::RunStatus Engine::Run(RunConfiguration configuration) {
//获取到配置的EntryPoint
last_entry_point_ = configuration.GetEntrypoint();
last_entry_point_library_ = configuration.GetEntrypointLibrary();
//准备和加载isolate
auto isolate_launch_status =
PrepareAndLaunchIsolate(std::move(configuration));
...
}
3.4 PrepareAndLaunchIsolate
//shell/common/engine.cc
Engine::RunStatus Engine::PrepareAndLaunchIsolate(
RunConfiguration configuration) {
auto isolate_configuration = configuration.TakeIsolateConfiguration();
std::shared_ptr<DartIsolate> isolate =
runtime_controller_->GetRootIsolate().lock();
...
//准备isolate
if (!isolate_configuration->PrepareIsolate(*isolate)) {
FML_LOG(ERROR) << "Could not prepare to run the isolate.";
return RunStatus::Failure;
}
...
//通过DartIsolate的run方法启动
if (!isolate->Run(configuration.GetEntrypoint(),
settings_.dart_entrypoint_args)) {
FML_LOG(ERROR) << "Could not run the isolate.";
return RunStatus::Failure;
}
...
return RunStatus::Success;
}
// runtime/dart_isolate.cc
[[nodiscard]] bool DartIsolate::Run(const std::string& entrypoint_name,
const std::vector<std::string>& args,
const fml::closure& on_run) {
TRACE_EVENT0("flutter", "DartIsolate::Run");
if (phase_ != Phase::Ready) {
return false;
}
tonic::DartState::Scope scope(this);
auto user_entrypoint_function =
Dart_GetField(Dart_RootLibrary(), tonic::ToDart(entrypoint_name.c_str()));
auto entrypoint_args = tonic::ToDart(args);
//调用main方法
if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
return false;
}
phase_ = Phase::Running;
if (on_run) {
on_run();
}
return true;
}
这里的entrypoint_name就是主方法名称“main”。该方法中获取到主方法名称对应的入口函数,也即是main方法。随后通过InvokeMainEntrypoint调用主方法。
3.5 调用main方法
// runtime/dart_isolate.cc
[[nodiscard]] static bool InvokeMainEntrypoint(
Dart_Handle user_entrypoint_function,
Dart_Handle args) {
...
Dart_Handle start_main_isolate_function =
tonic::DartInvokeField(Dart_LookupLibrary(tonic::ToDart("dart:isolate")),
"_getStartMainIsolateFunction", {});
...
if (tonic::LogIfError(tonic::DartInvokeField(
Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMainZoned",
{start_main_isolate_function, user_entrypoint_function, args}))) {
FML_LOG(ERROR) << "Could not invoke the main entrypoint.";
return false;
}
return true;
}
这里最终通过调用的Dart虚拟机的_runMainZoned()方法启动执行main方法。
//lib/ui/hooks.dart
@pragma('vm:entry-point')
// ignore: unused_element
void _runMainZoned(Function startMainIsolateFunction,
Function userMainFunction,
List<String> args) {
startMainIsolateFunction((){
runZonedGuarded<void>(() {
if (userMainFunction is _BinaryFunction) {
// This seems to be undocumented but supported by the command line VM.
// Let's do the same in case old entry-points are ported to Flutter.
(userMainFunction as dynamic)(args, '');
} else if (userMainFunction is _UnaryFunction) {
(userMainFunction as dynamic)(args);
} else {
userMainFunction();
}
}, (Object error, StackTrace stackTrace) {
_reportUnhandledException(error.toString(), stackTrace.toString());
});
}, null);
}
这里的userMainFunction等于main.dart文件中的main()方法。