前言
目前越來越多的APP并不是純?cè)鶤ndroid&IOS開發(fā),各大小公司也有嘗試混合開發(fā)。網(wǎng)上也有不少Android原生和React Native 混合開發(fā)環(huán)境搭建的文章,但是基本都是針對(duì)新開發(fā)項(xiàng)目的環(huán)境搭建,而如果是接手公司原來項(xiàng)目時(shí)并不太適用,接手舊項(xiàng)目問題會(huì)多很多。所以這篇文章主要是針對(duì)接手公司舊的混合項(xiàng)目的環(huán)境搭建。
1. 基礎(chǔ)環(huán)境搭建
不管是新開發(fā)還是接手舊的混合項(xiàng)目,都需要搭建Android 和 React Native 等最基本的運(yùn)行環(huán)境和開發(fā)環(huán)境,下文使用的命令和截圖為 windows 環(huán)境,如果是 mac 環(huán)境,查找對(duì)應(yīng)的命令即可。
1.1 React Native的環(huán)境搭建
React Native 的環(huán)境搭建需要安裝 **Python 、Node.js **。直接去官網(wǎng)下載安裝包跟著步驟走就可以了,很容易安裝。暫時(shí)先不用安裝React Native的相關(guān)插件。注意一點(diǎn)就是看看舊項(xiàng)目的 Python 、Node.js環(huán)境版本,如果無法得知就選擇比較接近時(shí)間的版本安裝。最好不要使用最新的版本,避免環(huán)境沖突產(chǎn)生的問題。由于React Native的支持問題, Python 的版本必須為 2.x(不支持 3.x)。
1.2 Android 的環(huán)境搭建
最好是使用 Android Studio 作為 Android 部分的開發(fā)工具,并且安裝好對(duì)應(yīng)的Android SDK 、JDK環(huán)境,并配置相應(yīng)的環(huán)境變量,這些網(wǎng)上都有很詳細(xì)的教程。這些如果是Android開發(fā)的話,估計(jì)是已經(jīng)搭建好了的。JDK 的版本最好是 1.8(目前不支持 1.9 及更高版本)。
1.3 WebStorm 的安裝
筆者比較推薦使用 WebStorm 作為 React Native 部分的開發(fā)工具,WebStorm 是 JetJBrains 公司旗下一款JavaScript 開發(fā)工具,安裝 React Native 指定版本的工具庫的時(shí)候非常方便。
2. 接入項(xiàng)目
從 Git 或者其他方式獲取到工程項(xiàng)目的源代碼以及配置文件。
2.1 檢查工程目錄
因?yàn)榭赡芙邮值囊恍╅_發(fā)者可能只做過原生的開發(fā),并不了解React Native 的開發(fā) 。所以先要弄清楚混合開發(fā)的工程目錄結(jié)構(gòu)。最基本的工程目錄應(yīng)該如下圖所示:

- 這個(gè)工程目錄就是React Native 的工程目錄,Android 原生部分的工程目錄被包含在其中。
- 從上圖可以看到 android 和 ios 文件夾,這兩個(gè)文件夾分別對(duì)應(yīng)的是 Android 和 IOS 部分原生的工程。這兩個(gè)文件夾有可能是空的,如果是空的,需要在這個(gè)文件夾中導(dǎo)入正確的 android 部分項(xiàng)目工程文件。如果是 Git 設(shè)置了關(guān)聯(lián)庫的話可能是有正確的 Android 或 IOS 工程文件的,所以要注意檢查一下這兩個(gè)文件夾。
- 而 src 文件夾則對(duì)應(yīng)的是 React Native 部分的工程源碼。
- 還有需要注意的是 package.json 這個(gè)文件,這是一個(gè)很重要的文件,文件中定義了這個(gè)項(xiàng)目所需要的各種模塊,以及項(xiàng)目的配置信息。
2.2 使用 WebStorm 打開工程目錄
使用 WebStorm 打開這個(gè)工程目錄,然后打開 package.json 這個(gè)文件,WebStorm 是比較智能的,他會(huì)檢測(cè)當(dāng)前打開工程的 package.json 文件,會(huì)并提示 Install Dependencies,是否按照文件配置按照指定版本的工具庫以及React Native 等,如下圖所示。

