Flutter - 混编项目集成Shorebird热更新🐦(安卓篇)

欢迎关注微信公众号:FSA全栈行动 👋

一、概述

目前我们的项目是按照 Flutter 官方文档 docs.flutter.dev/add-to-app/...,以源码依赖的方式集成到原生项目,在集成 Shorebird 实现热更新时,需要我们将源码依赖的方式调整成二进制依赖。

安卓端的改动还是很简单的,一路下来没怎么碰壁,接下来一起来看看如何操作吧

二、Shorebird 初始化

本文以 Mac 环境为例,如果你是 Windows 用户,请按官方文档去操作: docs.shorebird.dev

该部分内容只需要一开始没有环境和相应的文件时去操作一次

安装 CLI

打开终端,执行以下命令

shell 复制代码
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash

重启终端,输入 shorebird 即可看到相应的命令输出

shell 复制代码
$ shorebird
The shorebird command-line tool

Usage: shorebird <command> [arguments]

Global options:
-h, --help            Print this usage information.
    --version         Print the current version.
-v, --[no-]verbose    Noisy logging, including all shell commands executed.

Available commands:
  cache      Manage the Shorebird cache.
  doctor     Show information about the installed tooling.
  flutter    Manage your Shorebird Flutter installation.
  init       Initialize Shorebird.
  login      Login as a new Shorebird user.
  login:ci   Login as a CI user.
  logout     Logout of the current Shorebird user
  patch      Manage patches for a specific release in Shorebird.
  preview    Preview a specific release on a device.
  release    Manage your Shorebird app releases.
  upgrade    Upgrade your copy of Shorebird.

Run "shorebird help <command>" for more information about a command.

你可以查看当前 Shorebird 支持哪些 Flutter 版本

复制代码
shorebird flutter versions list
ruby 复制代码
$ shorebird flutter versions list
📦 Flutter Versions
✓ 3.13.9
  3.13.8
  3.13.7
  3.13.6
  3.13.5
  3.13.4
  3.13.3
  3.13.2
  3.13.1
  3.13.0
  3.10.7
  3.10.6
  3.10.5
  3.10.4
  3.10.3
  3.10.2
  3.10.1
  3.10.0

如我现在需要用到 Flutter 3.13.9 版本,则输入如下命令

shell 复制代码
$ shorebird flutter versions use 3.13.9

Flutter 模块初始化

在你的 Flutter 项目下执行如下命令

csharp 复制代码
shorebird init

该命令会生成在项目根目录生成 shorebird.yaml 文件

yaml 复制代码
# shorebird.ymal的内容
app_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx

# auto_update: false

以及修改 pubspec.yaml

yaml 复制代码
  assets:
    - shorebird.yaml

三、原生项目改造

以下的相关修改是以我们项目来写的(.kts),如果你的跟我的不一样,可以看一下文档:docs.shorebird.dev/guides/hybr...

build.gradle.kts

新增本地二进制依赖

diff 复制代码
buildscript {
    repositories {
        ...
            
+        // 本地依赖Flutter包
+        maven(url = "../../flutter_module/release")
+        maven(url = "https://download.shorebird.dev/download.flutter.io")
        
        ...
    }
}

allprojects {
    repositories {
        ...
            
+        // 本地依赖Flutter包
+        maven(url = "../../flutter_module/release")
+        maven(url = "https://download.shorebird.dev/download.flutter.io")
        
        ...
    }
}

settings.gradle.kts

注释掉本地源码依赖

diff 复制代码
- evaluate(new File(
-         settingsDir,
-         "../flutter_module/.android/include_flutter.groovy"
- ))
+ //evaluate(new File(
+ //        settingsDir,
+ //        "../flutter_module/.android/include_flutter.groovy"
+ //))

app/build.gradle.kts

注释掉本地源码依赖,新增本地二进制依赖

diff 复制代码
dependencies {
+    // Flutter源码依赖
-    implementation(project(LocalLib.flutter))    
+    // implementation(project(LocalLib.flutter))

+    // Flutter二进制依赖
+    releaseImplementation("com.lxf.flutter_modules:flutter_release:1.0")
}

四、创建 Shorebird Release

打发布包的时候操作,在 Flutter 工程目录下执行

shell 复制代码
cd xx/xx/flutter_modules

# 7.0.0+320: 大版本号+小版本号
shorebird release aar --release-version 7.0.0+320

该命令内部会去执行 flutter build aar --no-debug --no-profile ...,并且使用的是 Shorebird 魔改的 Flutter 引擎!

版本号可以在如下路径的文件中查看

xml 复制代码
# 路径: app/src/main/AndroidManifest.xml
# 小版本号: android:versionCode
# 大版本号: android:versionName

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.lxf.flutter_modules"
    android:versionCode="320"
    android:versionName="7.0.0">
...
</manifest>

