Files
MapLibreParticleLab/docs/50_Step记录/STEP-080_Android_AAR与RNTestHost标准构建流水线_v2.md
OpenAI Codex de8d230b87
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
docs: record public AAR to RN Test Host validation flow
2026-09-14 09:17:22 +08:00

13 KiB
Raw Permalink Blame History

STEP-080 — Android AAR 与 RN Test Host 标准构建流水线 v2

状态:已按真实 Linux → pbf → Windows 11 → Android 模拟器链路验证通过

日期:2026-09-14

1. 目的

本文固定 MapLibreParticleLab Android Native AAR 完成后,到 Windows 11 构建 RN Test Host、启动 Metro、安装 App、执行 QBIN V4 验证的标准流程。

以后正常验证不得再临时复制 AAR、临时改 MavenLocal、在 Windows 重编 Native AAR,或凭经验猜 Metro 端口。

2. 最终权威链路

Linux MapLibreParticleLab
→ 编译 Native OpenGL AAR
→ 发布到 /mnt/nas/pbf/maven
→ 公网 https://pbf.jpcn.ccwu.cc/maven

Linux RN package
→ npm pack
→ 发布到 /mnt/nas/pbf/npm
→ 公网 https://pbf.jpcn.ccwu.cc/npm

Windows 11 RN Test Host
→ npm install 公网 tgz
→ Gradle 从公网 Maven 自动取得 Native AAR
→ Expo prebuild
→ assembleDebug
→ Metro :8091
→ adb reverse 8081 → 8091
→ 安装并启动 App
→ QBIN V4 真机/模拟器验证

3. Linux 与 Windows 的职责边界

Linux 负责

  • MapLibre Native Android OpenGL AAR 编译。
  • Native AAR 版本管理。
  • RN package 打包。
  • AAR/POM/module 与 RN tgz 发布到 pbf。
  • 公网回读并校验 SHA-256。

Windows 11 负责

  • 从 pbf npm 安装 RN package。
  • 通过 Gradle 从 pbf Maven 消费对应 Native AAR。
  • Expo prebuild。
  • Test Host Debug APK 编译。
  • Metro、ADB reverse、安装、启动和人工验证。

禁止

  • Windows 正常流程中重新编译 MapLibre Native AAR。
  • Windows 正常流程中使用 Maven Local 替代 pbf Maven。
  • Linux 与 Windows 之间通过局域网临时复制 AAR 作为正式验证路径。
  • 覆盖旧 Maven 版本坐标。

4. 版本一致性硬门槛

以当前已验证版本为例:

RN package = 13.4.1-particle.3
Native AAR = 13.4.1-particle.3

以下位置必须全部一致,否则停止构建:

  1. platform/android/VERSION
  2. packages/maplibre-particle-rn/package.json
  3. packages/maplibre-particle-rn/android/build.gradle
  4. packages/maplibre-particle-rn/app.plugin.js
  5. integration/react-native/MapLibreParticleRNTestHost/plugins/withParticleNativeAndroid.js

5. Linux:AAR 构建与发布

推荐使用仓库内标准脚本:

cd /mnt/sda1/MapLibreParticleLab
tools/particle_android_pipeline/linux_build_publish.sh

如果只是检查版本、SDK、路径和发布条件:

tools/particle_android_pipeline/linux_build_publish.sh --preflight

Linux Android SDK 当前实际路径:

/root/Android/Sdk

AAR 必须使用新的版本目录发布,不能覆盖历史 .2:

/mnt/nas/pbf/maven/cc/navsea/maplibre/android-sdk-particle-opengl/<version>/

当前 .3 目录为:

/mnt/nas/pbf/maven/cc/navsea/maplibre/android-sdk-particle-opengl/13.4.1-particle.3/

至少包含:

android-sdk-particle-opengl-13.4.1-particle.3.aar
android-sdk-particle-opengl-13.4.1-particle.3.pom
android-sdk-particle-opengl-13.4.1-particle.3.module

RN package 使用 npm pack 生成,并发布到:

/mnt/nas/pbf/npm/navsea-maplibre-particle-rn-<version>.tgz

6. Linux:把 AAR 正式发布到公网 pbf