接下來只需要按照提示,點(diǎn)擊 Run 'npm install' 就可以完成 React Native 和一些工程中需要的依賴的安裝。所以請(qǐng)確保 package.json 這個(gè)文件內(nèi)容是正確的。
- 注意,如果提示命令不存在,則需要安裝命令行工具(react-native-cli )。React Native 的命令行工具用于執(zhí)行創(chuàng)建、初始化、更新項(xiàng)目、運(yùn)行打包服務(wù)(packager)等任務(wù)。運(yùn)行命令如下即可。
npm install -g react-native-cli
- 使用原來工程正確 package.json 文件,可以保證使用的是和當(dāng)時(shí)開發(fā)一致的環(huán)境。這樣可以避免產(chǎn)生很多問題。
- 安裝完成后,React Native 工程目錄下會(huì)多出一個(gè) node_modules 的文件夾,我們安裝的react native和react等都在這目錄下,這樣 React Native 需要的環(huán)境就搭建完成了。
- 使用如下命令,來查看當(dāng)前的react-native版本是否正確。
react-native -v

- 也可以手動(dòng)運(yùn)行 npm install 來進(jìn)行安裝環(huán)境,但是這樣容易出現(xiàn)錯(cuò)誤或者忽略一些庫,不推薦。
- 當(dāng)環(huán)境安裝完后,或者降低 React Native 版本后,一些網(wǎng)上文章可能會(huì)推薦使用 react-native upgrade 這個(gè)命令,這里需要強(qiáng)調(diào)一下,這個(gè)命令可能會(huì)生成一些文件到 android 和 ios 這兩個(gè)文件夾里,導(dǎo)致覆蓋原有正確的 android 或者 ios 工程文件。


請(qǐng)謹(jǐn)慎使用 react-native upgrade 命令。
2.3 使用 Android Studio 打開 Android 原生部分工程
使用 Android Studio 打開 React Native 項(xiàng)目下的 android 文件夾,如果 android 是空的,就需要獲取 Android 原生相關(guān)的工程文件,使用 git 拉取和直接 copy 都可以,注意git 拉取的時(shí)候分支較多的時(shí)候,不要拉錯(cuò)分支,避免粗心所帶來的各種問題。

-
用 Android Studio 打開這個(gè)工程,如下所示。
打開這個(gè)android部分工程.png 執(zhí)行 run 命令之前要先按照 2.4 步驟將React Native 部分的資源打包到 Android 部分。然后通過在 WebStorm 命令行中執(zhí)行一次 run,看看有什么問題,執(zhí)行該 run 命令需要打開android設(shè)備,模擬器設(shè)備和真機(jī)都可以。
react-native run-android
- 用 Android Studio 打開后可能會(huì)有各種各樣的錯(cuò)誤,很多時(shí)候是一些配置和構(gòu)建工具版本問題導(dǎo)致的,因?yàn)槊總€(gè)人遇到問題不一樣,這里先不貼出錯(cuò)誤和解決方法,最后會(huì)給出一些筆者遇到的問題和解決。
- 有些問題是過時(shí)和兼容性問題,雖然會(huì)提示警告,但是其實(shí)也可以正常編譯打包。
2.4 打包 React Native 部分到 Android 原生工程
混合工程的原生部分打包(比如debug包)可能需要使用命令將 React Native 部分資源打包到 Android 原生工程里,注意這里打包的是 React Native 部分資源。
- 打開一個(gè) cmd ,然后進(jìn)入到項(xiàng)目根目錄,運(yùn)行命令:
react-native start
- 新打開一個(gè) cmd,然后在項(xiàng)目根目錄運(yùn)行下面命令 (其實(shí)不用進(jìn)入android目錄)
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
--platform android:代表打包導(dǎo)出的平臺(tái)為Android;
--dev false:代表關(guān)閉JS的開發(fā)者模式;
--entry-file index.js:代表js的入口文件為index.js;
--bundle-output:后面跟的是打包后將JS bundle包導(dǎo)出到的位置;
--assets-dest:后面跟的是打包后的一些資源文件導(dǎo)出到的位置

