FSA全栈行动 FSA全栈行动
首页
  • 移动端文章

    • Android
    • iOS
    • Flutter
  • 学习笔记

    • 《Kotlin快速入门进阶》笔记
    • 《Flutter从入门到实战》笔记
    • 《Flutter复习》笔记
前端
后端
  • 学习笔记

    • 《深入浅出设计模式Java版》笔记
  • 逆向
  • 分类
  • 标签
  • 归档
  • LinXunFeng
  • GitLqr

公众号:FSA全栈行动

记录学习过程中的知识
首页
  • 移动端文章

    • Android
    • iOS
    • Flutter
  • 学习笔记

    • 《Kotlin快速入门进阶》笔记
    • 《Flutter从入门到实战》笔记
    • 《Flutter复习》笔记
前端
后端
  • 学习笔记

    • 《深入浅出设计模式Java版》笔记
  • 逆向
  • 分类
  • 标签
  • 归档
  • LinXunFeng
  • GitLqr
  • AndroidUI

  • Android第三方SDK

  • Android混淆

  • Android仓库

  • Android新闻

  • Android系统开发

  • Android源码

  • Android注解AOP

  • Android脚本

  • AndroidTv开发

  • AndroidNDK

  • Android音视频

  • Android热修复

  • Android性能优化

  • Android云游戏

  • Android插件化

  • iOSUI

  • iOS工具

  • iOS底层原理与应用

  • iOS组件化

  • iOS音视频

  • iOS疑难杂症

  • iOS之Swift

  • iOS之RxSwift

  • iOS开源项目

  • iOS逆向

  • Flutter开发

    • Dart - 抽象类的实例化
    • Flutter - 打印好用的Debug日志
    • Flutter - 混合开发
    • Flutter - 解决混合开发iOS脚本打包遇到的问题
    • Flutter - 低版本在iOS14上遇到的问题与解决方案
    • Flutter - 解决原生弹窗的触摸事件被Flutter响应的问题
    • Flutter - 实现列表上下拉切换header
    • Flutter - 获取ListView当前正在显示的Widget信息
    • Flutter - 列表滚动定位超强辅助库,墙裂推荐!🔥
    • Flutter - 快速实现聊天会话列表的效果,完美💯
    • Flutter - 聊天输入框更新文本时的必备优化点🔖
    • Flutter - 我给官方提PR,解决run命令卡住问题 😃
    • Flutter - 探索run命令到底做了什么 🤔
    • Flutter - 引擎调试(iOS篇)🛠
    • Flutter - 引擎调试bug到提交PR实战 🐞
    • Flutter - 船新升级😱支持观察第三方构建的滚动视图💪
    • Flutter - 瀑布流交替播放视频 🎞
    • Flutter - IM保持消息位置大升级(支持ChatGPT生成式消息) 🤖
    • Flutter - 滚动视图中的表单防遮挡 🗒
    • Flutter - 秒杀1/2曝光统计 📊
    • 一天内加入 Flutter 和 FlutterCandies 两大组织是什么体验 🧐
    • Flutter - 如何快速搓一个微信通讯录列表(azlist) 📓
    • Flutter - 混编项目集成Shorebird热更新🐦(安卓篇)
      • 一、概述
      • 二、Shorebird 初始化
        • 安装 CLI
        • 登录
        • 选择 Flutter 版本
        • Flutter 模块初始化
      • 三、原生项目改造
        • build.gradle.kts
        • settings.gradle.kts
        • app/build.gradle.kts
      • 四、创建 Shorebird Release
      • 五、创建 Shorebird Patch
      • 六、热更新验证
      • 七、脚本
        • switchflutterintegrate.py
        • shorebird.py
    • Flutter - 混编项目集成Shorebird热更新🐦(iOS篇)
    • Flutter - 解决返回原生页面时dispose方法未被触发的问题 🐞
    • Flutter - 升级3.19之后页面多次rebuild?🤨
    • Flutter - 热更新 Shorebird 1.0 正式版来了 🐦
    • Flutter - 使用Pigeon实现视频缓存插件 🐌
    • Flutter - 轻松搞定屏幕旋转功能 😎
    • Flutter - 解决Connection closed before full header was received
    • Flutter - 实现聊天键盘与功能面板的丝滑切换 🍻
    • Flutter - 支持观察NestedScrollView,兼容性更强 😈
    • Flutter - 聊天键盘与面板丝滑切换的强势升级 🍻
    • Flutter - 升级到3.24后页面还会多次rebuild吗?🧐
    • Flutter - 轻松实现PageView卡片偏移效果
    • Flutter - 轻松搞定炫酷视差(Parallax)效果
    • Flutter - 危!3.24版本苹果审核被拒!
    • Flutter - 子部件任意位置观察滚动数据
    • Flutter - iOS编译加速
    • Flutter - Xcode16 还原编译速度
  • 移动端
  • Flutter开发
LinXunFeng
2024-01-07
目录

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

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

# 一、概述

目前我们的项目是按照 Flutter 官方文档 https://docs.flutter.dev/add-to-app/android/project-setup?tab=module-source (opens new window),以源码依赖的方式集成到原生项目,在集成 Shorebird 实现热更新时,需要我们将源码依赖的方式调整成二进制依赖。

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

# 二、Shorebird 初始化

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

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

# 安装 CLI

打开终端,执行以下命令

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

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

$ 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 账号

shorebird login

# 选择 Flutter 版本

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

shorebird flutter versions list
$ 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 版本,则输入如下命令

$ shorebird flutter versions use 3.13.9

# Flutter 模块初始化

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

shorebird init

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

# shorebird.ymal的内容
app_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx

# auto_update: false

以及修改 pubspec.yaml

  assets:
    - shorebird.yaml

# 三、原生项目改造

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

# build.gradle.kts

新增本地二进制依赖

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

注释掉本地源码依赖

- evaluate(new File(
-         settingsDir,
-         "../flutter_module/.android/include_flutter.groovy"
- ))
+ //evaluate(new File(
+ //        settingsDir,
+ //        "../flutter_module/.android/include_flutter.groovy"
+ //))

# app/build.gradle.kts

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

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

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

# 四、创建 Shorebird Release

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

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 引擎!

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

# 路径: 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 工程目录下执行

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 内检测相关输出,成功还是失败可以直接看后两句,如下两种情况的输出:

成功:

[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

失败:

[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: https://github.com/LinXunFeng/script_box/tree/main/flutter (opens new window)

看官可自取修改~

# switch_flutter_integrate.py

切换 Flutter 项目的集成方式

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

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

# shorebird.py

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

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

# patch
python shorebird.py -p '原生工程路径' -s 'Flutter工程路径' -m patch -f android
#Dart#Flutter#Shorebird
Flutter - 如何快速搓一个微信通讯录列表(azlist) 📓
Flutter - 混编项目集成Shorebird热更新🐦(iOS篇)

← Flutter - 如何快速搓一个微信通讯录列表(azlist) 📓 Flutter - 混编项目集成Shorebird热更新🐦(iOS篇)→

最近更新
01
Flutter - Xcode16 还原编译速度
04-05
02
AI - 免费的 Cursor 平替方案
03-30
03
Android - 2025年安卓真的闭源了吗
03-28
更多文章>
Theme by Vdoing | Copyright © 2020-2025 FSA全栈行动
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×