Flutter 在Android Application 做了什么?

877 阅读2分钟

直接上代码

public class FlutterApplication extends Application {
    @Override
    @CallSuper
    public void onCreate() {
        super.onCreate();
        FlutterMain.startInitialization(this);
    }

   ...

FlutterApplicatio只调用了startInitialization

    public static void startInitialization(@NonNull Context applicationContext) {
       ...
        FlutterLoader.getInstance().startInitialization(applicationContext);
    }

FlutterLoader :主要作用是在apk中找到flutter的資源并且还加载Flutter的本机库。

 public void startInitialization(@NonNull Context applicationContext, @NonNull Settings settings) {
        ...
        initConfig(applicationContext);
        initResources(applicationContext);

        System.loadLibrary("flutter");

        VsyncWaiter
            .getInstance((WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE))
            .init();
...
    }

初始化做了三件事

  1. initConfig
  2. initResources
  3. load flutter.so

initConfig

 private void initConfig(@NonNull Context applicationContext) {

        //获取aot共享库的目录
        aotSharedLibraryName = metadata.getString(PUBLIC_AOT_SHARED_LIBRARY_NAME, DEFAULT_AOT_SHARED_LIBRARY_NAME);
        //flutter 资源目录
        flutterAssetsDir = metadata.getString(PUBLIC_FLUTTER_ASSETS_DIR_KEY, DEFAULT_FLUTTER_ASSETS_DIR);
        //虚拟机快照数据
        vmSnapshotData = metadata.getString(PUBLIC_VM_SNAPSHOT_DATA_KEY, DEFAULT_VM_SNAPSHOT_DATA);
        //isolate快照数据
        isolateSnapshotData = metadata.getString(PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY, DEFAULT_ISOLATE_SNAPSHOT_DATA);
    }

initResources

只有在测试/jit环境才会走这个

private void initResources(@NonNull Context applicationContext) {
        new ResourceCleaner(applicationContext).start();
        //如果是debug 和jit release
        if (BuildConfig.DEBUG || BuildConfig.JIT_RELEASE) {
            final String dataDirPath = PathUtils.getDataDirectory(applicationContext);
            final String packageName = applicationContext.getPackageName();
            final PackageManager packageManager = applicationContext.getPackageManager();
            final AssetManager assetManager = applicationContext.getResources().getAssets();
            resourceExtractor = new ResourceExtractor(dataDirPath, packageName, packageManager, assetManager);
        
            // 在调试/JIT模式下,这些资产将被写入磁盘,然后映射到内存,以便可以提供给DVM使用
         
            resourceExtractor
                .addResource(fullAssetPathFrom(vmSnapshotData))
                .addResource(fullAssetPathFrom(isolateSnapshotData))
                .addResource(fullAssetPathFrom(DEFAULT_KERNEL_BLOB));

            resourceExtractor.start();
        }
    }

继续找到 ResourceExtractor这个类发现里面有一个AsyncTask,他处理了这个任务

  @Override
        protected Void doInBackground(Void... unused) {
           //删除之前所有的资源
            deleteFiles(mDataDirPath, mResources);

            //解压所有pk的资源并且放到沙盒里面
            if (!extractAPK(dataDir)) {
                return null;
            }

            if (timestamp != null) {
                try {
                    new File(dataDir, timestamp).createNewFile();
                } catch (IOException e) {
                    Log.w(TAG, "Failed to write resource timestamp");
                }
            }

            return null;
        }
        
        
          @WorkerThread
        private boolean extractAPK(@NonNull File dataDir) {
            for (String asset : mResources) {
                try {
                    final String resource = "assets/" + asset;
                    final File output = new File(dataDir, asset);
                    if (output.exists()) {
                        continue;
                    }
                    if (output.getParentFile() != null) {
                        output.getParentFile().mkdirs();
                    }

                    try (InputStream is = mAssetManager.open(asset);
                        OutputStream os = new FileOutputStream(output)) {
                        copy(is, os);
                    }
                    if (BuildConfig.DEBUG) {
                        Log.i(TAG, "Extracted baseline resource " + resource);
                    }
                } catch (FileNotFoundException fnfe) {
                    continue;

                } catch (IOException ioe) {
                    Log.w(TAG, "Exception unpacking resources: " + ioe.getMessage());
                    deleteFiles(mDataDirPath, mResources);
                    return false;
                }
            }

            return true;
        }
    }

VsyncWaiter

 VsyncWaiter
         .getInstance((WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE))
         .init();
  public void init() {
     FlutterJNI.setAsyncWaitForVsyncDelegate(asyncWaitForVsyncDelegate);
     // TODO(mattcarroll): look into moving FPS reporting to a plugin
     float fps = windowManager.getDefaultDisplay().getRefreshRate();
     FlutterJNI.setRefreshRateFPS(fps);
 }

load flutter.so

加载flutter的so库

至此结束: 总结一下:FlutterApplication做什么:

  1. 初始化配置 获取meta-data数据
  2. 如果是测试模式就初始化磁盘资源到内存
  3. 把wms设置到VsyncWaiter 这一块暂时还不知道是干什么的?
  4. 加载flutter so包