这篇文章记录我在 Windows 上为一套 React Native 0.87.1 项目搭建 Android 打包和真机调试环境的完整过程。
它不是简单的“安装 JDK、安装 Android Studio、执行命令”清单,而是一次真实排错记录。整个过程里,真正耗时间的并不是 React Native 代码,而是:
- JDK 版本和
Path优先级不一致。 - Android SDK、NDK、CMake 没有安装完整。
- Gradle 发行包下载缓慢。
- Maven Central 和 Google 仓库下载长时间卡住。
react-android调试包超过 280 MB,下载中途没有进度。- 一个终端窗口修改了环境变量,另一个已经打开的进程仍然使用旧环境。
- 长时间编译期间,真机 USB 连接断开。
如果你的开发环境在中国大陆,尤其是公司网络、代理不稳定或无法访问某些境外服务,本文中的处理思路应该能直接复用。
一、项目背景
本次项目的移动端技术栈如下:
| 组件 | 版本或要求 |
|---|---|
| React Native | 0.87.1 |
| React | 19.2.3 |
| Node.js | >= 22.11.0 |
| Android compileSdk | 37 |
| Android targetSdk | 36 |
| Android minSdk | 24 |
| Gradle | 9.4.1 |
| Kotlin | 2.2.0 |
| NDK | 27.1.12297006 |
| CMake | 3.22.1 |
| JDK | 17 |
项目已经提供了两个 PowerShell 脚本:
mobileapp/deploy/build-android.ps1
mobileapp/deploy/run-android.ps1
它们分别负责:
- Release/Debug APK 打包和归档。
- 真机连接、
adb reverse、启动 Metro、安装 Debug APK 并拉起应用。
所以这篇文章的目标不是重新发明脚本,而是把脚本背后的环境补齐,并解决实际执行过程中遇到的国内网络问题。
二、最终搭建出的环境
完成后,本机环境如下。
1. JDK
JDK 17
D:\tools\jdk-17.0.20.1
用户环境变量:
JAVA_HOME=D:\tools\jdk-17.0.20.1
为什么必须用 JDK 17:
- React Native 0.87 的 Android Gradle Plugin 和新版本 Kotlin 工具链不再适合 JDK 8。
- 如果
JAVA_HOME指向 JDK 8,可能在 Gradle 配置、Kotlin 编译或 AGP 初始化阶段出现一堆难以直接定位的异常。 - 只有安装了 JDK 17 还不够,已经打开的终端、VS Code 和 Codex 进程不一定会立即继承新的环境变量。
2. Android SDK
Android SDK
D:\Android\Sdk
安装的组件:
platform-tools
platforms;android-37.0
build-tools;37.0.0
build-tools;36.0.0
ndk;27.1.12297006
cmake;3.22.1
用户环境变量:
ANDROID_HOME=D:\Android\Sdk
ANDROID_SDK_ROOT=D:\Android\Sdk
用户 Path 中加入:
D:\Android\Sdk\cmdline-tools\latest\bin
D:\Android\Sdk\platform-tools
3. 项目本地配置
项目中的:
mobileapp/android/local.properties
内容为:
sdk.dir=D\:\\Android\\Sdk
这个文件保存的是当前电脑的 SDK 路径,不应该提交到 Git,一般也已经写入 .gitignore。
4. Gradle 和 Maven 下载源
Gradle Wrapper:
mobileapp/android/gradle/wrapper/gradle-wrapper.properties
改成腾讯镜像,并增加官方 SHA-256 校验:
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-9.4.1-bin.zip
distributionSha256Sum=2ab2958f2a1e51120c326cad6f385153bb11ee93b3c216c5fccebfdfbb7ec6cb
networkTimeout=60000
Maven 和 Google 依赖:
mobileapp/android/build.gradle
mobileapp/android/settings.gradle
增加阿里云镜像,并保留官方仓库作为兜底。
三、从零开始的搭建步骤
以下命令默认在 PowerShell 中执行。
1. 检查项目要求
先进入移动端目录:
cd D:\projects\xxxxxxxx\mobileapp
检查 Node.js:
node -v
npm -v
安装依赖:
npm install
运行项目自带的静态检查:
npx tsc --noEmit
npm test -- --runInBand
npm run lint
本次验证结果:
- TypeScript 类型检查通过。
- Jest:2 个测试套件、9 个测试全部通过。
- ESLint 通过。
2. 安装 JDK 17
安装完成后确认:
D:\tools\jdk-17.0.20.1\bin\java.exe -version
预期输出类似:
openjdk version "17.0.20.1" 2026-08-18 LTS
OpenJDK Runtime Environment Microsoft-14940689
OpenJDK 64-Bit Server VM Microsoft-14940689
设置用户级环境变量:
[Environment]::SetEnvironmentVariable(
'JAVA_HOME',
'D:\tools\jdk-17.0.20.1',
'User'
)
3. 安装 Android SDK 命令行工具
下载 commandlinetools 后解压到:
D:\Android\Sdk\cmdline-tools\latest
然后执行:
$env:JAVA_HOME = 'D:\tools\jdk-17.0.20.1'
$env:ANDROID_HOME = 'D:\Android\Sdk'
$env:ANDROID_SDK_ROOT = 'D:\Android\Sdk'
$env:Path = "$env:JAVA_HOME\bin;D:\Android\Sdk\cmdline-tools\latest\bin;D:\Android\Sdk\platform-tools;$env:Path"
sdkmanager.bat "platform-tools"
sdkmanager.bat "platforms;android-37.0"
sdkmanager.bat "build-tools;37.0.0"
sdkmanager.bat "build-tools;36.0.0"
sdkmanager.bat "ndk;27.1.12297006"
sdkmanager.bat "cmake;3.22.1"
接受 Android SDK License:
sdkmanager.bat --licenses
过程中会多次要求输入 y。
验证组件:
Get-ChildItem D:\Android\Sdk\platforms, D:\Android\Sdk\build-tools, D:\Android\Sdk\ndk, D:\Android\Sdk\cmake -Directory
4. 创建 local.properties
在:
D:\projects\aperbio-erp\mobileapp\android\local.properties
写入:
sdk.dir=D\:\\Android\\Sdk
Git Bash 或 PowerShell 中,反斜杠和冒号需要特别处理,所以使用 properties 文件时应写成这种转义形式。
5. 配置当前终端
注意:只有在当前终端已经继承了新环境变量时,下面的命令才可以省略。
如果 VS Code、Codex 或 PowerShell 是在修改环境变量之前打开的,需要手动注入:
$env:JAVA_HOME = 'D:\tools\jdk-17.0.20.1'
$env:ANDROID_HOME = 'D:\Android\Sdk'
$env:ANDROID_SDK_ROOT = 'D:\Android\Sdk'
$env:Path = "$env:JAVA_HOME\bin;D:\Android\Sdk\cmdline-tools\latest\bin;D:\Android\Sdk\platform-tools;$env:Path"
验证:
java -version
adb version
6. 构建 Release APK
cd D:\projects\aperbio-erp\mobileapp
.\deploy\build-android.ps1
本次首次成功构建耗时约 14 分钟,原因是需要完成:
- Gradle 插件解析。
- React Native Maven 依赖下载。
- Hermes 和原生依赖准备。
react-native-screens的 CMake 编译。- JS Bundle、资源和 APK 打包。
最终产物:
android/app/build/outputs/apk/release/app-release.apk
deploy/dist/aperbio-erp-release-arm64-v8a-v0.0.1-20260922-1755.apk
APK 大小约 23.3 MB。
用 aapt2 检查:
& 'D:\Android\Sdk\build-tools\37.0.0\aapt2.exe' dump badging `
'D:\projects\aperbio-erp\mobileapp\android\app\build\outputs\apk\release\app-release.apk'
关键结果:
package: name='com.aperbio.erp'
versionCode='1'
versionName='1.0'
compileSdkVersion='37'
minSdkVersion:'24'
targetSdkVersion:'36'
native-code: 'arm64-v8a'
7. 构建 Debug APK
既可以直接执行:
.\deploy\build-android.ps1 -Mode debug
也可以直接走真机调试脚本:
.\deploy\run-android.ps1
本次 Debug APK 也成功生成:
android/app/build/outputs/apk/debug/app-debug.apk
由于 Gradle 默认编译了全部 ABI,大小约 143 MB:
arm64-v8a
armeabi-v7a
x86
x86_64
如果只调试一款现代 Android 真机,可以手动指定:
.\android\gradlew.bat installDebug -PreactNativeArchitectures=arm64-v8a
这样能明显减少 CMake 编译和 APK 打包时间。
四、真机调试链路
run-android.ps1 的核心逻辑可以概括为:
检测设备
↓
adb reverse tcp:8081 手机 -> 电脑 Metro
adb reverse tcp:9090 手机 -> 电脑后端
↓
启动或复用 Metro
↓
Gradle installDebug
↓
adb shell am start
查看设备:
adb devices -l
必须看到状态为 device:
CIR4VOCIAYPROFAA device product:dali model:25060RK16C device:dali
如果显示:
unauthorized:手机没有确认 USB 调试授权。offline:USB 连接、驱动或 adb 状态异常。- 没有设备:数据线、驱动、开发者选项或 USB 模式有问题。
执行调试:
cd D:\projects\aperbio-erp\mobileapp
.\deploy\run-android.ps1
脚本会启动 Metro,然后编译并安装 Debug 包。安装完成后,手机端登录页的“服务器地址”可以填写:
http://127.0.0.1:9090
这里的 127.0.0.1 不是手机自身的后端,而是通过 adb reverse 转发到电脑上的后端服务。
如果 Debug APK 已经编译过,只是设备当时没连上,可以跳过 Gradle 编译:
.\deploy\run-android.ps1 -NoBuild
五、踩过的坑
这一部分是本文最重要的内容。
坑 1:修改了 JAVA_HOME,但已经打开的终端仍然使用 JDK 8
现象
用户环境变量已经改成 JDK 17,但在已经打开的 VS Code、PowerShell 或 Codex 终端中执行脚本时,仍然报 JDK 版本不正确。
原因
Windows 环境变量修改后:
- 新启动的终端会读取新值。
- 已经启动的进程不会自动更新。
- VS Code、Codex 等桌面应用还可能把自己启动时的环境变量传给所有子终端。
解决
两种方式任选:
- 关闭并重新打开 VS Code/Codex/终端。
- 在脚本执行前临时注入:
$env:JAVA_HOME = 'D:\tools\jdk-17.0.20.1'
$env:Path = "$env:JAVA_HOME\bin;$env:Path"
这也是为什么“环境变量已经改了,但打包仍然失败”的情况非常常见。
坑 2:JAVA_HOME 是 JDK 17,但命令行 java 还是 JDK 8
现象
echo $env:JAVA_HOME
# D:\tools\jdk-17.0.20.1
java -version
# 仍然显示 JDK 8
原因
JAVA_HOME 和 Path 是两套机制:
- Gradle 通常优先使用
JAVA_HOME。 - 直接执行
java时,使用Path中第一个java.exe。
如果原来的 JDK 8 路径排在 JDK 17 前面,java -version 仍然会显示 JDK 8。
解决
把 JDK 17 放到用户 Path 最前面:
$jdk17Bin = 'D:\tools\jdk-17.0.20.1\bin'
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
$entries = @($userPath -split ';' | Where-Object {
$_ -and $_.TrimEnd('\') -ne $jdk17Bin.TrimEnd('\')
})
$newPath = (@($jdk17Bin) + $entries) -join ';'
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
重新打开终端后再验证。
坑 3:只有 JDK,没有 Android SDK
现象
Gradle 报找不到 Android SDK,或者提示 SDK location not found。
React Native 工程的 Android 构建不仅需要 JDK,还需要:
platform-tools- 对应版本的 Android Platform
- Build Tools
- NDK
- CMake
解决
使用 sdkmanager 安装完整组件,并创建 android/local.properties。
不要只复制 Android Studio 或平台目录,版本不完整时问题通常会推迟到 CMake 或打包阶段才暴露。
坑 4:Gradle 发行包下载缓慢
现象
Gradle Wrapper 卡在:
Downloading https://services.gradle.org/distributions/gradle-9.4.1-bin.zip
长时间没有进度。
原因
官方地址可能重定向到 GitHub Releases。在国内网络环境下,首次下载很容易超时。
解决
使用腾讯 Gradle 镜像,并保留 SHA-256 校验:
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-9.4.1-bin.zip
distributionSha256Sum=2ab2958f2a1e51120c326cad6f385153bb11ee93b3c216c5fccebfdfbb7ec6cb
networkTimeout=60000
为什么要保留校验值:
- 镜像可以加速下载。
- 校验值用于确认下载内容和官方发行包一致。
- 不要因为使用了镜像就取消完整性校验。
坑 5:Gradle 已经启动,但 Maven 依赖下载彻底卡住
现象
Gradle 看起来没有退出,但也没有持续输出日志。
例如卡在:
> Task :app:processDebugNavigationResources
等待几分钟后没有任何变化。
排查一:查看下载临时文件大小
Gradle 正在下载时,会在类似目录下生成临时文件:
$env:USERPROFILE\.gradle\.tmp\gradle_download*.bin
连续观察文件大小:
Get-ChildItem "$env:USERPROFILE\.gradle\.tmp" -Force -File |
Sort-Object LastWriteTime -Descending |
Select-Object -First 10 LastWriteTime, Length, Name
如果三分钟以上完全不增长,基本可以判断不是“下载慢”,而是连接已经停滞。
排查二:看进程是否还在网络读取
Get-NetTCPConnection -State Established |
Where-Object { $_.OwningProcess -eq <GradleJavaPID> }
如果连接还在,但临时文件完全不变,通常是 SSL 连接卡住,并不代表 Gradle 在继续正常下载。
排查三:查看 Gradle Daemon 线程栈
使用 JDK 自带工具:
jcmd <GradleJavaPID> Thread.print
本次能看到线程停在:
DownloadAction.execute
AccessorBackedExternalResource
SocketInputStream.read
这说明进程不是死锁,而是网络读取长时间没有返回。
解决
不要一直等。停止当前构建:
Ctrl+C
如果出现:
Terminate batch job (Y/N)?
输入:
y
然后停止 Gradle Daemon:
cd D:\projects\aperbio-erp\mobileapp\android
.\gradlew.bat --stop
改成国内镜像后重新构建。
六、国内网络问题怎么解决
这部分单独展开,因为这次真正影响效率的主要就是网络。
方案 1:替换 Gradle 发行包下载源
Gradle Wrapper 官方地址:
https://services.gradle.org/distributions/
国内可改用:
https://mirrors.cloud.tencent.com/gradle/
原则:
- 使用国内镜像。
- 不取消校验。
- 配置合理的网络超时时间。
方案 2:给 Maven 和 Google 仓库配置国内镜像
React Native Android 构建会从 Maven Central 和 Google Maven 下载大量依赖。
仅修改 Gradle Wrapper 不够,因为 Wrapper 只是 Gradle 程序本身,Gradle 启动后还会继续解析依赖。
在根工程的 build.gradle 中同时配置 Buildscript 和普通模块依赖:
buildscript {
repositories {
// Prefer domestic mirrors; keep official repositories as fallback.
maven { url = uri("https://maven.aliyun.com/repository/google") }
maven { url = uri("https://maven.aliyun.com/repository/public") }
google()
mavenCentral()
}
}
allprojects {
repositories {
maven { url = uri("https://maven.aliyun.com/repository/google") }
maven { url = uri("https://maven.aliyun.com/repository/public") }
google()
mavenCentral()
}
}
在 settings.gradle 的 pluginManagement 中配置 Gradle 插件仓库:
pluginManagement {
repositories {
maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }
maven { url = uri("https://maven.aliyun.com/repository/google") }
maven { url = uri("https://maven.aliyun.com/repository/public") }
gradlePluginPortal()
google()
mavenCentral()
}
}
这个配置的策略是:
国内镜像优先
↓
官方仓库兜底
如果公司要求统一通过 Nexus、Artifactory 或内部代理,也可以把阿里云镜像替换成公司仓库地址。
方案 3:手动预热超大 AAR
React Native Android 有两个非常大的依赖包:
react-android-0.87.1-release.aar
react-android-0.87.1-debug.aar
本次遇到的情况:
- Release AAR 约 168,714,849 字节。
- Debug AAR 约 268.3 MiB,约 281 MB。
- 官方 Maven 下载时,Gradle 长时间没有输出进度。
- 连接保持 ESTABLISHED,但临时文件不再增长。
这时可以用阿里云镜像手动下载:
Release:
curl.exe -L --fail --retry 3 --connect-timeout 20 `
-o D:\Android\cache\react-android-0.87.1-release.aar `
https://maven.aliyun.com/repository/public/com/facebook/react/react-android/0.87.1/react-android-0.87.1-release.aar
Debug:
curl.exe -L --fail --retry 3 --connect-timeout 20 `
-o D:\Android\cache\react-android-0.87.1-debug.aar `
https://maven.aliyun.com/repository/public/com/facebook/react/react-android/0.87.1/react-android-0.87.1-debug.aar
官方元数据中的 SHA-1:
Release:
9f07d211baf332c0a3e33e437ea550f63500c7c2
Debug:
c13d025a8fa066c1efb181c7fd7249e201904e94
验证:
Get-FileHash -LiteralPath D:\Android\cache\react-android-0.87.1-debug.aar `
-Algorithm SHA1
确认 SHA-1 后,放入 Gradle 缓存目录:
$env:USERPROFILE\.gradle\caches\modules-2\files-2.1\com.facebook.react\react-android\0.87.1\<SHA1>\
例如:
C:\Users\<用户名>\.gradle\caches\modules-2\files-2.1\com.facebook.react\react-android\0.87.1\c13d025a8fa066c1efb181c7fd7249e201904e94\react-android-0.87.1-debug.aar
注意:
- 目录名是 SHA-1,不是版本号。
- 不要在 Gradle 正在下载同一个文件时直接覆盖,先停止 Gradle。
- 必须验证文件哈希,避免把损坏或错误的包放进缓存。
- 这种方法适合超大依赖、镜像也慢或官方源持续卡住的场景。
方案 4:优先通过命令行下载,而不是浏览器
在 Windows 技术博客和教程里,经常看到“浏览器下载后手动解压”。
实际搭建环境时,优先使用 curl.exe 或 PowerShell:
curl.exe -L --fail --retry 3 --connect-timeout 20 -o <目标文件> <URL>
优点:
- 能直接看到下载速度和百分比。
- 容易配置重试和连接超时。
- 可以配合
Get-FileHash验证文件。 - 更适合脚本化和后续复现。
方案 5:不要把所有问题都归因于“网络慢”
国内网络问题常见的表现不只有“慢”,还有:
- 下载连接建立成功,但完全不传输。
- DNS 能解析,但 TLS 握手一直不结束。
- 某个仓库可以访问,另一个仓库卡死。
- 浏览器能下载,但 Gradle 使用代理后不能。
所以建议按下面的顺序排查:
有没有日志?
↓
日志停在哪一步?
↓
临时文件有没有增长?
↓
网络连接是否存在?
↓
线程栈是否停在下载读取?
↓
确认停滞后,切镜像或手动预热缓存
七、其他非网络类踩坑
1. local.properties 不存在
React Native 工程使用 Gradle 构建时,如果没有:
mobileapp/android/local.properties
可能报 SDK 路径找不到。
当前项目使用的是:
sdk.dir=D\:\\Android\\Sdk
2. ANDROID_HOME 和 ANDROID_SDK_ROOT 同时配置
为了让不同工具兼容,两个变量都设置了:
ANDROID_HOME=D:\Android\Sdk
ANDROID_SDK_ROOT=D:\Android\Sdk
这不是严格必须,但在 Android 工具链混用时更稳妥。
3. CMake 的 Hard link 警告不是错误
构建时出现过:
Hard link from 'C:\Users\...\libreactnative.so' to 'D:\...\libreactnative.so' failed.
Doing a slower copy instead.
原因是 Gradle 缓存位于 C 盘,项目构建目录位于 D 盘,跨卷硬链接失败。
Gradle 会自动退化为复制文件:
Doing a slower copy instead
这是性能提示,不是构建失败。
4. 旧依赖的 namespace、Kotlin 和 API 弃用警告
构建日志里出现大量:
Setting the namespace via the package attribute in the source AndroidManifest.xml is no longer supported
以及:
This class is part of Legacy Architecture and will be removed in a future release
这些来自第三方 React Native 库和 AGP API 演进,只要没有出现 FAILED 或 BUILD FAILED,不影响本次 APK 生成。
以后升级 React Native 或对应第三方库时,可以逐步清理这些警告。
5. Debug 包比 Release 包大很多
Release 包本次约:
23.3 MB
Debug 包包含四种 ABI,约:
143 MB
原因:
- Release 使用
arm64-v8a单架构。 - Debug 默认编译
arm64-v8a、armeabi-v7a、x86、x86_64。 - Debug 包含更多符号和调试信息。
如果只为真机调试,最好指定目标 ABI。
6. 编译期间真机掉线
现象
debug 编译和 CMake 都完成,最后执行 installDebug 时却报:
com.android.builder.testing.api.DeviceException: No connected devices!
重新执行:
adb devices -l
结果为空。
原因
手机在约 10 分钟的构建过程中断开 USB,或者 USB 调试授权失效。
解决
重新插好手机,确保:
- 手机上显示“允许 USB 调试”。
adb devices -l状态为device。- 手机没有自动切换到只充电模式。
然后跳过已经完成的编译:
cd D:\projects\aperbio-erp\mobileapp
.\deploy\run-android.ps1 -NoBuild
7. Release 默认使用 Debug Keystore
本次 Release APK 能正常构建,但默认使用的是项目的 debug keystore。
这意味着:
- 适合内部测试。
- 不适合正式分发。
- 不能直接用于应用市场发布。
正式发布需要:
android/app/aperbio-release.keystore
android/keystore.properties
并重新执行 Release 构建。
8. Metro 和 Release 包的关系
这两个包的使用方式不同:
| 包类型 | 是否需要 Metro | 用途 |
|---|---|---|
| Release | 不需要 | 独立运行,内置 JS Bundle |
| Debug | 需要 | 开发、热重载、真机调试 |
Debug 包安装后,如果 Metro 没有运行,或者 adb reverse 没有配置,应用可能白屏或无法正常连接。
八、国内网络下的推荐配置模板
Gradle Wrapper
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-9.4.1-bin.zip
distributionSha256Sum=2ab2958f2a1e51120c326cad6f385153bb11ee93b3c216c5fccebfdfbb7ec6cb
networkTimeout=60000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Android 根工程仓库
buildscript {
repositories {
maven { url = uri("https://maven.aliyun.com/repository/google") }
maven { url = uri("https://maven.aliyun.com/repository/public") }
google()
mavenCentral()
}
}
allprojects {
repositories {
maven { url = uri("https://maven.aliyun.com/repository/google") }
maven { url = uri("https://maven.aliyun.com/repository/public") }
google()
mavenCentral()
}
}
插件仓库
pluginManagement {
repositories {
maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }
maven { url = uri("https://maven.aliyun.com/repository/google") }
maven { url = uri("https://maven.aliyun.com/repository/public") }
gradlePluginPortal()
google()
mavenCentral()
}
}
临时环境变量
$env:JAVA_HOME = 'D:\tools\jdk-17.0.20.1'
$env:ANDROID_HOME = 'D:\Android\Sdk'
$env:ANDROID_SDK_ROOT = 'D:\Android\Sdk'
$env:Path = "$env:JAVA_HOME\bin;D:\Android\Sdk\cmdline-tools\latest\bin;D:\Android\Sdk\platform-tools;$env:Path"
九、最终验证结果
本机实际运行结果如下。
静态检查
TypeScript:
通过
Jest:
2 suites passed
9 tests passed
ESLint:
通过
Release 构建
BUILD SUCCESSFUL
202 actionable tasks
约 14 分钟首次构建
产物:
D:\projects\aperbio-erp\mobileapp\deploy\dist\
aperbio-erp-release-arm64-v8a-v0.0.1-20260922-1755.apk
大小:
23.3 MB
APK 信息:
applicationId: com.aperbio.erp
versionCode: 1
versionName: 1.0
minSdkVersion: 24
targetSdkVersion: 36
native-code: arm64-v8a
Debug 构建
编译成功:
android/app/build/outputs/apk/debug/app-debug.apk
大小:
143.0 MB
包含:
arm64-v8a
armeabi-v7a
x86
x86_64
最后安装阶段因为手机 USB 掉线,出现:
No connected devices!
重新连接设备后,使用:
.\deploy\run-android.ps1 -NoBuild
即可直接安装已经编译好的 Debug APK。
十、从零复现命令清单
下面是压缩版流程,可以放在博客末尾或作为团队新人手册。
1. 设置环境
$env:JAVA_HOME = 'D:\tools\jdk-17.0.20.1'
$env:ANDROID_HOME = 'D:\Android\Sdk'
$env:ANDROID_SDK_ROOT = 'D:\Android\Sdk'
$env:Path = "$env:JAVA_HOME\bin;D:\Android\Sdk\cmdline-tools\latest\bin;D:\Android\Sdk\platform-tools;$env:Path"
2. 验证工具
java -version
adb version
sdkmanager.bat --list_installed
3. 安装项目依赖
cd D:\projects\aperbio-erp\mobileapp
npm install
4. 静态检查
npx tsc --noEmit
npm test -- --runInBand
npm run lint
5. 构建 Release
.\deploy\build-android.ps1
6. 编译 Debug
.\deploy\build-android.ps1 -Mode debug
只构建 ARM64:
cd android
.\gradlew.bat assembleDebug -PreactNativeArchitectures=arm64-v8a
7. 检查设备
adb devices -l
8. 真机调试
cd D:\projects\aperbio-erp\mobileapp
.\deploy\run-android.ps1
Debug 包已经存在、只需要重新安装时:
.\deploy\run-android.ps1 -NoBuild
9. Metro 已单独运行时
.\deploy\run-android.ps1 -NoMetro
10. 后端地址
真机使用 USB 调试时填写:
http://127.0.0.1:9090
并确保 run-android.ps1 已经执行:
adb reverse tcp:9090 tcp:9090
十一、经验总结
这次环境搭建给我的最大感受是:
React Native Android 构建的难点,很少是 React Native 本身,更多是本地工具链和依赖分发网络。
如果把整个过程抽象成一条链路:
JDK 17
↓
Android SDK / NDK / CMake
↓
Gradle Wrapper
↓
Maven / Google 依赖
↓
React Native AAR
↓
CMake / Kotlin / Java 编译
↓
APK 签名和打包
↓
adb 安装和 Metro 调试
任何一个环节卡住,最终表现都可能只是“构建失败”或“没有进度”。
国内环境下最有效的组合是:
- JDK 和 SDK 按版本一次装完整。
- Gradle Wrapper 换国内镜像并保留 SHA-256。
- Maven/Google 依赖优先走国内镜像,官方源兜底。
- 超大 AAR 用
curl.exe从镜像下载并校验 SHA-1。 - 构建出现长时间无进度时,先用临时文件和线程栈确认是否真的停住。
- 已打开终端修改环境变量后,显式注入当前进程或重启终端。
- Debug APK 编译成功后,设备掉线可以先用
-NoBuild完成安装验证。
把这些坑记录进项目文档,下一次换电脑、换同事或升级 React Native 版本时,就不需要重新踩一遍。