5 步把源码构建的 Android 库跑上模拟器:react-native-macos 从构建到排障的完整指南
【免费下载链接】react-native-macos[deprecated in favor of https://microsoft.github.io/react-native-windows/] React Native for macOS is an experimental fork for writing desktop apps using Cocoa项目地址: https://gitcode.com/gh_mirrors/re/react-native-macos
如果你要修改 react-native-macos 的 Android 侧代码,或想确认自己维护的 fork 还能正常出包,最可靠的验证方式是:从源码编译ReactAndroid、发布到本地 Maven 仓库、再让一个新建工程引用这份产物,最后在模拟器上把构建、发布、模拟器运行和日志排查的闭环走一遍。本文按你实际会碰到的问题顺序,分 5 步讲完整条开发体验流程。
如果还没拿到仓库:
git clone https://gitcode.com/gh_mirrors/re/react-native-macos做完本文,你能独立复现 Android 源码构建环境,并知道每一环失败时该去哪里找原因。
1️⃣ 先把三个必须锁死版本的 SDK 组件装齐
这一步解决"机器上到底要装什么,构建才可能成功"。很多第一次构建失败,根因都不在代码,而在 SDK 组件版本没对齐。
在终端执行android打开 SDK Manager,对照下面这张表勾选:
| 组件 | 版本 | 它管什么 | 为什么是这个版本 |
|---|---|---|---|
| Android SDK(platform) | 23 | 编译期用的平台 API | ReactAndroid/build.gradle 里写死compileSdkVersion 23 |
| SDK Build Tools | 23.0.1 | aapt、dx 等构建工具链 | 同文件里buildToolsVersion "23.0.1" |
| Android Support Repository | 17 | 提供 Support Library | instrumentation 测试的AndroidJUnitRunner依赖它 |
几个容易忽略的点:
- 装比 23 更高的 platform 不会报错,但编译基线始终锚定 23,低于 23 则直接构建失败;
defaultConfig里minSdkVersion 16,意味着 API 16 以下的设备跑不了你构建出的应用;targetSdkVersion是 22 而不是 23,这是上游配置本身的选择,不用改。
配置完成后,可以在 ReactAndroid/DevExperience.md 里对照官方流程确认组件清单,它是本仓库内置的权威步骤文档。
2️⃣ 一条命令完成构建与发布:installArchives
这一步解决"如何把 ReactAndroid 源码变成一个别的工程能依赖的构件"。
在仓库根目录执行:
./gradlew :ReactAndroid:installArchives:ReactAndroid指向哪个模块,由根目录 settings.gradle 决定:
include ':ReactAndroid', ':RNTester:android:app'这条命令内部实际分两个阶段跑,理解这两阶段才能看懂报错出在哪:
- 编译阶段。ReactAndroid/build.gradle 里有一串
download*/prepare*任务:先把 boost、double-conversion、folly、glog 和 JavaScriptCore 头文件拉到build/downloads,拼装进third-party-ndk目录,然后调用ndk-build产出libreactnativejni等 so,再连同 Java 源码打成 AAR。如果你的机器上已有这些依赖源码,可以设置环境变量REACT_NATIVE_DEPENDENCIES指向该目录,跳过下载;boost 体积较大,单独支持REACT_NATIVE_BOOST_PATH。 - 发布阶段。ReactAndroid/release.gradle 中定义了
installArchives任务(类型是Upload),目标仓库是一个本地文件路径:
task installArchives(type: Upload) { configuration = configurations.archives repositories.mavenDeployer { repository url: "file://${projectDir}/../android" configureReactNativePom pom } }也就是仓库根目录下的android/目录,会被当成一个 Maven 仓库来写。发布坐标由 ReactAndroid/gradle.properties 决定:
| 属性 | 值 | 含义 |
|---|---|---|
| GROUP | com.facebook.react | 组织坐标 |
| POM_ARTIFACT_ID | react-native | 构件名 |
| VERSION_NAME | 1000.0.0-master | 版本号,刻意远高于 npm 上的 0.x |
| POM_PACKAGING | aar | 打包格式 |
验证方式:命令跑完后到仓库根目录的android/下看,应当出现com/facebook/react/react-native/1000.0.0-master/层级目录,里面有 AAR、sources、javadoc 和.pom文件。
还有一个前提必须提前满足:android-jsc(JavaScriptCore 的 Android 绑定)要事先装进本地 Maven 仓库,文档里对此只有一句"假定已安装"。原因是编译阶段的prepareJSC任务会直接从compile配置里取出android-jsc的 AAR 解包 so 文件,installArchives不会替你发布它——缺了它,构建会在依赖解析时就挂掉。
3. 新建工程,并让它真的引用你的构建产物
这一步解决"发布完了,新工程凭什么用你的本地 AAR 而不是 npm 上的旧版"。
创建工程:
react-native init ProjectNameinit生成的工程默认依赖 npm registry 上发布的 react-native。如果不做任何处理,Gradle 解析com.facebook.react:react-native时拿到的是预编译的旧版 AAR,你installArchives的产物就被完全绕过了。原文档给出的对策只有两条路,选其一即可:
- 把新工程
package.json中 react-native 的版本号提升到一个大于 0.9 的值(当时的 npm 最新版),确保版本约束下本地构件可被解析; - 为 react-native 配置代理(proxying),让依赖解析整体走你自己的 registry 或本地目录。
验证方式:改完后重新构建,观察 Gradle 是否下载/命中1000.0.0-master;最直接的办法是看依赖树里com.facebook.react:react-native的实际版本。
4. 一条命令上模拟器:run-android 替你做了五件事
这一步解决"应用怎么跑起来",以及它跑起来时 CLI 背后到底执行了什么。
先打开一个 Android 模拟器。官方文档推荐 Genymotion,理由是启动快、支持快照,适合反复"安装—启动"的调试循环;不过它对adb来说和普通 AVD 没有区别(adb devices都能列出来),用标准 AVD 同样走得通。
然后进入工程目录执行:
cd ProjectName react-native run-androidrun-android命令注册在 local-cli/runAndroid/runAndroid.js 中,从源码看它依次做了五件事:
- 工程体检:
checkAndroid检查android/gradlew是否存在,不存在直接提示 "Android project not found"; - Packager 检查:
isPackagerRunning(args.port)探测 8081 端口(默认来自RCT_METRO_PORT || 8081),没跑就用startServerInNewWindow另开窗口拉起 JS 服务; - 构建安装:切到工程
android/目录执行./gradlew installDebug(Windows 下是gradlew.bat),依赖解析在此命中你发布的1000.0.0-master本地 AAR; - 端口反代:对每台已连接设备执行
adb reverse tcp:8081 tcp:8081,把设备内的 8081 映射回宿主机,应用靠它从本机 Packager 拉 JS bundle; - 拉起 Activity:
adb shell am start -n <package>/<package>.MainActivity。
多设备或自定义工程时常用的参数(同样定义在该文件底部):
| 参数 | 用途 | 什么时候用 |
|---|---|---|
--deviceId <id> | 指定某台设备(adb devices可查) | 多设备/多模拟器并存 |
--variant <name> | 指定构建变体 | 工程有 flavor 划分 |
--appFolder <name> | Android 源码目录名,默认app | 目录结构非默认 |
--appId/--appIdSuffix | 指定要启动的 applicationId | 多应用 ID 的 flavor |
--main-activity <name> | 指定启动 Activity,默认MainActivity | 入口不是 MainActivity |
--no-packager | 不自动拉起 Packager | 服务已在别处运行 |
--port <n> | Packager 端口,默认 8081 | 端口被占用 |
验证方式:命令顺利跑完后,模拟器上应能看到应用界面并渲染出 JS 内容,而不是白屏或 "Unable to load script" 提示。
5. 崩了就分层定位:adb logcat 看日志
这一步解决"应用没起来,第一步查什么"。
标准动作就一条命令:
adb logcat然后在输出里找 Java 异常。结合第 4 步的执行链,失败通常落在三层之一,症状和排查位置完全不同:
| 故障层 | 典型症状 | 去哪看 |
|---|---|---|
| 依赖解析失败 | installDebug阶段 Gradle 直接报缺依赖 | 构建期日志;android/目录是否为空、android-jsc 是否已发布 |
| JS bundle 加载失败 | 应用启动但白屏,提示连不上 dev server | 宿主机 8081 是否可达、adb reverse是否生效 |
| Java/原生崩溃 | 日志出现FATAL EXCEPTION、AndroidRuntime | adb logcat中的堆栈,能看到崩溃的 Activity 或 Module |
两个提速技巧:
- 过滤关键字:
adb logcat | grep -i "ReactNative\|FATAL"; - 想要干净现场:先
adb logcat -c清空缓冲区,再复现崩溃,避免被历史日志淹没。
如果崩溃发生在 JNI 层,日志里还会出现ReactNativeJS或 so 库相关条目,那说明问题出在 native 实现而非 Java 侧。
🧪 不想手工验证?仓库自带两套自动化测试
手工流程验证的是"开发体验",而仓库同时提供了验证"源码正确性"的自动化手段,可以互相补充:
- 本地单元测试:scripts/run-android-local-unit-tests.sh,内部就是
buck fetch+buck test ReactAndroid/src/test/...; - 集成/instrumentation 测试:ContainerShip/scripts/run-android-ci-instrumentation-tests.js,逐个类执行并自动重试,规避用例抖动;
- 更省事的是 package.json 里的 npm scripts,基于 Docker 一键跑:
npm run test-android-unit、npm run test-android-instrumentation、npm run test-android-e2e。
测试套件跑通后,样本应用的渲染效果可以参考仓库中集成测试的参考截图:
两套手段的分工很清楚:buck/Docker 脚本盯构建与模块本身是否正确,本文的手工流程盯"一个新工程能不能顺利吃下你的改动"。
收尾速查:环节—动作—验证
| 环节 | 关键动作 | 验证方式 |
|---|---|---|
| 环境 | 执行android核对 SDK 23 / Build Tools 23.0.1 / Support Repository 17 | 三个组件均显示已安装 |
| 前置 | android-jsc 装入本地 Maven | 构建期不再报缺依赖 |
| 构建发布 | ./gradlew :ReactAndroid:installArchives | 根目录android/下出现 AAR 与 POM |
| 新工程 | react-native init+ 版本号或代理二选一 | Gradle 命中1000.0.0-master |
| 运行 | 模拟器 +react-native run-android | 应用加载 JS 并正常渲染 |
| 排障 | adb logcat找 Java 异常 | 按上表对号入座定位故障层 |
最后提醒:本文所有版本号(SDK 23、1000.0.0-master)与 CLI 行为均以本仓库代码为准。这是 react-native-macos 这个实验性 fork 继承自上游 React Native 的 Android 构建链路,若你手上的 SDK 或 CLI 版本更新,请以对应版本的构建日志为准。
【免费下载链接】react-native-macos[deprecated in favor of https://microsoft.github.io/react-native-windows/] React Native for macOS is an experimental fork for writing desktop apps using Cocoa项目地址: https://gitcode.com/gh_mirrors/re/react-native-macos
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考