- 打包完成后,會(huì)生成 index.android.bundle 文件 和一些 res 文件。
- 如果打包失敗,請(qǐng)先檢查環(huán)境是否搭建完全,當(dāng)前版本是否有沖突,還有就是檢查 React Native 代碼是否有正確,(當(dāng)項(xiàng)目多時(shí),不要引用錯(cuò)了版本)。
- 打包完成后,在 Android Studio 運(yùn)行 ,debug 包 React Native 部分圖片可能不顯示。
到這里項(xiàng)目基本就接入完成了,主要是可能會(huì)發(fā)生很多的錯(cuò)誤,筆者就遇到很多的錯(cuò)誤,最后會(huì)給出常見和疑難問題以及解決辦法。
3 打包
3.1 打 debug 包
打 debug 的包,直接在Android Studio 點(diǎn)擊倒三角圖標(biāo)運(yùn)行,或者使用命令打 debug 包,和平時(shí)調(diào)試差不多。
打 debug 的包可能會(huì)提示
The option 'android.enableAapt2' is deprecated and should not be used anymore.
Use 'android.enableAapt2=true' to remove this warning.
It will be removed at the end of 2018..
遇到這個(gè)問題 gredle.properties 里把 android.enableAapt2=false 暫時(shí)注釋
筆者 使用的 build:gradle:3.2.0 已被棄用 aapt2 。所以會(huì)提示這個(gè)問題。
為什么暫時(shí)注釋,后面會(huì)給出解釋。
3.2 打 release 包
打 release 生成 apk 文件?;竞驮_發(fā)打包一樣的步驟。
- 檢查舊項(xiàng)目的簽名等文件,是否存在,是否放在正確的位置,buildTypes 里面配置是否正確。signingConfigs簽名配置是否正確。
- 一般使用命令來打包正式包
gradle assembleRelease
- 打包 release 版本的時(shí)候,其實(shí)會(huì)自動(dòng)幫我們生成 React Native 部分資源。


到此可以成功打出 debug 和 release 包的話,混合的環(huán)境基本就搭建完畢了,其他的環(huán)境包看個(gè)人需求。
4 常見的錯(cuò)誤
4.1 工程不正確造成的錯(cuò)誤
Could not read script 'D:\work\node_modules\react-native\react.gradle' as it does not exist.
JS server already running.
Building and installing the app on the device (cd android && gradlew.bat installDebug)...
錯(cuò)誤: 找不到或無法加載主類 org.gradle.wrapper.GradleWrapperMain
Could not install the app on the device, read the error above for details.
Make sure you have an Android emulator running or a device connected and have
set up your Android development environment:
https://facebook.github.io/react-native/docs/getting-started.html
這類錯(cuò)誤很可能是工程文件不全和工程文件不對(duì)造成的,雖然可以通過拷貝其他項(xiàng)目 gradlewarpper 來解決,但是可能會(huì)產(chǎn)生其他更多的錯(cuò)誤,請(qǐng)仔細(xì)檢查工程版本和完整性。
4.2 上文提到的 react-native upgrade 命令導(dǎo)致的 style 和 String 文件覆蓋的問題


請(qǐng)謹(jǐn)慎使用 react-native upgrade 命令,因?yàn)樗赡軙?huì)覆蓋你的 Android 原生部分的某些文件。
4.3 operation not permitted 以及 Failed to create 權(quán)限的問題
operation not permitted, lstat 'D:\work\example\android\app\build\intermedi.
\app\build\intermediates\incremental\packageDebug\tmp\debug\zip-cache
Failed to create directory 'D:\work\example\android\faceid\build\intermediates\manifests\full\release'
使用 Android Studio 點(diǎn)擊 Build 選項(xiàng) Clean Project 然后 Rebuild Project ,或者點(diǎn)擊 File 選項(xiàng) Invalidate Caches / Restart ... 基本可以解決這類問題。
4.4 React Native 部分打包失敗的問題

