This page looks best with JavaScript enabled

Flutter 在 Android 上是如何运行起来的

 ·  ☕ 11 min read

Flutter 应用运行的本质还是原生应用的运行。那么在 Android 上, Flutter 框架是如何运行起来的呢?

整体流程

本文基于 Flutter v1.10.5 版本源码

先回想下编写一个纯 Flutter 应用的场景:

  1. 创建项目, flutter create 命令会生成 IOS, Android, Dart 三个项目结构
  2. 在 Dart 项目目录的 lib 文件夹下编写 Dart 代码
  3. 执行 flutter run 在 IOS 或 Android 上运行应用

这套流程下了,感觉完全不用接触 IOS 和 Android 的原生开发了。但是, 我们知道 Flutter 其实只是一个 UI 框架, 它是基于 IOS 和 Android 已有的机制运行的。所以 Flutter 应用运行的本质还是原生应用的运行。那么在 Android 上, Flutter 框架是如何运行起来的呢。

Android 应用的启动

首先, 简单来说. Android 应用的启动可以在 AndroidManifest 中配置, 启动使用的 Application 类(可不单独配置)和启动之后打开的第一个 Activity. 这个规则外部应该是不能干涉的. 所以, Flutter 应用首先肯定会打开一个 Activity, 可能会使用自己单独的 Application 类.

flutter create

看下使用 flutter create 命令生成的项目中的 Android 部分:

android
├── app
│   ├── build.gradle
│   └── src
│       └── main
│           ├── AndroidManifest.xml
│           ├── java
│           │   └── io
│           │       ├── flutter
│           │       │   └── plugins
│           │       │       └── GeneratedPluginRegistrant.java
│           │       └── github
│           │           └── stefanji
│           │               └── fluttergitlab
│           │                   └── MainActivity.java

创建了一个 Activity: MainActivity.java.

再看下 AndroidManifest 文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="io.github.stefanji.fluttergitlab">
    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

不出所料, 应用启动之后, 首先会打开 MainActivity. 而且 manifest 里还单独声明了一个 Application 类: FlutterApplication. 这就说明, 应用启动的将会是这个类.

再看下 flutter build apk --debug 生成的 apk 文件:

├── assets
│   └── flutter_assets
│       ├── AssetManifest.json
│       ├── FontManifest.json
│       ├── LICENSE
│       ├── fonts
│       ├── isolate_snapshot_data
│       ├── kernel_blob.bin
│       ├── packages
│       └── vm_snapshot_data
├── classes.dex
├── lib
│   ├── arm64-v8a
│   │   └── libflutter.so
│   ├── armeabi-v7a
│   │   └── libflutter.so
│   ├── x86
│   │   └── libflutter.so
│   └── x86_64
│       └── libflutter.so

再对比下 flutter build apk --release 生成的:

├── assets
│   └── flutter_assets
│       ├── AssetManifest.json
│       ├── FontManifest.json
│       ├── LICENSE
│       ├── fonts
│       └── packages
├── classes.dex
├── lib
│   ├── arm64-v8a
│   │   ├── libapp.so
│   │   └── libflutter.so
│   └── armeabi-v7a
│       ├── libapp.so
│       └── libflutter.so

对比 release 打包和 debug 打包能发现, bebug 模式下 assets/flutter_assets 目录里会多出 isolate_snapshot_data kernel_blob.bin vm_snapshot_data 三个文件, 而 release 模式下打包则在 lib 目录下多出一个 libapp.so 动态链接库. 这些文件的区别, 现在还没清楚, 后面可能会遇到.

看了文件结构和打包的差异之后, 先从应用启动开始梳理.

应用启动

io.flutter.app.FlutterApplication

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class FlutterApplication extends Application {
    @Override
    @CallSuper
    public void onCreate() {
        super.onCreate();
        FlutterMain.startInitialization(this);
    }

    private Activity mCurrentActivity = null;
    public Activity getCurrentActivity() {
        return mCurrentActivity;
    }
    public void setCurrentActivity(Activity mCurrentActivity) {
        this.mCurrentActivity = mCurrentActivity;
    }
}

没有特别多的代码, 但是有一行代码(FlutterMain.startInitialization), 应该和 Flutter 框架的初始化有关.

Flutter 框架初始化

io.flutter.view.FlutterMain#startInitialization(android.content.Context, io.flutter.view.FlutterMain.Settings)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static void startInitialization(@NonNull Context applicationContext, @NonNull Settings settings) {
    if (Looper.myLooper() != Looper.getMainLooper()) {
      throw new IllegalStateException("startInitialization must be called on the main thread");
    }
    // Do not run startInitialization more than once.
    if (sSettings != null) {
      return;
    }
    sSettings = settings;
    long initStartTimestampMillis = SystemClock.uptimeMillis();
    initConfig(applicationContext);
    initResources(applicationContext);
    // 加载 libflutter.so
    System.loadLibrary("flutter");
    VsyncWaiter
        .getInstance((WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE))
        .init();
    // We record the initialization time using SystemClock because at the start of the
    // initialization we have not yet loaded the native library to call into dart_tools_api.h.
    // To get Timeline timestamp of the start of initialization we simply subtract the delta
    // from the Timeline timestamp at the current moment (the assumption is that the overhead
    // of the JNI call is negligible).
    long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis;
    FlutterJNI.nativeRecordStartTimestamp(initTimeMillis);
}