https://pbf.jpcn.ccwu.cc/ 的服务器文件根目录固定映射为:

/mnt/nas/pbf

因此 Maven 公网根:

https://pbf.jpcn.ccwu.cc/maven/

对应 Linux:

/mnt/nas/pbf/maven/

npm/tgz 公网根:

https://pbf.jpcn.ccwu.cc/npm/

对应 Linux:

/mnt/nas/pbf/npm/

发布不需要 SSH 到其他服务器,也不需要从 Win11 上传;Linux 直接写 /mnt/nas/pbf 即完成公网发布。

6.1 发布 Native AAR

先定义版本:

VERSION=13.4.1-particle.3
GROUP_PATH=cc/navsea/maplibre/android-sdk-particle-opengl
SRC="$HOME/.m2/repository/$GROUP_PATH/$VERSION"
DST="/mnt/nas/pbf/maven/$GROUP_PATH/$VERSION"

正常发布必须使用一个从未发布过的新版本。先保护旧版本:

test ! -e "$DST" || {
  echo "目标版本已经存在,禁止覆盖:$DST" >&2
  exit 1
}

确认本地 Maven publication 完整:

ls -lh "$SRC"
sha256sum "$SRC/android-sdk-particle-opengl-$VERSION.aar"

创建公网 Maven 版本目录并复制:

mkdir -p "$DST"
cp -a "$SRC"/. "$DST"/

至少确认:

test -f "$DST/android-sdk-particle-opengl-$VERSION.aar"
test -f "$DST/android-sdk-particle-opengl-$VERSION.pom"
test -f "$DST/android-sdk-particle-opengl-$VERSION.module"

6.2 公网回读验证 AAR

公网 URL 规则:

https://pbf.jpcn.ccwu.cc/maven/cc/navsea/maplibre/android-sdk-particle-opengl/<VERSION>/android-sdk-particle-opengl-<VERSION>.aar

发布后必须从公网重新下载,不允许只检查 /mnt/nas/pbf 本地文件:

LOCAL_AAR="$DST/android-sdk-particle-opengl-$VERSION.aar"
PUBLIC_AAR="https://pbf.jpcn.ccwu.cc/maven/$GROUP_PATH/$VERSION/android-sdk-particle-opengl-$VERSION.aar"
TMP_AAR="$(mktemp)"

curl -fL "${PUBLIC_AAR}?nocache=$(date +%s)" -o "$TMP_AAR"
sha256sum "$LOCAL_AAR" "$TMP_AAR"
cmp -s "$LOCAL_AAR" "$TMP_AAR"

cmp 必须返回 0。只有公网回读字节完全一致,才算 AAR 发布完成。

同时可验证 POM/module HTTP 200:

curl -fI "https://pbf.jpcn.ccwu.cc/maven/$GROUP_PATH/$VERSION/android-sdk-particle-opengl-$VERSION.pom"
curl -fI "https://pbf.jpcn.ccwu.cc/maven/$GROUP_PATH/$VERSION/android-sdk-particle-opengl-$VERSION.module"

6.3 发布 RN package 到公网 npm 目录

在仓库中生成 tgz:

cd /mnt/sda1/MapLibreParticleLab/packages/maplibre-particle-rn
npm pack

生成文件示例:

navsea-maplibre-particle-rn-13.4.1-particle.3.tgz

正式发布路径:

TGZ="navsea-maplibre-particle-rn-$VERSION.tgz"
PUBLIC_TGZ_DIR="/mnt/nas/pbf/npm"

test ! -e "$PUBLIC_TGZ_DIR/$TGZ" || {
  echo "公网同版本 tgz 已存在,禁止覆盖;请升级版本" >&2
  exit 1
}

cp "$TGZ" "$PUBLIC_TGZ_DIR/$TGZ"

公网 URL:

https://pbf.jpcn.ccwu.cc/npm/navsea-maplibre-particle-rn-<VERSION>.tgz

发布后必须公网回读并比较 SHA:

TMP_TGZ="$(mktemp)"
curl -fL "https://pbf.jpcn.ccwu.cc/npm/$TGZ?nocache=$(date +%s)" -o "$TMP_TGZ"
sha256sum "$TGZ" "$TMP_TGZ"
cmp -s "$TGZ" "$TMP_TGZ"

