# MapLibreParticleRNTestHost 这是 MapLibreParticleLab 内的独立 React Native 开发宿主,不是 NavSea 业务应用。它只有一个 `MLRNMapView` 与 WeatherRuntime 控制页,用于证明低频控制面:React 的 `reactTag` 经薄 Android 模块定位该 View,再定位该 View 的 `MapLibreMap` 与 map-owned `WeatherRuntime`。 ## 版本与首次 prebuild 边界 - package manager 为 npm(`packageManager: npm@10.9.4`),锁文件为 `package-lock.json`;当前环境的 `npm ci --dry-run --ignore-scripts` 无须 `--legacy-peer-deps` 即可解析。 - package 明确固定 React Native `0.85.2`、React `19.2.5`、Expo `56.0.4`、TypeScript `5.9.3`、MLRN `11.3.6`;`app.json` 明确请求 New Architecture。Hermes 的最终启用状态必须在首次 Android prebuild 后检查生成工程。 - AGP `8.5.0`、Gradle `8.14.3`、Kotlin `2.1.20`、NDK `27.1.12297006`、JDK 17、minSdk 24、compile/targetSdk 36 是本 Test Host 的**人工验收配置目标**,不是尚未生成 Android 工程的已验证结果。首次 prebuild 后必须以实际 Gradle wrapper、AGP/Kotlin plugin、SDK/NDK 与 Hermes/New Architecture 配置为准核对。 - MLRN 的 root Gradle extras 固定 `org.maplibre.reactnative.nativeVersion=13.4.1` 与 `nativeVariant=opengl`。 ## Custom SDK 来源(手工执行) Gate C 封存环境负责生成 custom AAR;Test Host 只负责 Maven Local handoff。Expo plugin 对唯一 custom 坐标 `org.maplibre.gl:android-sdk-opengl` 排除 Maven Central,而将 Maven Local 排在首位。因此未先发布本仓库 custom SDK 时 dependency resolution 必须失败,不能悄悄使用官方 SDK;MLRN 的独立 turf/annotation/scalebar 依赖不被这个 SDK-only 排除误伤。 ```bash cd /mnt/sda1/MapLibreParticleLab/platform/android RENDERER=opengl BUILDTYPE=Release make apackage ./gradlew :MapLibreAndroid:publishOpenglreleasePublicationToMavenLocal cd /mnt/sda1/MapLibreParticleLab/integration/react-native/MapLibreParticleRNTestHost npm ci npx expo prebuild --platform android --clean npx expo run:android ``` 上述 Android 命令必须在 Gate C 封存 Linux 环境由用户手工执行;本 Step 的 Codex 没有执行。先移走 Maven Local 的旧同版本 artifact,再检查当前 HEAD 新 AAR 的 mtime/SHA-256、`WeatherRuntime`/`MapLibreMap` classes 和发布后的 AAR/POM/module metadata。2026-08-29 的旧 AAR(SHA-256 `5c67…f85e5c`)只可作 Gate C 历史证据,不能用于 STEP-060。 ## Bridge 与生命周期 `WeatherRuntimeBridge` 每个命令通过 `UIManagerHelper.getUIManager(...FABRIC).resolveView(reactTag)` 解析 View,并只接受 `MLRNMapView`。它直接读取公开的 `MLRNMapView.mapLibreMap`,不复制 MLRN 的私有 `mViews`,不保存 current map,也没有第二套 timeline/playback state。`MapLibreMap` 持有每个 map 的唯一 `WeatherRuntime`:style replacement、View detach 和 React unmount 都会 dispose 旧 facade;style ready 后 `attach` 创建新的 facade。 Style JSON 明确创建 background、host-field `RasterArraySource`、`WeatherColorLayer` 与 `RasterParticleLayer`。Bridge 仅在 source/layers 都存在且 style 已加载时 attach;它不会创建私有 Style registry。错误为结构化 reject:`MAP_VIEW_NOT_FOUND`、`MAP_NOT_READY`、`STYLE_NOT_READY`、`WEATHER_OBJECTS_NOT_READY`、`RUNTIME_DISPOSED`、`INVALID_ARGUMENT` 或 Native `REJECTED`。 ## Phase A / B 操作 页面 style ready 后显示 reactTag/runtime;Phase A 按钮为 `getState`、enable、WeatherColor visible、particle visible、FPS 30。Phase B 还通过 bridge 暴露 epoch-ms forecast seek、PLAY/PAUSE、速度、stops、独立 particle/trail RGBA、粒子视觉参数和 WeatherColor opacity。JS 只校验小参数,并不保存另一套 runtime 状态;snapshot 来自 Native。 当前**不包含 Binary Field**,不传 `number[]`、JSON 数组或 base64 field。3.01 MiB canonical field ingress 留给 STEP-061。 启动入口是 `App.tsx`。Android build、安装及设备操作必须由用户手工执行,详见 `docs/60_测试/STEP-060_RNTestHost_Android人工编译与验收_v1.md`。