initConfig

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
private static void initConfig(@NonNull Context applicationContext) {
    Bundle metadata = getApplicationInfo(applicationContext).metaData;
    if (metadata == null) {
        return;
    }
    // 读取一些文件名配置, 其对应的默认值就是上面打包的文件名
    //libapp.so
    sAotSharedLibraryName = metadata.getString(PUBLIC_AOT_SHARED_LIBRARY_NAME, DEFAULT_AOT_SHARED_LIBRARY_NAME);
    //flutter_assets
    sFlutterAssetsDir = metadata.getString(PUBLIC_FLUTTER_ASSETS_DIR_KEY, DEFAULT_FLUTTER_ASSETS_DIR);
    //vm_snapshot_data
    sVmSnapshotData = metadata.getString(PUBLIC_VM_SNAPSHOT_DATA_KEY, DEFAULT_VM_SNAPSHOT_DATA);
    //isolate_snapshot_data
    sIsolateSnapshotData = metadata.getString(PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY, DEFAULT_ISOLATE_SNAPSHOT_DATA); 
}

initResources

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
private static void initResources(@NonNull Context applicationContext) {
    new ResourceCleaner(applicationContext).start();
    // 如果是 Debug 模式则把下面的文件从 assets/flutter_assets 目录中拷到 /data/data/packageName/app_flutter 目录中
    if (BuildConfig.DEBUG) {
        final String dataDirPath = PathUtils.getDataDirectory(applicationContext);
        final String packageName = applicationContext.getPackageName();
        final PackageManager packageManager = applicationContext.getPackageManager();
        final AssetManager assetManager = applicationContext.getResources().getAssets();
        sResourceExtractor = new ResourceExtractor(dataDirPath, packageName, packageManager, assetManager);
        // 拷贝的刚好是 debug 模式下打包多出的 3 个文件
        sResourceExtractor
            .addResource(fromFlutterAssets(sVmSnapshotData))
            .addResource(fromFlutterAssets(sIsolateSnapshotData))
            .addResource(fromFlutterAssets(DEFAULT_KERNEL_BLOB));
        sResourceExtractor.start();
    }
}

libflutter.so 被加载时会运行的源码 shell/platform/android/library_loader.cc

其在 JNI_OnLoad 中做了两件事:

  1. FlutterJNI 类注册 JNI 方法签名
  2. 把 cpp 代码要用到的 Java 方法, 在 FlutterJNI 类里找到 jmethodID, 并用 static 变量存起来
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// This is called by the VM when the shared library is first loaded.
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
  // Initialize the Java VM.
  fml::jni::InitJavaVM(vm);

  JNIEnv* env = fml::jni::AttachCurrentThread();
  bool result = false;

  // Register FlutterMain.
  result = flutter::FlutterMain::Register(env);
  FML_CHECK(result);

  // Register PlatformView
  result = flutter::PlatformViewAndroid::Register(env);
  FML_CHECK(result);

  // Register VSyncWaiter.
  result = flutter::VsyncWaiterAndroid::Register(env);
  FML_CHECK(result);

  return JNI_VERSION_1_4;
}

FlutterMain::Register 方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
bool FlutterMain::Register(JNIEnv* env) {
  // 注册了两个方法:
  // void nativeInit(Context, String, String, String, String)
  // void nativeRecordStartTimestamp(long)
  static const JNINativeMethod methods[] = {
      {
          .name = "nativeInit",
          .signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
                       "lang/String;Ljava/lang/String;Ljava/lang/String;)V",
          .fnPtr = reinterpret_cast<void*>(&Init),
      },
      {
          .name = "nativeRecordStartTimestamp",
          .signature = "(J)V",
          .fnPtr = reinterpret_cast<void*>(&RecordStartTimestamp),
      },
  };

  jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");

  if (clazz == nullptr) {
    return false;
  }

  return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0;
}

PlatformViewAndroid::RegisterVsyncWaiterAndroid::Register 与上面类似.