正常发布不得重新覆盖同一版本的 tgz。今天 .3 的覆盖属于修复历史错误包的例外,不应成为日常流程。

7. Windows 11:从公网取得 RN package 与 AAR

Windows 正常流程不直接下载 AAR 文件。AAR 由 Gradle 根据 RN package 中的 Maven coordinate 自动从 pbf Maven 获取。

当前 Test Host 建议工作目录:

D:\React\MapLibreParticleRNTestHost-V4

不要在 V:\ 盘符根目录执行 Expo prebuild;本次实测 Expo autolinking 在盘符根目录会出现 Couldn't find package.json up from path V:\。

7.1 安装 RN package

cd D:\React\MapLibreParticleRNTestHost-V4

npm install --force `
  https://pbf.jpcn.ccwu.cc/npm/navsea-maplibre-particle-rn-13.4.1-particle.3.tgz

正常情况下新版本不需要清 npm cache;只有确认同版本曾被错误覆盖时才做:

npm cache clean --force

安装后必须核对实际依赖:

Get-Content node_modules\@navsea\maplibre-particle-rn\package.json
Select-String `
  -Path node_modules\@navsea\maplibre-particle-rn\android\build.gradle `
  -Pattern 'android-sdk-particle-opengl'

必须看到目标版本,例如:

cc.navsea.maplibre:android-sdk-particle-opengl:13.4.1-particle.3

7.2 Expo prebuild 与 Android SDK

执行:

cd D:\React\MapLibreParticleRNTestHost-V4
npx expo prebuild --platform android

Windows Android SDK 当前实际路径:

C:\Users\taibe\AppData\Local\Android\Sdk

如果 Gradle 报 SDK location not found,优先在当前 PowerShell 显式设置:

$env:ANDROID_HOME='C:\Users\taibe\AppData\Local\Android\Sdk'
$env:ANDROID_SDK_ROOT='C:\Users\taibe\AppData\Local\Android\Sdk'

并写入:

D:\React\MapLibreParticleRNTestHost-V4\android\local.properties

内容:

sdk.dir=C\:\\Users\\taibe\\AppData\\Local\\Android\\Sdk

7.3 构建 Debug APK

cd D:\React\MapLibreParticleRNTestHost-V4\android
$env:ANDROID_HOME='C:\Users\taibe\AppData\Local\Android\Sdk'
$env:ANDROID_SDK_ROOT=$env:ANDROID_HOME
.\gradlew.bat :app:assembleDebug

成功产物:

D:\React\MapLibreParticleRNTestHost-V4\android\app\build\outputs\apk\debug\app-debug.apk

8. Metro、ADB reverse、安装与启动

Test Host 的固定规则是:

Metro 实际监听端口:8091
App 默认访问端口:8081
ADB reverse:tcp:8081 → tcp:8091

8.1 启动 Metro

cd D:\React\MapLibreParticleRNTestHost-V4
npx expo start --port 8091 --clear

8.2 配置 reverse

另开一个 PowerShell:

adb -s 192.168.1.146 reverse --remove-all
adb -s 192.168.1.146 reverse tcp:8081 tcp:8091
adb -s 192.168.1.146 reverse --list

必须看到:

tcp:8081 tcp:8091

8.3 安装并启动

adb -s 192.168.1.146 install -r `
  D:\React\MapLibreParticleRNTestHost-V4\android\app\build\outputs\apk\debug\app-debug.apk

