FlutterFlutter

flutter 在 android 上的热更新

2018-08-18  本文已影响9396人  tangzejin921

热更新是一种需求吧。
自然会想到flutter 是否支持热更新。

然后一些群里问了问普遍反映不可以热更新,还说咸鱼的文章写了不支持热更新。
然后我表示很怀疑。

我的结论可以做到热更新

这有个apk

1.你需要把flutter 编译出来的类容放到sdcard 根目录
2.点击"加载根目录"编译生成产物
3.点击"启动"

你便可以看到效果了 (不骗你的)
其实这个apk 只做了一件事,那就是把 flutter_assets 目录里的所有内容
拷贝到 data/data/包名/app_flutter/flutter_assets目录下
比较暴力,暴力,暴力

copyDir(
        Environment.getExternalStorageDirectory().getAbsolutePath()+"/flutter_assets",
        FlutterMain.findAppBundlePath(getApplicationContext())
);

我觉得你应该了解以下类容

flutter 命令

cmd 里 执行 flutter -h 如下,这些内容可以百度

Global options:
    -h, --help            Print this usage information.
    -v, --verbose         Noisy logging, including all shell commands executed.
    -d, --device-id       Target device id or name (prefixes allowed).
        --version         Reports the version of this tool.
        --bug-report      Captures a bug report file to submit to the Flutter team (contains local paths, device
                          identifiers, and log snippets).
        --flutter-root    The root directory of the Flutter repository (uses $FLUTTER_ROOT if set).
Available commands:
    analyze        Analyze the project's Dart code.//分析项目的Dart代码。
    build          Flutter build commands.
    channel        List or switch flutter channels.//列出或切换颤振通道。
    clean          Delete the build/ directory.
    config         Configure Flutter settings.
    create         Create a new Flutter project.
    devices        List all connected devices.//列出所有连接的设备。
    doctor         Show information about the installed tooling.//显示有关已安装工具的信息。
    drive          Runs Flutter Driver tests for the current project.//运行当前项目的Flutter Driver测试。
    emulators      List and launch available emulators.//列出并启动可用的模拟器。
    format         Format one or more dart files.//格式化一个或多个dart文件。
    fuchsia_reload Hot reload on Fuchsia.//热重装。
    help           Display help information for flutter.
    install        Install a Flutter app on an attached device.
    logs           Show log output for running Flutter apps.
    packages       Commands for managing Flutter packages.
    precache       Populates the Flutter tool's cache of binary artifacts.//填充Flutter工具的二进制工件缓存。
    run            Run your Flutter app on an attached device.
    screenshot     Take a screenshot from a connected device.//从连接的设备截取屏幕截图。
    stop           Stop your Flutter app on an attached device.
    test           Run Flutter unit tests for the current project.
    trace          Start and stop tracing for a running Flutter app.//启动和停止正在运行的Flutter应用程序的跟踪。
    upgrade        Upgrade your copy of Flutter.//升级您的Flutter副本。

这些内容可以百度

其中 flutter build

    aot    Build an ahead-of-time compiled snapshot of your app's Dart code.//为应用的Dart代码构建一个提前编译的快照。
    apk    Build an Android APK file from your app.
    bundle Build the Flutter assets directory from your app.//从您的应用程序构建Flutter资产目录。
    flx    Deprecated//弃用
    ios    Build an iOS application bundle (Mac OS X host only).

更多的参数你可以参照 flutter.gradle
这个文件可以在 flutter\packages\flutter_tools\gradle 中找到如:

        if (buildMode != "debug") {
            project.exec {
                executable flutterExecutable.absolutePath
                workingDir sourceDir
                if (localEngine != null) {
                    args "--local-engine", localEngine
                    args "--local-engine-src-path", localEngineSrcPath
                }
                args "build", "aot"
                args "--suppress-analytics"
                args "--quiet"
                args "--target", targetPath
                args "--target-platform", "android-arm"
                args "--output-dir", "${intermediateDir}"
                if (previewDart2) {
                    args "--preview-dart-2"
                } else {
                    args "--no-preview-dart-2"
                }
                if (trackWidgetCreation) {
                    args "--track-widget-creation"
                }
                if (extraFrontEndOptions != null) {
                    args "--extra-front-end-options", "${extraFrontEndOptions}"
                }
                if (extraGenSnapshotOptions != null) {
                    args "--extra-gen-snapshot-options", "${extraGenSnapshotOptions}"
                }
                if (preferSharedLibrary) {
                    args "--prefer-shared-library"
                }
                if (targetPlatform != null) {
                    args "--target-platform", "${targetPlatform}"
                }
                args "--${buildMode}"
            }
        }