回到 startInitialization 的 VsyncWaiter init

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class VsyncWaiter {
    private static VsyncWaiter instance;
    @NonNull
    private final WindowManager windowManager;

    public void init() {
        // 把 this.asyncWaitForVsyncDelegate 存到 FlutterJNI 的 static 变量 asyncWaitForVsyncDelegate 中
        // 当 FlutterJNI 的 asyncWaitForVsync 方法被 native 层调用时就会回调 asyncWaitForVsyncDelegate 的 asyncWaitForVsync 方法
        // asyncWaitForVsync 方法执行时会 post 一个在下一个 Vsync 信号来时的回调到 Choreographer
        FlutterJNI.setAsyncWaitForVsyncDelegate(this.asyncWaitForVsyncDelegate);
        float fps = this.windowManager.getDefaultDisplay().getRefreshRate();
        FlutterJNI.setRefreshRateFPS(fps);
    }
    
    private final AsyncWaitForVsyncDelegate asyncWaitForVsyncDelegate = new AsyncWaitForVsyncDelegate() {
        public void asyncWaitForVsync(final long cookie) {
            Choreographer.getInstance().postFrameCallback(new FrameCallback() {
                // doFrame 将在下一个 Vsync 信号来时被调用
                public void doFrame(long frameTimeNanos) {
                    float fps = VsyncWaiter.this.windowManager.getDefaultDisplay().getRefreshRate();
                    long refreshPeriodNanos = (long)(1.0E9D / (double)fps);
                    // 调用 shell/platform/android/vsync_waiter_android.cc#OnNativeVsync
                    FlutterJNI.nativeOnVsync(frameTimeNanos, frameTimeNanos + refreshPeriodNanos, cookie);
                }
            });
        }
    };

    @NonNull
    public static VsyncWaiter getInstance(@NonNull WindowManager windowManager) {
        if (instance == null) {
            instance = new VsyncWaiter(windowManager);
        }
        return instance;
    }

    private VsyncWaiter(@NonNull WindowManager windowManager) {
        this.windowManager = windowManager;
    }
}

至此, FlutterApplication onCreate 执行完毕, 主要做了:

  1. 加载 libflutter.so
  2. 如果是 debug 模式, 一些资源文件会被写到外部
  3. 注册了 Vsync 监听.

MainActivity 启动

接着看下 MainActivity 的代码:

1
2
3
4
5
6
7
8
public class MainActivity extends FlutterActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 一些自己创建的 plugin 的注册
    GeneratedPluginRegistrant.registerWith(this);
  }
}

没有特殊逻辑, 但是也没有 Android 开发中常见的 setContentView. 进入父类 FlutterActivity 看下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class FlutterActivity extends Activity implements Provider, PluginRegistry, ViewFactory {
    private static final String TAG = "FlutterActivity";
    // 创建 FlutterActivityDelegate 对象
    private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this);
    private final FlutterActivityEvents eventDelegate;
    private final Provider viewProvider;
    private final PluginRegistry pluginRegistry;

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

    public FlutterView getFlutterView() {
        return this.viewProvider.getFlutterView();
    }

    public FlutterView createFlutterView(Context context) {
        return null;
    }

    public FlutterNativeView createFlutterNativeView() {
        return null;
    }

    public boolean retainFlutterNativeView() {
        return false;
    }

    //...

    public final Registrar registrarFor(String pluginKey) {
        return this.pluginRegistry.registrarFor(pluginKey);
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.eventDelegate.onCreate(savedInstanceState);
    }

    protected void onStart() {
        super.onStart();
        this.eventDelegate.onStart();
    }

    public void onBackPressed() {
        if (!this.eventDelegate.onBackPressed()) {
            super.onBackPressed();
        }
    }

    protected void onPostResume() {
        super.onPostResume();
        this.eventDelegate.onPostResume();
    }
    //... 省略其他几个回调
}

FlutterActivity 继承了 Android 原生的 Activity, 实现了 3 个接口 Provider PluginRegistry ViewFactory.

  • Activity 的生命周期回调都代理给 FlutterActivityDelegate 处理
  • 涉及 FlutterView 的, 则交给 viewProvider 处理
  • 涉及 Plugin 的, 交给 pluginRegistry 处理

onCreate

既然 onCreate 交给了 FlutterActivityDelegate 处理, 就看下这个 onCreate 里做了什么:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public void onCreate(Bundle savedInstanceState) {
    //...

    String[] args = getArgsFromIntent(this.activity.getIntent());

    FlutterMain.ensureInitializationComplete(this.activity.getApplicationContext(), args);
    // viewFactory 即是 FlutterActivity, FlutterActivity 中 createFlutterView 返回的是 null
    this.flutterView = this.viewFactory.createFlutterView(this.activity);
    if (this.flutterView == null) {
        // FlutterActivity 中 createFlutterNativeView 返回的是 null
        FlutterNativeView nativeView = this.viewFactory.createFlutterNativeView();
        // 构造一个 FlutterView
        this.flutterView = new FlutterView(this.activity, (AttributeSet)null, nativeView);
        // matchParent: 一个静态 LayoutParams 变量, 宽高都 MATCH_PARENT
        this.flutterView.setLayoutParams(matchParent);
        // 熟悉的味道: 调用 FlutterActivity 的 setContentView, 将 FlutterView 添加到 Activity 的 ANDROID_CONTENT 布局里
        this.activity.setContentView(this.flutterView);
        // 创建闪屏
        this.launchView = this.createLaunchView();
        if (this.launchView != null) {
            // 将闪屏添加到布局最上层, 闪屏结束之后, 会 remove launchView. 具体见 addLaunchView()
            this.addLaunchView();
        }
    }
    //...
}

通过 FlutterActivityDelegateonCreate, 看到了 FlutterActivity 是怎样显示出来的, 以及闪屏是怎样添加的. 但是还没有看到 Flutter 框架是怎么开始运行的.