ShoreBird 的内部逻辑会去以这个版本号组合,向服务器请求判断是否存在相应版本的相关补丁!

执行完成后,在 Shorebird 控制台上可以看到相应的项

在命令执行前,请确保不存在 7.0.0+320 的 Release,如果有的话,请先删除

五、创建 Shorebird Patch

紧急修复线上包的bug时操作,在 Flutter 工程目录下执行

shell 复制代码
shorebird patch aar --release-version 7.0.0+320

注:版本号与上述的 release 命令中使用的要保持一致!

执行完成后,在 Shorebird 控制台上点击对应的 Release 项,进去后可以看到相应的补丁

六、热更新验证

  1. 未打 patch 时,请以 release 模式运行原生工程(在 Active Build Variant 的下拉选项中选择 release)
  2. 关闭 App
  3. 打 patch 后,重新打开 App,关闭 App 再打开 App,即可看到变化

如果补丁没有生效,可以在 Logcat 内检测相关输出,成功还是失败可以直接看后两句,如下两种情况的输出:

成功:

shell 复制代码
[INFO:shorebird.cc(109)] Shorebird updater: no active patch.
[INFO:shorebird.cc(113)] Starting Shorebird update
updater::network: Sending patch check request: PatchCheckRequest { app_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx", channel: "stable", release_version: "7.0.0+320", patch_number: None, platform: "android", arch: "aarch64" }
updater::updater: Patch 1 successfully installed.
updater::updater: Update thread finished with status: Update installed

失败:

shell 复制代码
[INFO:shorebird.cc(109)] Shorebird updater: no active patch.
[INFO:shorebird.cc(113)] Starting Shorebird update
updater::network: Sending patch check request: PatchCheckRequest { app_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx", channel: "stable", release_version: "7.0.0+320", patch_number: None, platform: "android", arch: "aarch64" }
updater::updater: Update failed: failed to fill whole buffer
updater::updater: Update thread finished with status: Update had error

失败的时候,看一下 PatchCheckRequest 后面的请求参数输出,一般失败都是因为这里的参数错误才导致。

七、脚本

由于我们日常研发还是使用的是源码依赖的方式,只会在打最终测试包时才需要去做上述的调整操作,所以这里用我比较熟悉的 Python 去制作了简易的脚本,并结合 Jenkins 来辅助完成这种万年不变的无聊步骤

脚本已上传至 Github: github.com/LinXunFeng/...

看官可自取修改~

switch_flutter_integrate.py

切换 Flutter 项目的集成方式

shell 复制代码
# 二进制依赖
python switch_flutter_integrate.py -p '原生工程路径' -m 'binary' -f 'android'

# 源码依赖
python switch_flutter_integrate.py -p '原生工程路径' -m 'source' -f 'android' 

shorebird.py

自动获取版本号,并执行 Shorebird 相关命令

shell 复制代码
# release
python shorebird.py -p '原生工程路径' -s 'Flutter工程路径' -m release -f android

# patch
python shorebird.py -p '原生工程路径' -s 'Flutter工程路径' -m patch -f android

八、最后

本篇到此结束,感谢大家的支持,我们下次再见! 👋

如果文章对您有所帮助, 请不吝点击关注一下我的微信公众号:FSA全栈行动, 这将是对我最大的激励. 公众号不仅有 iOS 技术,还有 Android,Flutter,Python 等文章, 可能有你想要了解的技能知识点哦~

相关推荐
粥里有勺糖33 分钟前
安利一下最近用的桌面“Agent” | T3 Code
前端·github·ai编程
蒸鱼Yuzheng37 分钟前
Android 构建可复现性:APK 指纹、文件级差异与供应链审计
android·apk·devops·软件供应链·可复现构建
xy345339 分钟前
Axure 9.0 动态面板基本操作
前端·ui·html·axure·原型·产品设计
不停喝水1 小时前
【前端转全栈java速通课】 项目实战④7-11节 操作数据库-登录-注册-修改密码-注销-mubatis-plus简化crud-
java·前端·数据库
一水鉴天2 小时前
统一对象拓扑(UOT)设计全链定稿:从三件事分离到三继承 之1 20261010(豆包“查看聊天内容”继续)
前端·css
栖凤2 小时前
Java 的 try-catch 在 Agent 里失效了,我用了 5 个模式才兜住
java·前端·python
粥里有勺糖2 小时前
视野修炼第136期 | 前端小恐龙"Deno"被收购
前端·github·ai编程
修炼的dance2 小时前
页面塞了13.88 MB字体,导出的PDF只有71 KB
前端
qq_369173632 小时前
如何将 AI 生成的 HTML 网页发布成在线链接?不用自己搭建服务器
前端·人工智能·html·效率工具·html 发布
风花一世月2 小时前
⚡ 我把一座含氢能源园区搬进了浏览器(五类能流实时算守恒,在线直接玩)
前端·人工智能