编译环境
官方的编译环境要求如下,值得注意的是这里的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根目录下创建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的时候发现一直卡在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 就会快很多。或者直接从 官网地址 下载并复制到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库的问题,我们需要执行以下三个步骤。
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文件,缩短编译的时间。
网友评论