ensureInitializationComplete

注意在 setContentView 之前, 有个调用 FlutterMain.ensureInitializationComplete, 貌似与 Flutter 的初始化有关.

io.flutter.view.FlutterMain#ensureInitializationComplete

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public static void ensureInitializationComplete(@NonNull Context applicationContext, @Nullable String[] args) {
    if (!isRunningInRobolectricTest) {
        //...
        } else if (!sInitialized) {
            // sInitialized 初始值是 false, 开始肯定走到这里
            try {
                // 添加一些参数
                List<String> shellArgs = new ArrayList<>();
                shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat");

                ApplicationInfo applicationInfo = getApplicationInfo(applicationContext);
                // libflutter.so
                shellArgs.add("--icu-native-lib-path=" + applicationInfo.nativeLibraryDir + File.separator + DEFAULT_LIBRARY);

                if (args != null) {
                    Collections.addAll(shellArgs, args);
                }

                String kernelPath = null;
                if (BuildConfig.DEBUG) {
                    // DEBUG 下把多出的 3 个文件也添加
                    String snapshotAssetPath = PathUtils.getDataDirectory(applicationContext) + File.separator + sFlutterAssetsDir;
                    kernelPath = snapshotAssetPath + File.separator + DEFAULT_KERNEL_BLOB;
                    shellArgs.add("--" + SNAPSHOT_ASSET_PATH_KEY + "=" + snapshotAssetPath);
                    shellArgs.add("--" + VM_SNAPSHOT_DATA_KEY + "=" + sVmSnapshotData);
                    shellArgs.add("--" + ISOLATE_SNAPSHOT_DATA_KEY + "=" + sIsolateSnapshotData);
                } else {
                    // Relase 下则把 libapp.so 添加
                    shellArgs.add("--" + AOT_SHARED_LIBRARY_NAME + "=" + sAotSharedLibraryName);

                    // Most devices can load the AOT shared library based on the library name
                    // with no directory path.  Provide a fully qualified path to the library
                    // as a workaround for devices where that fails.
                    shellArgs.add("--" + AOT_SHARED_LIBRARY_NAME + "=" + applicationInfo.nativeLibraryDir + File.separator + sAotSharedLibraryName);
                }

                shellArgs.add("--cache-dir-path=" + PathUtils.getCacheDirectory(applicationContext));
                if (sSettings.getLogTag() != null) {
                    shellArgs.add("--log-tag=" + sSettings.getLogTag());
                }
                // 调用 FlutterJNI nativeInit
                FlutterJNI.nativeInit(applicationContext, (String[])shellArgs.toArray(new String[0]), kernelPath, appStoragePath, engineCachesPath);
                sInitialized = true;
            } catch (Exception var7) {
                Log.e("FlutterMain", "Flutter initialization failed.", var7);
                throw new RuntimeException(var7);
            }
        }
    }
}

FlutterJNI.nativeInit 对应的 native 方法为 FlutterMain::Init:

shell/platform/android/flutter_main.cc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void FlutterMain::Init(JNIEnv* env,
                       jclass clazz,
                       jobject context,
                       jobjectArray jargs,
                       jstring kernelPath,
                       jstring appStoragePath,
                       jstring engineCachesPath) {
  std::vector<std::string> args;
  args.push_back("flutter");
  for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
    args.push_back(std::move(arg));
  }
  auto command_line = fml::CommandLineFromIterators(args.begin(), args.end());
  // 根据传递的 args 创建 Settings 对象
  auto settings = SettingsFromCommandLine(command_line);

  flutter::DartCallbackCache::SetCachePath(fml::jni::JavaStringToString(env, appStoragePath));
  fml::paths::InitializeAndroidCachesPath(fml::jni::JavaStringToString(env, engineCachesPath));
  flutter::DartCallbackCache::LoadCacheFromDisk();

  if (!flutter::DartVM::IsRunningPrecompiledCode() && kernelPath) {
    auto application_kernel_path =
        fml::jni::JavaStringToString(env, kernelPath);

    if (fml::IsFile(application_kernel_path)) {
      settings.application_kernel_asset = application_kernel_path;
    }
  }

  // 创建一个新的 FlutterMain 对象, 赋给 g_flutter_main 这个全局对象
  g_flutter_main.reset(new FlutterMain(std::move(settings)));
  // 调用 FlutterMain 的 SetupObservatoryUriCallback 方法
  g_flutter_main->SetupObservatoryUriCallback(env);
}

FlutterMain 的构造函数, 使用初始化列表方式

1
2
FlutterMain::FlutterMain(flutter::Settings settings)
    : settings_(std::move(settings)), observatory_uri_callback_() {}

