读者可通过本篇文章深入了解,在现有原生项目基础上,集成RN功能步骤及注意事项,推荐各位阅读。
一、环境准备
1. 创建 package.json
(项目根目录)
{
"name": "YourProject",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "yarn react-native start",
"bundle-android": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/"
},
"dependencies": {
"react": "17.0.2",
"react-native": "0.66.5"
}
}
关键点:
react
版本需与 RN 0.66.5 匹配(官方推荐 17.0.2)- 添加
bundle-android
脚本用于生产环境打包 JS Bundle
2. 安装依赖
yarn install
二、Android 工程配置
1. 修改根目录 build.gradle
allprojects {
repositories {
google()
mavenCentral()
// 添加 React Native 本地仓库路径
maven {
url "$rootDir/node_modules/react-native/android"
}
maven {
// Android JSC is installed from npm
url("$rootDir/node_modules/jsc-android/dist")
}
}
}
作用:让 Gradle 从本地 node_modules
目录加载 RN 依赖
2. 修改 App 模块 build.gradle
android {
compileSdkVersion 30
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
ndk {
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
}
}
dependencies {
implementation "com.facebook.react:react-native:0.66.5" // 指定版本
implementation "org.webkit:android-jsc:+"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" // RN 依赖的兼容库
// Fresco 版本需与 RN 0.66.5 匹配(通过查看 node_modules/react-native/react-native-0.66.5.pom 确定)
implementation 'com.facebook.fresco:fresco:2.5.0'
implementation 'com.facebook.fresco:animated-gif:2.5.0'
}
兼容性说明:
minSdkVersion
≥ 21(RN 0.66.5 最低要求)- Fresco 版本需通过检查
node_modules/react-native/react-native-0.66.5.pom
确认
三、初始化 React Native 环境
1. 创建 MainApplication
(继承 Application
并实现 ReactApplication
)
public class MainApplication 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.asList(
new MainReactPackage()
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, false); // 初始化 Fresco 等原生模块
}
}
2. 创建 ReactActivity
(用于加载 RN 页面)
public class ReactNativeActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "YourApp"; // 与 JS 端注册的组件名一致
}
}
四、配置 AndroidManifest.xml
<manifest>
<!-- 添加网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MainApplication"
...>
<!-- 添加 RN Activity -->
<activity
android:name=".ReactNativeActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" />
</application>
</manifest>
五、Fragment中添加ReactFragment
// Fragment嵌套子Fragment
val transaction = childFragmentManager.beginTransaction()
val reactNativeFragment: Fragment = ReactFragment.Builder()
.setComponentName("MyReactNativeApp")
.build()
transaction.add(R.id.ll_rn, reactNativeFragment).commit()
// Activity中添加
Fragment reactNativeFragment = new ReactFragment.Builder()
.setComponentName("MyReactNativeApp")
.setLaunchOptions(getLaunchOptions("test message"))
.build();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.reactNativeFragment, reactNativeFragment)
.commit();
// 上面setComponentName中的字符串是index.js文件中AppRegistry.registerComponent重点的字符串内容,要一致
AppRegistry.registerComponent(
'MyReactNativeApp',
() => HelloWorld
);
// MainActivity需要实现implements DefaultHardwareBackBtnHandler
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
添加getLaunchOptions方法,该方法允许你将属性传递到组件。这是可选的,如果不需要传递任何属性,可以删除setLaunchOptions。
private Bundle getLaunchOptions(String message) {
Bundle initialProperties = new Bundle();
initialProperties.putString("message", message);
return initialProperties;
}
六、JS Bundle 加载配置
1. 开发环境(Debug 模式)
- 启动 Metro 服务:
yarn start
- 在
ReactNativeActivity
中通过ReactNativeHost
动态加载 Metro 服务提供的 Bundle
2. 生产环境(Release 模式)
生成预编译的 JS Bundle:
npm run bundle-android
输出文件:
android/app/src/main/assets/index.android.bundle
android/app/src/main/res/
中的静态资源
七、常见问题解决
1. Gradle 下载超时
修改 gradle-wrapper.properties
:
distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-7.3.3-all.zip
(Gradle 版本需与 RN 0.66.5 兼容)
2. 依赖冲突
在 app/build.gradle
中强制指定版本:
configurations.all {
resolutionStrategy {
force 'com.facebook.fresco:fresco:2.5.0'
}
}
3. 原生版本兼容性问题
需要根据原生项目的compileSdkVersion及gradle版本,集成合适的RN版本,否则容易出现compileSdkVersion不一致问题。
android = [
compileSdkVersion: 30,
buildToolsVersion: "30.0.3",
supportSdkVersion: "30.0.3",
minSdkVersion : 21,
targetSdkVersion : 30,
versionCode : 36,
versionName : rootProject.VERSION_NAME
]
七、版本兼容性参考表
组件 | RN 0.66.5 要求版本 | 兼容性说明 |
---|---|---|
compileSdkVersion | 30+ | 推荐与原生项目保持一致 |
Fresco | 2.5.0 | 通过 POM 文件验证 |
OkHttp | 3.12.1 | 需与 RN 内置版本一致 |
node | v16.20.2 | 需与 RN 当前版本兼容 |
集成完成后,可通过 ReactNativeActivity
跳转至 RN 页面。若需进一步优化(如新架构启用),可参考 RN 0.66.5 官方文档调整配置。
八、作为全屏Activity及Fragment同时存在,需要在 index.js 中注册多个组件
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import FragmentTest from './fragment_test'
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
}
});
// 全屏Activity入口
AppRegistry.registerComponent(
'MyReactNativeApp',
() => HelloWorld
);
// Fragment 入口
AppRegistry.registerComponent('FragmentComponent', () => FragmentTest);