Windows 下搭建 React Native Android 打包与真机调试环境:一次国内网络环境的完整实践

这篇文章记录我在 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 Native0.87.1
React19.2.3
Node.js>= 22.11.0
Android compileSdk37
Android targetSdk36
Android minSdk24
Gradle9.4.1
Kotlin2.2.0
NDK27.1.12297006
CMake3.22.1
JDK17

项目已经提供了两个 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 等桌面应用还可能把自己启动时的环境变量传给所有子终端。

解决

两种方式任选:

  1. 关闭并重新打开 VS Code/Codex/终端。
  2. 在脚本执行前临时注入:
$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 调试

任何一个环节卡住,最终表现都可能只是“构建失败”或“没有进度”。

国内环境下最有效的组合是:

  1. JDK 和 SDK 按版本一次装完整。
  2. Gradle Wrapper 换国内镜像并保留 SHA-256。
  3. Maven/Google 依赖优先走国内镜像,官方源兜底。
  4. 超大 AAR 用 curl.exe 从镜像下载并校验 SHA-1。
  5. 构建出现长时间无进度时,先用临时文件和线程栈确认是否真的停住。
  6. 已打开终端修改环境变量后,显式注入当前进程或重启终端。
  7. Debug APK 编译成功后,设备掉线可以先用 -NoBuild 完成安装验证。

把这些坑记录进项目文档,下一次换电脑、换同事或升级 React Native 版本时,就不需要重新踩一遍。

发表评论