SetupObservatoryUriCallback

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void FlutterMain::SetupObservatoryUriCallback(JNIEnv* env) {
  g_flutter_jni_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
      env, env->FindClass("io/flutter/embedding/engine/FlutterJNI"));
  if (g_flutter_jni_class->is_null()) {
    return;
  }
  jfieldID uri_field = env->GetStaticFieldID(
      g_flutter_jni_class->obj(), "observatoryUri", "Ljava/lang/String;");
  if (uri_field == nullptr) {
    return;
  }

  auto set_uri = [env, uri_field](std::string uri) {
    fml::jni::ScopedJavaLocalRef<jstring> java_uri =
        fml::jni::StringToJavaString(env, uri);
    env->SetStaticObjectField(g_flutter_jni_class->obj(), uri_field,
                              java_uri.obj());
  };

  fml::MessageLoop::EnsureInitializedForCurrentThread();
  fml::RefPtr<fml::TaskRunner> platform_runner =
      fml::MessageLoop::GetCurrent().GetTaskRunner();

  // 为 observatory_uri_callback_ 赋值
  observatory_uri_callback_ = DartServiceIsolate::AddServerStatusCallback(
      [platform_runner, set_uri](std::string uri) {
        platform_runner->PostTask([uri, set_uri] { set_uri(uri); });
      });
}

至此, ensureInitializationComplete 流程结束, 只是为全局指针 g_flutter_main 赋了一个 FlutterMain 对象, 还没发现与 Flutter 或 Dart 运行相关的流程. 所以, 回到 onCreate 中, 进入 FlutterView 看下.

FlutterView

由上文可知, FlutterView 是在 FlutterActivity onCreate 时创建的, FlutterView 的构造函数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public FlutterView(Context context, AttributeSet attrs, FlutterNativeView nativeView) {
    super(context, attrs);
    Activity activity = getActivity(getContext());
    if (activity == null) {
        throw new IllegalArgumentException("Bad context");
    }
    if (nativeView == null) {
        // FlutterActivity 默认传递的 null
        mNativeView = new FlutterNativeView(activity.getApplicationContext());
    } else {
        mNativeView = nativeView;
    }
    // 从 FlutterNativeView 中获取 DartExecutor
    // 暂且把 DartExecutor 看做 Dart 的执行器 ?
    dartExecutor = mNativeView.getDartExecutor();
    // 创建 FlutterRenderer
    flutterRenderer = new FlutterRenderer(mNativeView.getFlutterJNI());
    mIsSoftwareRenderingEnabled = mNativeView.getFlutterJNI().nativeGetIsSoftwareRenderingEnabled();
    mMetrics = new ViewportMetrics();
    mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density;
    setFocusable(true);
    setFocusableInTouchMode(true);
    mNativeView.attachViewAndActivity(this, activity);
    mSurfaceCallback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            assertAttached();
            // 调到 platform_view_anroid_jni.cc#SurfaceCreated
            mNativeView.getFlutterJNI().onSurfaceCreated(holder.getSurface());
        }
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            assertAttached();
            // 调到 platform_view_anroid_jni.cc#SurfaceChanged
            mNativeView.getFlutterJNI().onSurfaceChanged(width, height);
        }
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            assertAttached();
            // 调到 platform_view_anroid_jni.cc#SurfaceDestroyed
            mNativeView.getFlutterJNI().onSurfaceDestroyed();
        }
    };
    // FlutterView 继承了 SurfaceView, 所以有 SurfaceHolder, 注册 mSurfaceCallback
    getHolder().addCallback(mSurfaceCallback);
    mActivityLifecycleListeners = new ArrayList<>();
    mFirstFrameListeners = new ArrayList<>();
    // Create all platform channels
    navigationChannel = new NavigationChannel(dartExecutor);
    keyEventChannel = new KeyEventChannel(dartExecutor);
    lifecycleChannel = new LifecycleChannel(dartExecutor);
    localizationChannel = new LocalizationChannel(dartExecutor);
    platformChannel = new PlatformChannel(dartExecutor);
    systemChannel = new SystemChannel(dartExecutor);
    settingsChannel = new SettingsChannel(dartExecutor);
    // Create and setup plugins
    PlatformPlugin platformPlugin = new PlatformPlugin(activity, platformChannel);
    addActivityLifecycleListener(new ActivityLifecycleListener() {
        @Override
        public void onPostResume() {
            platformPlugin.updateSystemUiOverlays();
        }
    });
    mImm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    PlatformViewsController platformViewsController = mNativeView.getPluginRegistry().getPlatformViewsController();
    // 以下几位顾名思义一下?
    mTextInputPlugin = new TextInputPlugin(this, dartExecutor, platformViewsController);
    androidKeyProcessor = new AndroidKeyProcessor(keyEventChannel, mTextInputPlugin);
    androidTouchProcessor = new AndroidTouchProcessor(flutterRenderer);
    mNativeView.getPluginRegistry().getPlatformViewsController().attachTextInputPlugin(mTextInputPlugin);

    // Send initial platform information to Dart
    sendLocalesToDart(getResources().getConfiguration());
    sendUserPlatformSettingsToDart();
}

可见在 FlutterView 创建时进行了许多工作, 其中 FlutterNativeView 负责了许多, 而且在这里终于见到 Dart 的影子了.