這個(gè)根據(jù)具體提示來判斷分析是什么問題產(chǎn)生的,比如這里是 could not be found from ... XXX.js ,none of these files exits ;,檢查這個(gè)js文件是否存在,如果不存在就說明工程可能存在問題,檢查工程引用是否正確和完整。
4.5 Unable to resolve dependency for 錯(cuò)誤

Unable to resolve dependency for ':app@mock/compileClasspath': Could not resolve project :react-native-code-push.
Unable to resolve dependency for ':app@exp/compileClasspath': Could not resolve project :react-native-i18n.
這個(gè)錯(cuò)誤比較讓人頭疼,可能是不同的原因產(chǎn)生的。
1.檢查工具庫是否存在node_modules目錄下,不存在就安裝這些庫,一般來說使用 WebStorm 的話都會(huì)有安裝
2.檢查工具庫是否 link 正確 ,一般來說是自動(dòng) link 的。
3.檢查是否使用了代理,加入google() 等配置。
4.如果以上3步都沒出現(xiàn)問題,那么查看你的 buildTypes 設(shè)置的 mock 、exp 等環(huán)境是否配置正確,如果不行就注釋掉這些報(bào)錯(cuò)的環(huán)境配置避免多余的干擾。如果不想注釋將 app 的 build.gradle 文件,將其中的 buildTypes {} 節(jié)點(diǎn)完整的拷貝到你的module庫的 build.gradle 文件中即可,節(jié)點(diǎn)具體內(nèi)容可以為空,但是節(jié)點(diǎn)名字要相同,保證其一致。

4.6 The version qualifier may be implied 問題
打包的時(shí)候,報(bào)如下錯(cuò)誤:
/android/app/build/intermediates/res/merged/release/drawable-mdpi/ic_launcher.png: Original is here. The version qualifier may be implied.
打開到 android 原生部分 找到 res/drawable目錄 這些報(bào)錯(cuò)的在2.4中打包 React Native 資源的時(shí)候會(huì)生成的 res 部分。
把這些生成的 drawable 文件夾刪除掉,就不會(huì)報(bào)錯(cuò)了。

刪除的時(shí)候注意看一下,不要?jiǎng)h除掉自己需要的 drawable ,點(diǎn)擊進(jìn)去看看哪些 drawable 里面有React Native 生成的圖片確認(rèn)一下這個(gè)文件夾是否是React Native 生成的,是的話就需要?jiǎng)h除。
4.7 error: uncompiled PNG 問題
ailed to generate apk due to error “error: uncompiled PNG file passed as argument. Must be compiled first into .flat file..”
error: uncompiled PNG

解決辦法: 在 gredle.properties 里使用
android.enableAapt2=false
但是你會(huì)發(fā)現(xiàn),Android Studio提示如下:

英文描述 在2018年底 android.enableAapt2=false 配置項(xiàng)將會(huì)失效。Android Studio 3.X 就會(huì)產(chǎn)生提示,所以 雖然已經(jīng) is deprecated 但是還是得使用,在打 debug 包的時(shí)候可能會(huì)報(bào)錯(cuò),所以只能暫時(shí)注釋掉,使用命令打 release 包的時(shí)候不會(huì)報(bào)錯(cuò),目前最方便辦法解決png錯(cuò)誤。因?yàn)楣P者項(xiàng)目 React Native 版本為 0.55.4,嘗試過非常多網(wǎng)上的辦法基本沒法解決這個(gè)問題。
其中有一種辦法是在 defaultConfig { 中添加:
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
雖然實(shí)測(cè)可以打包成功,但是運(yùn)行會(huì)產(chǎn)生崩潰錯(cuò)誤。

所以設(shè)置 aaptOptions 這個(gè)辦法是不可行的。在不改變 React Native 版本的情況下還是得使用 android.enableAapt2=false 才可以解決這個(gè)問題,或者提升 React Native 版本,但是這樣可能帶來更多的兼容性問題。
5 總結(jié)
接手舊的項(xiàng)目真的會(huì)有很多問題,解決起來也很讓人頭疼,需要更多的耐心來分析這些問題,特別要注意如下幾點(diǎn)。
