原生Android應(yīng)用中內(nèi)嵌RN
環(huán)境以及版本:
python v2.7.13 x64 |
node v6.10.3 |
npm v3.10.10 |
Android Studio v2.2.2 |
React v15.4.1 |
React-Native v0.39.2 |
Android-SDK 23
1.用AS新建原生Android空項(xiàng)目
-
如圖:
-
創(chuàng)建完成后的文件目錄結(jié)構(gòu)如下:
2.使用npm在原生android根目錄下初始化項(xiàng)目
$ npm init
-
如圖(注:name必須為全小寫(xiě)):
修改package.json文件(這里之所以限定版本是因?yàn)椴煌姹局g可能會(huì)用兼容問(wèn)題拍皮。在實(shí)際開(kāi)發(fā)中發(fā)現(xiàn)"react": "15.4.1"與"react-native": "0.39.2"可以兼容)
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
}
"dependencies": {
"react": "15.4.1",
"react-native": "0.39.2"
}
-
修改后如下
3.使用npm安裝
$ npm install
安裝過(guò)程中的報(bào)錯(cuò)信息饿幅,例如require react@某.某.某版本, but none was installed 說(shuō)明react 和 react-native的版本不兼容需更換版本(測(cè)試中react 15.4.1 和react-native 0.39.2是兼容的)
-
出現(xiàn)以下情況說(shuō)明下載成功,項(xiàng)目下會(huì)多一個(gè)node_modules里面就是react 和rn相關(guān)
4.新建.flowconfig
文件
在項(xiàng)目根目錄下新建
.flowconfig
文件
-
.flowconfig
文件內(nèi)容為:
[ignore]
; We fork some components by platform
.*/*[.]android.js
; Ignore templates for 'react-native init'
.*/local-cli/templates/.*
; Ignore the website subdir
<PROJECT_ROOT>/website/.*
; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/
; Ignore unexpected extra "@providesModule"
.*/node_modules/.*/node_modules/fbjs/.*
; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
.*/Libraries/react-native/React.js
.*/Libraries/react-native/ReactNative.js
[include]
[libs]
Libraries/react-native/react-native-interface.js
flow/
[options]
emoji=true
module.system=haste
experimental.strict_type_args=true
munge_underscores=true
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-5]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-5]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
unsafe.enable_getters_and_setters=true
[version]
^0.45.0
5.項(xiàng)目根目錄下新建 index.android.js
'use strict';
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
class HelloWorld extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.hello}>Hello, World</Text>
</View>
)
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
hello: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
6.修改app中build.gradle
文件
-
文件位置
將app中
build.gradle
文件修改為:
配置文件中最大版本不能超過(guò)23最低不能低于16,添加以下信息到相應(yīng)位置.
7.為 React Native 添加一個(gè) maven 依賴(lài)的入口
allprojects {
repositories {
...
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
...
}
-
如下圖:
8.在新建的原生android項(xiàng)目中新建一個(gè)用于裝載RN的activity
- activity內(nèi)容如下:
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.KeyEvent;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
/**
* Created by jianghe on 2017/5/11.
*/
public class MyReactActivity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")//制定ReactInstanceManager對(duì)應(yīng)的js文件
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
// 注意這里的HelloWorld必須對(duì)應(yīng)“index.android.js”中的
// “AppRegistry.registerComponent()”的第一個(gè)參數(shù)
mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorld", null);
setContentView(mReactRootView);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause(this);
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostDestroy();
}
}
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
}
9.修改android清單文件
-
如下圖:
10.啟動(dòng)rn服務(wù)
$ npm start
補(bǔ)充個(gè)打包命令(將rn打包為bundle文件放入assets資源文件夾下)
$ react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/
后續(xù)會(huì)補(bǔ)充android+RN增量熱更新以及預(yù)加載的文檔