FlutterNativeView

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Flutter UI Display 回调
private final FlutterUiDisplayListener flutterUiDisplayListener = new FlutterUiDisplayListener() {
     @Override
     public void onFlutterUiDisplayed() {
         if (mFlutterView == null) {
             return;
         }
         mFlutterView.onFirstFrame();
     }

     @Override
     public void onFlutterUiNoLongerDisplayed() {
         // no-op
     }
};

public FlutterNativeView(@NonNull Context context, boolean isBackgroundView) {
    mContext = context;
    mPluginRegistry = new FlutterPluginRegistry(this, context);
    mFlutterJNI = new FlutterJNI();
    // 将 flutterUiDisplayListener 添加到 FlutterJNI 的 flutterUiDisplayListeners 中, native 会在 Flutter 第一帧渲染时回调
    mFlutterJNI.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);
    this.dartExecutor = new DartExecutor(mFlutterJNI, context.getAssets());
    // FlutterJNI 中的 EngineLifecycleListener 会被 native 在 FlutterEngine 重启时回调
    mFlutterJNI.addEngineLifecycleListener(new EngineLifecycleListenerImpl());
    attach(this, isBackgroundView);
    assertAttached();
}

private void attach(FlutterNativeView view, boolean isBackgroundView) {
    // 调用 platform_view_anroid_jni.cc#AttachJNI
    mFlutterJNI.attachToNative(isBackgroundView);
    // 注册 platform message handler 到 Dart 的执行上下文中
    dartExecutor.onAttachedToJNI();
}

AttachJNI

platform_view_anroid_jni.cc#AttachJNI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
static jlong AttachJNI(JNIEnv* env, jclass clazz, jobject flutterJNI, jboolean is_background_view) {
  // 为 flutterJNI 对象创建一个 WeakGlobalRef
  fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
  // 构造一个 AndroidShellHolder 对象, 由 FlutterView.java 构造 FlutterNativeView 可知, is_background_view 为 false
  auto shell_holder = std::make_unique<AndroidShellHolder>(FlutterMain::Get().GetSettings(), java_object, is_background_view);
  if (shell_holder->IsValid()) {
    return reinterpret_cast<jlong>(shell_holder.release());
  } else {
    return 0;
  }
}

shell/platform/android/android_shell_holder.cc#AndroidShellHolder

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
AndroidShellHolder::AndroidShellHolder(
    flutter::Settings settings,
    fml::jni::JavaObjectWeakGlobalRef java_object,
    bool is_background_view)
    : settings_(std::move(settings)), java_object_(java_object) {
  static size_t shell_count = 1;
  auto thread_label = std::to_string(shell_count++);
  // 调用 pthread_key_create 创建一个线程本地变量, 当线程释放是会调用 ThreadDestructCallback
  // FML_CHECK 是一个工具方法, 当传递的 condition 为 false 时会打印日志
  FML_CHECK(pthread_key_create(&thread_destruct_key_, ThreadDestructCallback) == 0);

  if (is_background_view) {
  } else {
    // 创建 UI,GPU,IO 线程
    // thread_label.ui thread_label.gpu thread_label.io
    thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU | ThreadHost::Type::IO};
  }

  // Detach from JNI when the UI and GPU threads exit.
  // 创建一个 closure, 执行时把 thread_destruct_key_ 存储的值设为 void
  auto jni_exit_task([key = thread_destruct_key_]() {
    FML_CHECK(pthread_setspecific(key, reinterpret_cast<void*>(1)) == 0);
  });
  thread_host_.ui_thread->GetTaskRunner()->PostTask(jni_exit_task);
  if (!is_background_view) {
    thread_host_.gpu_thread->GetTaskRunner()->PostTask(jni_exit_task);
  }

  // WeakPtr 的空构造函数相当于赋值 nullptr
  fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
  // on_create_platform_view 回调
  Shell::CreateCallback<PlatformView> on_create_platform_view =
      [is_background_view, java_object, &weak_platform_view](Shell& shell) {
        std::unique_ptr<PlatformViewAndroid> platform_view_android;
        if (is_background_view) {
        } else {
          // 构造一个 PlatformViewAndroid
          platform_view_android = std::make_unique<PlatformViewAndroid>(
              shell,                   // delegate
              shell.GetTaskRunners(),  // task runners
              java_object,             // java object handle for JNI interop
              shell.GetSettings()
                  .enable_software_rendering  // use software rendering
          );
        }
        // 赋给 weak_platform_view
        weak_platform_view = platform_view_android->GetWeakPtr();
        return platform_view_android;
      };

  Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
    return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
  };

  // The current thread will be used as the platform thread. Ensure that the message loop is initialized.
  // 确保当前线程的 MessageLoop 已经创建
  fml::MessageLoop::EnsureInitializedForCurrentThread();
  fml::RefPtr<fml::TaskRunner> gpu_runner;
  fml::RefPtr<fml::TaskRunner> ui_runner;
  fml::RefPtr<fml::TaskRunner> io_runner;
  fml::RefPtr<fml::TaskRunner> platform_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();
  if (is_background_view) {
  } else {
    // 获取每个线程的 TaskRunner, 通过 TaskRunner 可以传递 task 到线程的 MessageLoop 中
    gpu_runner = thread_host_.gpu_thread->GetTaskRunner();
    ui_runner = thread_host_.ui_thread->GetTaskRunner();
    io_runner = thread_host_.io_thread->GetTaskRunner();
  }
  flutter::TaskRunners task_runners(thread_label,     // label
                                    platform_runner,  // platform
                                    gpu_runner,       // gpu
                                    ui_runner,        // ui
                                    io_runner         // io
  );
  // 创建 Shell
  shell_ = Shell::Create(task_runners,             // task runners
                    settings_,                // settings
                    on_create_platform_view,  // platform view create callback
                    on_create_rasterizer      // rasterizer create callback
      );

  platform_view_ = weak_platform_view;
  FML_DCHECK(platform_view_);

  is_valid_ = shell_ != nullptr;

  if (is_valid_) {
    task_runners.GetGPUTaskRunner()->PostTask([]() {
      // Android describes -8 as "most important display threads, for
      // compositing the screen and retrieving input events". Conservatively
      // set the GPU thread to slightly lower priority than it.
      if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
        // Defensive fallback. Depending on the OEM, it may not be possible
        // to set priority to -5.
        if (::setpriority(PRIO_PROCESS, gettid(), -2) != 0) {
          FML_LOG(ERROR) << "Failed to set GPU task runner priority";
        }
      }
    });
    task_runners.GetUITaskRunner()->PostTask([]() {
      if (::setpriority(PRIO_PROCESS, gettid(), -1) != 0) {
        FML_LOG(ERROR) << "Failed to set UI task runner priority";
      }
    });
  }
}

