点我
这种将在已有Android 项目中集成React-Native 项目,是在原来Android项目中添加 RN项目,不会修改 Android项目的外层结构。大概结果如下:
新建一个Android 项目“Android_With_RN"
进入到 ”Android_With_RN“ 项目的根目录,Terminal窗口,输入
npm init
然后可以看到会生成 package.json 的文件,填写一些配置信息,中间需要输入包名,其他默认就好
//init命令提示输入的信息
name: Android_With_RN
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
//package.json
{
"name": "Android_With_RN",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author":,
"license": "ISC"
}
添加启动脚本到 package.json 中, 注意脚本路径与实际目录是否一致。
"start": "node node_modules/react-native/local-cli/cli.js start"
最后package.json 内容为
package.json
{
"name": "android_with_rn",
"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.8.6",
"react-native": "^0.59.5"
}
}
npm install --save react react-native
如看到这个 ”npm WARN [email protected] requires a peer of [email protected] but none is installed. You must install peer dependencies yourself. “
需要手动安装对应的 react 16.8.3版本
npm i -s [email protected]
在项目的跟目录创建”.flowconfig"文件,文件内容可以从 FaceBook的GitHub上下载, 地址,把内容copy进去即可
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
...
// From node_modules.
api "com.facebook.react:react-native:+"
}
为了防止个别机型.so库和findbugsbug问题,建议在app/build.gradle中增加下面的代码:
android {
defaultConfig {
ndk {
//选择要添加的对应cpu类型的.so库。
abiFilters 'armeabi', "armeabi-v7a","armeabi-v7a","x86"
}
}
//...
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.0'
}
}
这里注意maven官网写的是路径是:url “ r o o t D i r / . . / n o d e m o d u l e s / r e a c t − n a t i v e / a n d r o i d " , 这 个 是 因 为 官 方 的 A n d r o i d 项 目 是 放 在 a n d r o i d / 目 录 下 , 而 我 们 是 放 在 项 目 的 跟 目 录 下 , 所 以 路 径 变 为 " u r l " rootDir/../node_modules/react-native/android",这个是因为官方的Android项目是放在 android/ 目录下,而我们是放在项目的跟目录下,所以路径变为" url " rootDir/../nodemodules/react−native/android",这个是因为官方的Android项目是放在android/目录下,而我们是放在项目的跟目录下,所以路径变为"url"rootDir/node_modules/react-native/android” "
allprojects {
repositories {
maven {
url "$rootDir/node_modules/react-native/android"
}
jcenter()
}
}
在根目录添加 index.js 文件,这个文件是React-Native的入口文件
index.js
import React from 'react';
import {AppRegistry, StyleSheet, Text, View} from 'react-native';
class HelloWorld extends React.Component {
render() {
return (
RN 项目
);
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
hello: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
AppRegistry.registerComponent('Android_With_RN', () => HelloWorld);
AndroidManifest.xml
-这个权限是用调试的,debug模式需要悬浮窗权限
public class MainActivity extends AppCompatActivity {
static final int OVERLAY_PERMISSION_REQ_CODE = 1000;
private AppCompatButton mBtnRn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initEvent();
}
private void initEvent() {
initView();
checkAppPermission();
}
@SuppressLint("WrongViewCast")
private void initView() {
mBtnRn = findViewById(R.id.btn_rn);
mBtnRn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//跳转RN页面
startActivity(new Intent(MainActivity.this, BaseRnActivity.class));
}
});
}
private void checkAppPermission() {
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, OVERLAY_PERMISSION_REQ_CODE);
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
//SYSTEM_ALERT_WINDOW被拒绝
}
}
}
}
}
新版的RN,0.55以后版本,我们不需要实现DefaultHardwareBackBtnHandler接口,直接继承ReactActivity,实现getMainComponentName()方法,在该方法中返回一开始我们注册的ReactNative的名称(Android_With_RN)即可,在ReactActivity中,已经帮我们实现了ReactRoot与ReactInstanceManager的配置,在之前的版本中,ReactRoot 与ReactInstanceManager需要我们自己去写。
public class BaseRnActivity extends ReactActivity {
@Nullable
@Override
protected String getMainComponentName() {
return "Android_With_RN";
}
}
我们需要在AndroidManifest.xml 把 MyReactActivity 的主题设定为 Theme.AppCompat.Light.NoActionBar ,因为里面有许多组件都使用了这一主题。
接下来创建一个MyApplication,并初始化一个ReactNativeHost,该MyApplication继承Application并实现ReactApplication,在源码loadApp方法时,会将当前的Activity的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 getPackages() {
return Arrays.asList(
new MainReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
}
在AndroidManifest 配置MainApplication,不然会报错,java.lang.ClassCastException:
android.app.Application cannot be cast to
com.facebook.react.ReactApplication
在原生添加一个按钮,点击按钮从原生(MainActitivy)跳转到RN(BaseRnActivity ),修改layout布局,activity_main.xml
跳转实现
startActivity(new Intent(MainActivity.this, BaseRnActivity.class));
你也可以使用 Android Studio 来打 release 包!其步骤基本和原生应用一样,只是在每次编译之前需要先执行 js 文件的打包(即生成离线的 jsbundle 文件)。具体的 js 打包命令如下:
注意:bundle文件路径,把上述命令中的路径替换为你实际项目的路径。如果 assets 目录不存在,则需要手动的在app/src/main/目录中添加一个assets目录。
react-native bundle --platform android --dev false --entry-file index.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/
–platform : 平台(android/ios)
–dev : 开发模式
–entry-file : 条目文件
–bundle-output : bundle文件生成的目录
–assets-dest : 资源文件生成的目录