美文网首页FlutterFlutter
flutter 在 android 上的热更新

flutter 在 android 上的热更新

作者: tangzejin921 | 来源:发表于2018-08-18 18:57 被阅读9396次

    热更新是一种需求吧。
    自然会想到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目录的东西我就不一一列举了

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

    相关文章

      网友评论

        本文标题:flutter 在 android 上的热更新

        本文链接:https://www.haomeiwen.com/subject/uwififtx.html