ThreadHost

engine 使用到的所有线程的集合, 从中能看出 engine 一共使用了 4 个线程.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
struct ThreadHost {
  enum Type {
    Platform = 1 << 0,
    UI = 1 << 1,
    GPU = 1 << 2,
    IO = 1 << 3,
  };

  std::unique_ptr<fml::Thread> platform_thread;
  std::unique_ptr<fml::Thread> ui_thread;
  std::unique_ptr<fml::Thread> gpu_thread;
  std::unique_ptr<fml::Thread> io_thread;
};

// 实现
ThreadHost::ThreadHost(std::string name_prefix, uint64_t mask) {
  if (mask & ThreadHost::Type::Platform) {
    platform_thread = std::make_unique<fml::Thread>(name_prefix + ".platform");
  }

  if (mask & ThreadHost::Type::UI) {
    ui_thread = std::make_unique<fml::Thread>(name_prefix + ".ui");
  }

  if (mask & ThreadHost::Type::GPU) {
    gpu_thread = std::make_unique<fml::Thread>(name_prefix + ".gpu");
  }

  if (mask & ThreadHost::Type::IO) {
    io_thread = std::make_unique<fml::Thread>(name_prefix + ".io");
  }
}

shell/common/shell.cc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
std::unique_ptr<Shell> Shell::Create(
    TaskRunners task_runners,
    Settings settings,
    Shell::CreateCallback<PlatformView> on_create_platform_view,
    Shell::CreateCallback<Rasterizer> on_create_rasterizer) {

  // 创建 DartVM
  auto vm = DartVMRef::Create(settings);
  auto vm_data = vm->GetVMData();

  return Shell::Create(std::move(task_runners),             //
                       std::move(settings),                 //
                       vm_data->GetIsolateSnapshot(),       // isolate snapshot
                       DartSnapshot::Empty(),               // shared snapshot
                       std::move(on_create_platform_view),  //
                       std::move(on_create_rasterizer),     //
                       std::move(vm)                        //
  );
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
std::unique_ptr<Shell> Shell::Create(
    TaskRunners task_runners,
    Settings settings,
    fml::RefPtr<const DartSnapshot> isolate_snapshot,
    fml::RefPtr<const DartSnapshot> shared_snapshot,
    Shell::CreateCallback<PlatformView> on_create_platform_view,
    Shell::CreateCallback<Rasterizer> on_create_rasterizer,
    DartVMRef vm) {

  if (!task_runners.IsValid() || !on_create_platform_view || !on_create_rasterizer) {
    return nullptr;
  }

  fml::AutoResetWaitableEvent latch;
  std::unique_ptr<Shell> shell;
  // 立即运行或者将 task post 到 MessageLoop 中
  fml::TaskRunner::RunNowOrPostTask(
      task_runners.GetPlatformTaskRunner(),
     { shell = CreateShellOnPlatformThread(std::move(vm),
                                            std::move(task_runners),    
                                            settings,                   
                                            std::move(isolate_snapshot),
                                            std::move(shared_snapshot), 
                                            on_create_platform_view,    
                                            on_create_rasterizer);      
        latch.Signal();
      });
  // 等待, 直到 CreateShellOnPlatformThread 完成
  latch.Wait();
  return shell;
}
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
    DartVMRef vm,
    TaskRunners task_runners,
    Settings settings,
    fml::RefPtr<const DartSnapshot> isolate_snapshot,
    fml::RefPtr<const DartSnapshot> shared_snapshot,
    Shell::CreateCallback<PlatformView> on_create_platform_view,
    Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
  if (!task_runners.IsValid()) {
    return nullptr;
  }

  auto shell = std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings));

  // 在 GPU 线程创建 光栅化器 Rasterizer
  std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
  auto rasterizer_future = rasterizer_promise.get_future();
  fml::TaskRunner::RunNowOrPostTask(
      task_runners.GetGPUTaskRunner(), [&rasterizer_promise,   //
                                        on_create_rasterizer,  //
                                        shell = shell.get()    //
  ]() {
        rasterizer_promise.set_value(on_create_rasterizer(*shell));
      });

  // 创建 PlatformViewAndroid 在 platform 线程(当前线程)
  auto platform_view = on_create_platform_view(*shell.get());
  if (!platform_view || !platform_view->GetWeakPtr()) {
    return nullptr;
  }

  // Ask the platform view for the vsync waiter. This will be used by the engine
  // to create the animator.
  auto vsync_waiter = platform_view->CreateVSyncWaiter();
  if (!vsync_waiter) {
    return nullptr;
  }

  // Create the IO manager on the IO thread. The IO manager must be initialized
  // first because it has state that the other subsystems depend on. It must
  // first be booted and the necessary references obtained to initialize the
  // other subsystems.
  std::promise<std::unique_ptr<ShellIOManager>> io_manager_promise;
  auto io_manager_future = io_manager_promise.get_future();
  std::promise<fml::WeakPtr<ShellIOManager>> weak_io_manager_promise;
  auto weak_io_manager_future = weak_io_manager_promise.get_future();
  auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();

  // TODO(gw280): The WeakPtr here asserts that we are derefing it on the
  // same thread as it was created on. We are currently on the IO thread
  // inside this lambda but we need to deref the PlatformView, which was
  // constructed on the platform thread.
  //
  // https://github.com/flutter/flutter/issues/42948
  fml::TaskRunner::RunNowOrPostTask(
      io_task_runner,
      [&io_manager_promise,                          //
       &weak_io_manager_promise,                     //
       platform_view = platform_view->GetWeakPtr(),  //
       io_task_runner                                //
  ]() {
        auto io_manager = std::make_unique<ShellIOManager>(
            platform_view.getUnsafe()->CreateResourceContext(), io_task_runner);
        weak_io_manager_promise.set_value(io_manager->GetWeakPtr());
        io_manager_promise.set_value(std::move(io_manager));
      });

  // Send dispatcher_maker to the engine constructor because shell won't have
  // platform_view set until Shell::Setup is called later.
  auto dispatcher_maker = platform_view->GetDispatcherMaker();

  // Create the engine on the UI thread.
  std::promise<std::unique_ptr<Engine>> engine_promise;
  auto engine_future = engine_promise.get_future();
  fml::TaskRunner::RunNowOrPostTask(
      shell->GetTaskRunners().GetUITaskRunner(),
      fml::MakeCopyable([&engine_promise,                                 //
                         shell = shell.get(),                             //
                         &dispatcher_maker,                               //
                         isolate_snapshot = std::move(isolate_snapshot),  //
                         shared_snapshot = std::move(shared_snapshot),    //
                         vsync_waiter = std::move(vsync_waiter),          //
                         &weak_io_manager_future                          //
  ]() mutable {
        const auto& task_runners = shell->GetTaskRunners();

        // The animator is owned by the UI thread but it gets its vsync pulses
        // from the platform.
        auto animator = std::make_unique<Animator>(*shell, task_runners,
                                                   std::move(vsync_waiter));
        // 构造 Engine 对象
        engine_promise.set_value(std::make_unique<Engine>(
            *shell,                     
            dispatcher_maker,           
            *shell->GetDartVM(),        
            std::move(isolate_snapshot),
            std::move(shared_snapshot), 
            task_runners,               
            shell->GetSettings(),       
            std::move(animator),        
            weak_io_manager_future.get()
            ));
      }));

  if (!shell->Setup(std::move(platform_view),
                    engine_future.get(),     
                    rasterizer_future.get(), 
                    io_manager_future.get()) 
  ) {
    return nullptr;
  }

  return shell;
}

shell/common/engine.cc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
runtime_controller_ = std::make_unique<RuntimeController>(
      *this,                                 // runtime delegate
      &vm,                                   // VM
      std::move(isolate_snapshot),           // isolate snapshot
      std::move(shared_snapshot),            // shared snapshot
      task_runners_,                         // task runners
      std::move(io_manager),                 // io manager
      image_decoder_.GetWeakPtr(),           // image decoder
      settings_.advisory_script_uri,         // advisory script uri 在 Setting 对象默认为 main.dart
      settings_.advisory_script_entrypoint,  // advisory script entrypoint 在 Setting 对象默认为 main 
      settings_.idle_notification_callback,  // idle notification callback
      settings_.isolate_create_callback,     // isolate create callback
      settings_.isolate_shutdown_callback,   // isolate shutdown callback
      settings_.persistent_isolate_data      // persistent isolate data
  );
Support the author with
alipay QR Code
wechat QR Code

Yang
WRITTEN BY
Yang
Developer