adb -s 192.168.1.146 shell am force-stop org.maplibre.particle.rntesthost
adb -s 192.168.1.146 shell am start `
  -n org.maplibre.particle.rntesthost/.MainActivity

9. V3 fixture 与 Metro watchFolders

当前 Test Host 同时保留旧 V3 数据集和 V4 QBIN 数据集。

独立 Windows Host 使用:

D:\React\MapLibreParticleRNTestHost-V4
D:\React\particle-v3-fields

src/fieldDatasets.ts 使用 ../../particle-v3-fields/...,因此这些 fixture 位于 Metro 项目根之外。

此时 metro.config.js 必须把外部 fixture 目录加入 watchFolders,例如独立 Windows Host:

const path = require("path");
const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);
config.resolver.assetExts = [...new Set([...config.resolver.assetExts, "f32", "u8", "qbin"])];
config.watchFolders = [
  path.resolve(__dirname, "..", "particle-v3-fields"),
];

module.exports = config;

修改 metro.config.js 后必须重启 Metro,普通 Reload 不足以保证配置重载。

如果看到:

Unable to resolve ../../particle-v3-fields/...

先确认文件实际存在,再检查 watchFolders;不要重复复制同一批 fixture 或误判为 QBIN 问题。

10. QBIN V4 验收确认

V4 测试区必须走:

assets/qbin-golden/*.qbin
→ FieldRuntime.submitEncodedField(...)
→ WeatherRuntimeBridgeModule.submitEncodedField(...)
→ WeatherRuntime.submitEncodedField(...)
→ JNI native_map_view.cpp
→ RasterArraySource::submitEncodedField(...)
→ QbinV2Decoder::decode(...)

这与旧 V3 metadata.json + .f32 + .u8 → submitField(...) 是两条不同链路。

至少验证:

  • V4 Wind:T0/T1 load、Color Binding、Particle Binding、T0/midpoint/T1 seek。
  • V4 Wave:同上。
  • V4 Current:同上。
  • V4 Rain:Color Binding、T0/midpoint/T1;Particle Binding 为 N/A。
  • PLAY / PAUSE / playback speed。
  • clearEncodedField / clearAllEncodedFields。

人工确认 V4 功能正常后,才可判定 Windows Android QBIN V4 验证通过。

11. 本次 .3 已验证发布基线

Native AAR:

cc.navsea.maplibre:android-sdk-particle-opengl:13.4.1-particle.3
SHA-256: 9ef03eb0d0c03457adc04847cfa69fb67d85191daecd64d3b76db2ad8cc688cd

最终修正后的 RN tgz:

https://pbf.jpcn.ccwu.cc/npm/navsea-maplibre-particle-rn-13.4.1-particle.3.tgz
SHA-256: abdd5b5f313b6dc2bc2f2b00848d1901be72fed6a6e1fa15899efb10df9f923f

Windows 11 Debug APK 已于 2026-09-14 成功构建、安装并由用户完成功能验证。

12. 本次实际踩过的弯路与固定处理

A. Win11 不要重编 Native AAR

症状:为了验证 Test Host,又在 Windows 尝试重建 MapLibre Native。

固定规则:Native AAR 只在 Linux 生产;Windows 只通过 pbf Maven 消费。

B. 不要用局域网复制 AAR 作为正常路径

固定规则:Linux 发布到 /mnt/nas/pbf/maven,Windows Gradle 从 https://pbf.jpcn.ccwu.cc/maven 获取。

C. RN package 版本号相同但内部仍依赖旧 AAR

必须检查 android/build.gradle、app.plugin.js、Test Host plugin 的 Maven coordinate,不能只看 package.json 版本号。

D. Android Kotlin 必须实编译

Linux TypeScript/Core 检查无法替代 Android Kotlin 编译。本次实际发现 value >= if (...) 在 Kotlin 编译器下失败,最终改为显式括号与 Double 常量。

E. Expo 不要在 V:\ 根目录 prebuild

本次实际出现 Couldn't find package.json up from path V:\。固定使用普通子目录,例如 D:\React\MapLibreParticleRNTestHost-V4。

F. App 报 localhost:8081,而 Metro 在 8091

这是正常设计,不要把 Metro 改回 8081。正确映射是:

adb reverse tcp:8081 tcp:8091

G. fixture 文件存在但 Metro 仍 Unable to resolve

优先检查 watchFolders,不要重复复制 fixture。仓库 Test Host 的 metro.config.js 已加入仓库布局/独立 Windows 布局自动探测。

13. 文档优先级

本文件 v2 覆盖 STEP-080 v1 中“Linux bundle → Windows MavenLocal”的正常发布结论。

tools/particle_android_pipeline/ 中旧脚本保留用于历史/离线用途;正常联网验证以本文的 pbf 公网链路为准。