你在flutter 工程目录下 执行 flutter build bundle 即可生成编译文件 在 build 中

这里提下配置项
看类 FlutterMain.java

private static void initConfig(Context applicationContext) {
    try {
        Bundle metadata = applicationContext.getPackageManager().getApplicationInfo(applicationContext.getPackageName(), 128).metaData;
        if (metadata != null) {
            sAotSharedLibraryPath = metadata.getString(PUBLIC_AOT_AOT_SHARED_LIBRARY_PATH, "app.so");
            sAotVmSnapshotData = metadata.getString(PUBLIC_AOT_VM_SNAPSHOT_DATA_KEY, "vm_snapshot_data");
            sAotVmSnapshotInstr = metadata.getString(PUBLIC_AOT_VM_SNAPSHOT_INSTR_KEY, "vm_snapshot_instr");
            sAotIsolateSnapshotData = metadata.getString(PUBLIC_AOT_ISOLATE_SNAPSHOT_DATA_KEY, "isolate_snapshot_data");
            sAotIsolateSnapshotInstr = metadata.getString(PUBLIC_AOT_ISOLATE_SNAPSHOT_INSTR_KEY, "isolate_snapshot_instr");
            sFlx = metadata.getString(PUBLIC_FLX_KEY, "app.flx");
            sSnapshotBlob = metadata.getString(PUBLIC_SNAPSHOT_BLOB_KEY, "snapshot_blob.bin");
            sFlutterAssetsDir = metadata.getString(PUBLIC_FLUTTER_ASSETS_DIR_KEY, "flutter_assets");
        }

    } catch (NameNotFoundException var2) {
        throw new RuntimeException(var2);
    }
}

也就是说 这些类容在什么位置,你完全可以在 metaData 里配置出来

编译生成产物

懒懒懒懒懒。。。。
这个自己看下就知道有些什么了,不一定非要知道每一个文件什么作用

系统拷贝assets那些内容到app_flutter目录

这个要看代码了,FlutterMain.java

private static void initResources(Context applicationContext) {
    (new ResourceCleaner(applicationContext)).start();
    sResourceExtractor = (new ResourceExtractor(applicationContext))
                            .addResources(SKY_RESOURCES)
                            .addResource(fromFlutterAssets(sFlx))
                            .addResource(fromFlutterAssets(sSnapshotBlob))
                            .addResource(fromFlutterAssets(sAotVmSnapshotData))
                            .addResource(fromFlutterAssets(sAotVmSnapshotInstr))
                            .addResource(fromFlutterAssets(sAotIsolateSnapshotData))
                            .addResource(fromFlutterAssets(sAotIsolateSnapshotInstr))
                            .addResource(fromFlutterAssets("kernel_blob.bin"))
                            .addResource(fromFlutterAssets("platform.dill"));
    if (sIsPrecompiledAsSharedLibrary) {
        sResourceExtractor.addResource(sAotSharedLibraryPath);
    } else {
        sResourceExtractor.addResource(sAotVmSnapshotData).addResource(sAotVmSnapshotInstr).addResource(sAotIsolateSnapshotData).addResource(sAotIsolateSnapshotInstr).addResource(sSnapshotBlob);
    }

    sResourceExtractor.start();
}

这里的 addResources和addResource 就是拷贝到 app_flutter目录的东西我就不一一列举了

其实这里才是重点,你要高清每一个文件,在更新时那些需要替换,那些是不变的,不然的话你全都替换比较暴力
希望哪位大神把这些文件怎么作用都整理出来,有人已经整理的请帖出地址

上一篇下一篇

猜你喜欢

热点阅读