在Android原生应用中嵌入ReactNative页面
程序员文章站
2022-05-29 19:58:11
...
1、编译环境和SDK的准备
- Android Studio 3.0.1
- NodeJS
- Android SDK 7.0
2、创建项目目录结构
首先创建一个空目录用于存放React Native项目,在里面创建一个名称为android的目录,将现有的工程全部拷贝进去。
3、初始化package.json
在项目根目录下创建文件’package.json’,内容编辑如下:
{
"name": "reactnativedemo",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"dependencies": {
"react": "16.0.0-alpha.12",
"react-native": "0.45.1"
}
}
其中react和react-native的版本号要匹配,否则编译会报错,然后启动一个命令提示行,运行npm install命令安装reactnative组件
4、修改Gradle配置
- 修改Android路径下的build.gradle文件
在allprojects内配置react-native的本地代码路径
allprojects {
...
repositories {
...
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
}
- 修改android/app路径下的build.gradle文件
添加NDK配置
apply plugin: 'com.android.application'
android {
...
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
...
}
在依赖库配置里添加react-native,版本要和package.json的一致
dependencies {
...
compile "com.facebook.react:react-native:0.45.1" // From node_modules.
}
- 修改android目录下的gradle.properties,在最下方添加一句
android.useDeprecatedNdk=true
5、创建JS文件
在项目的根目录下创建一个index.android.js文件,并添加要显示的控件。注意最后一行的registerComponent的参数要同安卓package.json的项目名称一致
'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('reactnativedemo', () => HelloWorld);
6、修改安卓代码
添加一个activity,作为加载react-native实例的容器
public class MyReactActivity extends AppCompatActivity 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")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
// 注意这里的reactnativedemo必须对应“index.android.js”中的
// “AppRegistry.registerComponent()”的第一个参数
mReactRootView.startReactApplication(mReactInstanceManager, "reactnativedemo", null);
setContentView(mReactRootView);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
添加其他的生命周期状态接口
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause(MyReactActivity.this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostDestroy(MyReactActivity.this);
}
}
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
- 在其他界面上添加一个跳转到MyReactActivity的接口
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Android6.0以上,开发版本需要判断是否有打开悬浮窗(overlay)权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(MainActivity.this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
return;
}
}
Intent intent = new Intent();
intent.setClass(MainActivity.this, MyReactActivity.class);
startActivity(intent);
}
});
7、修改AndroidManifest.xml配置文件
- 权限清单里添加网络权限、系统悬浮窗权限、允许在其他应用上的上层显示权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
- 添加activity清单
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
<activity
android:name=".MyReactActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
</activity>
8、程序运行
- 运行react-native start,启动服务器
- 保持JS服务器端的窗口不要关掉,直接在android-studio中运行项目即可.执行跳转到MyReactActivity的接口即可打开JS页面
9、程序打包
你也可以使用Android Studio来打release包!其步骤基本和原生应用一样,只是在每次编译打包之前需要先执行js文件的打包(即生成离线的jsbundle文件)。具体的js打包命令如下:
$ react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/com/your-company-name/app-package-name/src/main/assets/index.android.bundle --assets-dest android/com/your-company-name/app-package-name/src/main/res/
注意把上述命令中的路径替换为你实际项目的路径。如果assets目录不存在,则需要提前自己创建一个。
然后在Android Studio中正常生成release版本即可!
上一篇: Dropdual