阅读 425

Flutter 应用启动分析 (Android视角)

文章内容基于 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在初始化过程做了以下的事情:

  1. initConfig 初始化配置信息
  2. initResources 初始化资源信息
  3. System.loadLibrary("flutter"); 加载flutter native库,注册JNI方法
  4. 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中有以下操作:

  1. initJavaVM 初始化Java虚拟机
  2. 注册FlutterMain
  3. 注册PlatformViewAndroid
  4. 注册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初始化时的主要功能。

  1. onAttach()
  2. 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的相互通信。成员里还有

  1. flutterEngine代表着Flutter的渲染引擎

  2. flutterSplashView应该是闪屏页的视图对象

  3. flutterView是FlutterActivity承载的flutter视图对象

  4. 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中,进行了以下事情:

  1. 通过setupFlutterEngine 创建Flutter引擎。
  2. 通过attachToActivity将当前FlutterActivity和flutter引擎关联上
  3. 通过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构造方法的三个参数:

  1. 从FlutterMain拿到之前初始化的Settings对象
  2. PlatformViewAndroidJNIImpl
  3. 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的构造方法主要完成以下任务:

  1. 创建ThreadHost

  2. 创建PlatformView的回调,在这里为PlatformViewAndroid

  3. 初始化当前线程,并初始化四个runner,gup/ui/io/platform,同时保证MessageLoop初始化完成

  4. 创建task runners

  5. 创建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方法主要功能:

  1. 完成Shell对象的创建

  2. 在raster线程创建rasterizer

  3. 在platform线程上创建platfomeview,通过on_create_platform_view回调创建,在2.1.2 创建AndroidShellHolder一节中我们知道创建的PlatformView实际为PlatformViewAndroid

  4. 为platform请求VsyncWaiter,引擎将用这个对象创建动画

  5. 在UI线程上创建引擎

  6. 通过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()方法。