ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

5 步把源码构建的 Android 库跑上模拟器:react-native-macos 从构建到排障的完整指南

5 步把源码构建的 Android 库跑上模拟器:react-native-macos 从构建到排障的完整指南

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编译期用的平台 APIReactAndroid/build.gradle 里写死compileSdkVersion 23
SDK Build Tools23.0.1aapt、dx 等构建工具链同文件里buildToolsVersion "23.0.1"
Android Support Repository17提供 Support Libraryinstrumentation 测试的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'

这条命令内部实际分两个阶段跑,理解这两阶段才能看懂报错出在哪:

  1. 编译阶段。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。
  2. 发布阶段。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 决定:

属性值含义
GROUPcom.facebook.react组织坐标
POM_ARTIFACT_IDreact-native构件名
VERSION_NAME1000.0.0-master版本号,刻意远高于 npm 上的 0.x
POM_PACKAGINGaar打包格式

验证方式:命令跑完后到仓库根目录的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 ProjectName

init生成的工程默认依赖 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-android

run-android命令注册在 local-cli/runAndroid/runAndroid.js 中,从源码看它依次做了五件事:

  1. 工程体检:checkAndroid检查android/gradlew是否存在,不存在直接提示 "Android project not found";
  2. Packager 检查:isPackagerRunning(args.port)探测 8081 端口(默认来自RCT_METRO_PORT || 8081),没跑就用startServerInNewWindow另开窗口拉起 JS 服务;
  3. 构建安装:切到工程android/目录执行./gradlew installDebug(Windows 下是gradlew.bat),依赖解析在此命中你发布的1000.0.0-master本地 AAR;
  4. 端口反代:对每台已连接设备执行adb reverse tcp:8081 tcp:8081,把设备内的 8081 映射回宿主机,应用靠它从本机 Packager 拉 JS bundle;
  5. 拉起 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、AndroidRuntimeadb 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),仅供参考

返回列表