React Native的項目中分爲Android與IOS,但是若在現有的Android項目中,集成RN,不能按照那個包結構來,我們統一在app文件夾下處理。
一、集成步驟:
1.添加js文件
(1)在app文件夾下輸入命令 npm init,生成package.json文件。這裏會讓你輸入name等信息,除了name,其他可不輸入。打開package.json文件,在scripts節點下,添加如下代碼,注意逗號隔開"test"節點。
"start": "node node_modules/react-native/local-cli/cli.js start"
完整的package.json,我也貼出來:{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^16.2.0",
"react-native": "^0.52.1"
}
}
(2)安裝React 和React Native:app下繼續命令npm install --save react react-native
這裏需要一段時間,完成後,會在app目錄下生成一個node_modules文件夾。
(3)配置其他文件。
a:將RN HelloWorld項目中的.flowconfig文件和.watchmanconfig文件拷貝過來;
b:將RN HelloWorld項目中的index.js和App.js文件拷貝過來,並將index.js文件中註冊組件的名字與package.json中的名字一致(我使用的RN版本中已沒有index.android.js文件了)。
AppRegistry.registerComponent('app', () => App);
2.項目配置
(1)配置app下的build.gradle文件。
a:添加RN庫。
b:處理RN引用的so文件:RN中提供的libreactnativejni.so文件是32位,而Android項目中用了一些64位的so文件,導致不兼容。解決辦法就是禁止使用那些64位的so文件。
c:appcompat-v7版本爲23.0.1(只能使用該版本下的v7/v4包)。
貼下整個的配置:
android{
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
packagingOptions {
exclude "lib/arm64-v8a"
}
dependencies {
compile "com.facebook.react:react-native:+" // From node_modules.
compile 'com.android.support:appcompat-v7:23.0.1'
}
(2)項目的build.gradle中添加依賴
allprojects {
repositories {
google()
jcenter()
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/app/node_modules/react-native/android"
}
}
}
3.創建Activity
(1)創建MyRNActivity,繼承ReactActivity,重寫getMainComponentName()方法,返回值爲package.json中的name值。
(2)創建MyApplication,繼承Application,實現ReactApplication接口。
public class MyApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
}
(3)清單文件註冊Activity和Application,並添加網絡權限和DevSettingsActivity。至此,集成結束。貼下集成的目錄:
二、運行
先在app目錄下,啓動node.js。再運行Android項目就可以了。
npm start
三、異常
(1)v4/v7包版本不對,只能使用23.0.1版本構建。如果你用的是自己已發佈的項目,要注意引用庫中v4/v7包的版本,必要的時候,將引用庫中的v4/v7包排除掉。
IllegalAccessError: Method 'void android.support.v4.net.ConnectivityManagerCompat.<init>()
(2)so文件不統一。可以排除掉64位的so文件,具體配置見第二節。
java.lang.UnsatisfiedLinkError: could find DSO to load: libreactnativejni.so
(3)缺失index.android.bundle文件。
Got JS Exception: ReferenceError: Can't find variable: __fbBatchedBridge
--> Unable to load script from assets: index.android.bundle
解決辦法:手動添加assets目錄,創建index.android.bundle文件,使用命令打包js到該文件中。 react-native bundle --entry-file index.js --bundle-output ./src/main/assets/index.android.bundle --platform android --assets-dest ./src/main/res/ --dev false
(4)ReactNativeJS報錯
ReactNativeJS: undefined is not a function (evaluating '(d.remoteModuleConfig||[]).forEach(function(e,n){var t=u(e,n);t&&(t.module?v[t.name]=t.module:h(v,t.name,{get:function(){return l(t.name,n)}}))})')
原因:項目下的build.gradle文件,引用node_modules路徑錯誤,正確的如下:maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/app/node_modules/react-native/android"
}
(5)Cannot find entry file index.android.js in any of the roots。找不到index.android.js文件。查看官網的issue,找到了解決方案:複製index.js文件,命名爲index.android.js即可。 鏈接地址:https://github.com/facebook/react-native/issues/18217