編譯環(huán)境
官方的編譯環(huán)境要求如下,值得注意的是這里的NDK版本最好是r10e,親測過其他兩個版本的NDK并沒有成功,因此這里最好是下載r10e版本的NDK。
- Android SDK version 23 (編譯SDK版本號在build.gradle中可以找到)
- SDK build tools version 23.0.1(編譯工具版本號在build.gradle中可以找到)
- Android Support Repository >= 17
- Android NDK r10e下載地址
將Gradle指向你的安卓SDK: 設置$ANDROID_SDK和$ANDORID_NDK為對應的目錄,或者按照以下內容在react-native根目錄下創(chuàng)建local.properties文件(注意:windows下需要使用反雙斜杠)。
sdk.dir=指向android sdk目錄的絕對路徑
ndk.dir=指向android ndk目錄的絕對路徑
例如:
ndk.dir=D\:\\android-ndk-r10e
sdk.dir=C\:\\Users\\AppData\\Local\\Android\\Sdk
獲取源碼
按照官方給的下面命令獲取源碼,我試了運行失敗。
npm install --save github:facebook/react-native#master
其實當我們 react-native init [ProjectName] 的時候,工程node-modules/react-native/ReactAndroid的目錄就包含了源碼,因此我們可以直接讓我們的應用工程引用這一個源碼工程,因此這里我們直接運行一下命令初始化一個react native工程testapp。
react-native init testapp
添加gradle依賴
(1) 在生成的React Native工程中,將android/build.gradle文件中添加gradle-download-task依賴。
...
dependencies {
// gradle可以不替換,還是原來的版本
classpath 'com.android.tools.build:gradle:1.3.1'
classpath 'de.undercouch:gradle-download-task:3.1.2' //新增加的內容
// 注意:不要把你的應用的依賴放在這里;
// 它們應該放在各自模塊的build.gradle文件中
}
...
(2) 添加:ReactAndroid項目,在android/settings.gradle中添加:ReactAndroid項目。
...
//包含ReactAndroid工程
include ':ReactAndroid'
//指出ReactAndroid工程的地址
project(':ReactAndroid').projectDir = new File(rootProject.projectDir, '../node_modules/react-native/ReactAndroid')
...
(3) 修改你的android/app/build.gradle文件,使用:ReactAndroid替換預編譯庫。例如用compile project(':ReactAndroid'):替換compile 'com.facebook.react:react-native:+'
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1"
compile project(':ReactAndroid') //添加React-native項目
//compile "com.facebook.react:react-native:+" //注釋掉原來的react-native引用
}
(4) 讓第三方模塊使用你的分支
如果你使用第三方的React Native模塊,你需要重寫它們的依賴以避免它們仍然打包官方的預編譯庫。否則當你編譯時會報錯-Error: more than one library with package name 'com.facebook.react'.(錯誤:有幾個重名的'com.facebook.react'的包)
修改你的android/app/build.gradle文件,添加如下內容:
configurations.all {
exclude group: 'com.facebook.react', module: 'react-native'
}
編譯運行
在Android Studio歡迎頁中選擇Import project,隨后選擇應用所在的文件夾。
然后開始Run,這個過程需要下載200多M的文件然后才開始編譯,編譯快的可能幾分鐘,有時候甚至不一定成功。
在我編譯的時候查看Gradle Console的時候發(fā)現(xiàn)一直卡在downloadBoost這個task上,
:ReactAndroid:createNativeDepsDirectories UP-TO-DATE
:ReactAndroid:downloadBoost
Download http://mirror.nienbo.com/boost/boost_1_57_0.zip
查看ReactAndroid/build.gradle里面的內容可以看到這個任務(如下)下載的是C++的boost庫,文件大小接近105M,因此我們把 https://downloads.sourceforge.net/project/boost/boost/1.57.0/boost_1_57_0.zip 替換成 http://mirror.nienbo.com/boost/boost_1_57_0.zip 就會快很多?;蛘咧苯訌?官網(wǎng)地址 下載并復制到ReactAndroid工程的build/downloads目錄下,這樣就會直接跳過downloadBoost這個task,編譯速度就會快很多。
task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
src 'https://downloads.sourceforge.net/project/boost/boost/1.57.0/boost_1_57_0.zip'
onlyIfNewer true
overwrite false
dest new File(downloadsDir, 'boost_1_57_0.zip')
}
clean與build 問題
當我們成功編譯運行后,clean的時候會將我們之前下載的文件包括boost庫文件刪除掉,因此為了clean之后再次下載編譯so庫的問題,我們需要執(zhí)行以下三個步驟。
1.將ReactAndroid/build/react-ndk 文件夾移動到ReactAndroid項目下也就是ReactAndroid/react-ndk目錄下,這一個目錄是編譯生成的so文件。
2.將ReactAndroid/build.gradle里面的SourceSets.main里面的jniLibs.srcDir的目錄從"$buildDir/react-ndk/exported"改為"react-ndk/exported",這樣就編譯的時候就會去尋找ReactAndroid/react-ndk目錄的so文件。
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir "react-ndk/exported" //so庫目錄
res.srcDirs = ['src/main/res/devsupport', 'src/main/res/shell', 'src/main/res/views/modal']
java {
srcDirs = ['src/main/java', 'src/main/libraries/soloader/java', 'src/main/jni/first-party/fb/jni/java']
exclude 'com/facebook/react/processing'
exclude 'com/facebook/react/module/processing'
}
}
3.將ReactAndroid/build.gradle里面編譯so文件的task注釋掉,并將clean依賴于cleanReactNdkLib的task也注視掉,這樣clean的時候才不會出錯。
//注釋掉下面兩個任務
/* tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn packageReactNdkLibs //開始編譯前先進行ndk編譯
}
clean.dependsOn cleanReactNdkLib*/
這樣clean之后再次build就不會重新進行ndk編譯so文件,縮短編譯的時間。