经过测试,集成到原生的官方文档老旧存在很的bug,之后通过命令行创建完成项目研究其原生目录结构后总结出正确的集成RN已有原生app方法
命令行创建项目的方法可以参考官方文档,这里主要对集成rn到原生项目进行介绍
集成RN后的目录结构如图
1. 创建/修改 Android 项目
用 Android Studio 创建一个 Android 项目,注意
Minimum SDK 要设置为 API 16 或以上,因为 React Native 要求 Android 4.1 及以上的环境。
如果现有 Android 项目且 Minimum API 小于16则修改 Minimum SDK 到16,注意部分 API 变化。
app.gradle添加相关依赖,注意为了保证兼容性
appcompat最好保证23版本否则可能出错
2 设置项目目录结构
首先创建一个空目录用于存放React Native项目,然后在其中创建一个
/android
子目录,把你现有的Android项目拷贝到
/android
子目录中。
3 添加 package.json
{
"name"
:
"RnRnRn"
,
"version"
:
"0.0.1"
,
"private"
:
true
,
"scripts"
: {
"start"
:
"node node_modules/react-native/local-cli/cli.js start"
,
"test"
:
"jest"
},
"dependencies"
: {
"react"
:
"16.2.0"
,
"react-native"
:
"0.50.4"
},
"devDependencies"
: {
"babel-jest"
:
"21.2.0"
,
"babel-preset-react-native"
:
"4.0.0"
,
"jest"
:
"21.2.1"
,
"react-test-renderer"
:
"16.0.0"
},
"jest"
: {
"preset"
:
"react-native"
}
}
到当前根路径执行
执行
npm install 就可以安装
dependencies 下的 npm 组件了。
这个时候在
React Native 项目根目录就生成了
node_modules/ 文件夹,里面就是一些用到的组件。
4. 添加 index.android.js
在
React Native项目根目录创建目录
js/,js 相关的代码就放在这个文件夹下。
在
js/ 下添加
App.js,内容如下
import
React, { Component }
from
'react'
import
{ View, Text, StyleSheet }
from
'react-native'
export
default
class
extends
Component {
render() {
return
(
<View
style
=
{
styles.container
}
>
<Text
style
=
{
styles.text
}
>
Hello React Native!
</Text>
</View>
);
}
}
const
styles = StyleSheet.create({
container: {
flex:
1
,
justifyContent:
'center'
,
alignItems:
'center'
,
backgroundColor:
'#ffffff'
},
text: {
fontSize:
20
,
color:
'#333333'
}
})
在
React Native 项目根目录新建文件
index.android.js,(新版index.js可以不区分ios和Android)内容如下
import
{ AppRegistry }
from
'react-native'
import
App
from
'./js/App'
AppRegistry.registerComponent(
'navigation'
, ()
=>
App)
这里的
navigation 一般会根据模块功能命名,后面还会用到。
当然也可以把
App.js 的内容写在
index.android.js 里,但这样写更清晰一些,尤其是项目大了文件多的情况。
5. Android 项目添加依赖
Android 默认的依赖包的源
jcenter()
不包含最新版的 React Native,新版的 React Native 都只在 npm 里发布,因此要依赖
node_modules/
下的东西。
在 Android 项目根目录下的
build.gradle 文件添加如下内容
allprojects {
repositories {
google()
jcenter()
maven {
// All of React Native (JS, Android binaries) is installed from npm
url
"
$rootDir
/../node_modules/react-native/android"//一部分累是从该本地导入的
}
}
}
4.2 module 级别的 build.gradle
compile
"com.facebook.react:react-native:+"
//
一部分累是从这里导入
compile
"com.android.support:appcompat-v7:23.0.1"
6. React Native 相关的 Activity 和 Application
创建一个继承自
com.facebook.react.ReactActivity 的 Activity
public class
RNActivity
extends
ReactActivity{
@Override
protected
String getMainComponentName() {
return
"navigation"
;
}
}
重写 getMainComponentName() 方法,返回的字符串必须和前面的 AppRegistry.registerComponent('navigation', () => App) 里的 navigation 对应,表示该 Activity 会显示对应组件里的内容。
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
;
}
@Override
public void
onCreate() {
super
.onCreate();
SoLoader.
init
(
this
,
/* native exopackage */
false
);
}
}
权限
<
uses-permission
android
:name=
"android.permission.INTERNET"
/>
<
uses-permission
android
:name=
"android.permission.SYSTEM_ALERT_WINDOW"
/>
活动
<activity android:name=".自己创建的活动" />
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
android.permission.INTERNET 用于开发调试,
android.permission.SYSTEM_ALERT_WINDOW 用于显示悬浮窗。
当系统大于等于6.0时需要动态获取权限
* 获取悬浮窗权限,rn报错会以浮窗的形式弹出
*/
private void
initPermision() {
if
(Build.VERSION.
SDK_INT
>= Build.VERSION_CODES.
M
) {
if
(!Settings.
canDrawOverlays
(
this
)) {
Intent intent =
new
Intent(Settings.
ACTION_MANAGE_OVERLAY_PERMISSION
,
Uri.
parse
(
"package:"
+ getPackageName()));
startActivityForResult(intent,
0
);
}
}
}
@Override
protected void
onActivityResult(
int
requestCode,
int
resultCode, Intent data) {
if
(requestCode ==
0
) {
if
(Build.VERSION.
SDK_INT
>= Build.VERSION_CODES.
M
) {
if
(!Settings.
canDrawOverlays
(
this
)) {
// SYSTEM_ALERT_WINDOW permission not granted...
Toast.
makeText
(
this
,
"没有获取到权限"
, Toast.
LENGTH_SHORT
).show();
}
else
{
Toast.
makeText
(
this
,
"获取到权限"
, Toast.
LENGTH_SHORT
).show();
}
}
}
}
最好cd相关文件夹命令行运行即可,总之要根据命令行生成的项目来参考集成,官网目前介绍的方法还存在一些问题