import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; import CodeBlock from '@theme/CodeBlock'; import RNTemplateRepoLink from '@site/core/RNTemplateRepoLink'; import {getTemplateBranchNameForCurrentVersion} from '@site/src/getTemplateBranchNameForCurrentVersion';
把 React Native 组件集成到 Android 应用中有如下几个主要步骤:
- 配置好项目结构。
- 安装必要的 NPM 依赖。
- 在 Gradle 中配置 React Native 依赖。
- 编写 TypeScript 代码,创建你的第一个 React Native 页面。
- 使用 ReactActivity 来把 React Native 集成到你的 Android 项目代码中。
- 运行打包服务,验证集成结果。
在跟随本指南时,我们建议你使用 React Native Community Template 作为参考。模板包含一个 精简的 Android app 并且可以帮助你理解如何将 React Native 集成到现有的 Android 应用中。
按照开发环境搭建教程和不使用框架使用 React Native 来配置你的 Android 开发环境。
本教程还假设你熟悉 Android 开发的基础知识,例如创建 Activity 和编辑 AndroidManifest.xml 文件。
首先创建一个空目录用于存放 React Native 项目,然后在其中创建一个/android子目录,把你现有的 Android 项目拷贝到/android子目录中。
在根目录下运行以下命令:
{`curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/${getTemplateBranchNameForCurrentVersion()}/template/package.json`}这将把 package.json 社区模板中的文件复制到你的项目中。
接下来我们使用 yarn 或 npm 来安装必要的模块。请打开一个终端/命令提示行,进入到项目目录中(即包含有 package.json 文件的目录),然后运行下列命令来安装:
npm installyarn install所有 JavaScript 依赖模块都会被安装到项目根目录下的node_modules/目录中。
把node_modules/目录记录到.gitignore文件中(可以参考社区模板中的默认配置)。
React Native 使用 React Native Gradle Plugin 来配置您的依赖项和项目设置。
首先,让我们通过添加以下行来编辑您的settings.gradle文件
(请参考社区模板):
// 此处配置用于自动链接第三方原生库的 React Native Gradle 插件
pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
plugins { id("com.facebook.react.settings") }
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
// 如果使用 .gradle.kts 文件:
// extensions.configure<com.facebook.react.ReactSettingsExtension> { autolinkLibrariesFromCommand() }
includeBuild("../node_modules/@react-native/gradle-plugin")
// 在这里引入你已有的其他 Gradle 模块。
// include(":app")然后你需要打开顶层的 build.gradle 文件并添加这一行(请参考社区模板):
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
+ classpath("com.facebook.react:react-native-gradle-plugin")
}
}这将确保 React Native Gradle Plugin 在您的项目中可用。
最后,在您的应用的 build.gradle 文件中添加以下行(这是不同于上面的另一个 build.gradle 文件,通常在 app 文件夹内——您可以参考社区模板文件):
apply plugin: "com.android.application"
+apply plugin: "com.facebook.react"
repositories {
mavenCentral()
}
dependencies {
// Other dependencies here
+ // 注:我们故意不在这里指定版本号,因为 React Native Gradle Plugin 会自动处理它。
+ // 如果您不使用 React Native Gradle Plugin,则必须手动指定版本。
+ implementation "com.facebook.react:react-android"
+ implementation "com.facebook.react:hermes-android"
}
+react {
+ // 启用自动链接需要添加以下行,参考: https://github.com/react-native-community/cli/blob/main/docs/autolinking.md
+ autolinkLibrariesWithApp()
+}最后,打开应用的 gradle.properties 文件并添加以下行(请参考社区模板文件):
+reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
+newArchEnabled=true
+hermesEnabled=true首先,确保你的 AndroidManifest.xml 中有网络权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MainApplication">
</application>
</manifest>然后你需要在你的调试 AndroidManifest.xml 中启用明文传输:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
+ android:usesCleartextTraffic="true"
+ tools:targetApi="28"
/>
</manifest>同样可以参考社区模板的 AndroidManifest.xml 文件作为参考:main 和 debug。
这是因为你的应用将通过 HTTP 与本地打包服务 Metro 进行通信。
请确保只在调试 Manifest 中添加此配置。
现在我们将修改原生 Android 应用程序以集成 React Native。
我们要编写的第一个代码是将集成到应用中的新 React Native 屏幕的实际代码。
首先在项目根目录中创建一个空的index.js文件。
index.js是 React Native 应用的入口文件,而且它是不可或缺的。它可以是个很简单的文件,简单到可以只包含一行import导入其他 React Native 组件或应用的文件,或者它也可以包含所有需要的代码。
我们的 index.js 应该如下所示(请参考社区模板文件):
import {AppRegistry} from 'react-native';
import App from './App';
AppRegistry.registerComponent('HelloWorld', () => App);下面我们创建一个 App.tsx 文件。这是一个 TypeScript 文件,可以包含 JSX 表达式。它包含了我们将在 Android 应用中集成的根 React Native 组件(链接):
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
function App(): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<View
style={{
backgroundColor: isDarkMode
? Colors.black
: Colors.white,
padding: 24,
}}>
<Text style={styles.title}>Step One</Text>
<Text>
Edit <Text style={styles.bold}>App.tsx</Text> to
change this screen and see your edits.
</Text>
<Text style={styles.title}>See your changes</Text>
<ReloadInstructions />
<Text style={styles.title}>Debug</Text>
<DebugInstructions />
</View>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
title: {
fontSize: 24,
fontWeight: '600',
},
bold: {
fontWeight: '700',
},
});
export default App;我们现在需要添加一些原生代码来启动 React Native 运行时,并让它渲染我们的 React 组件。
首先,我们需要更新你的 Application 类来正确初始化 React Native,如下所示:
package <your-package-here>;
import android.app.Application;
+import com.facebook.react.PackageList;
+import com.facebook.react.ReactApplication;
+import com.facebook.react.ReactHost;
+import com.facebook.react.ReactNativeHost;
+import com.facebook.react.ReactPackage;
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
+import com.facebook.react.defaults.DefaultReactHost;
+import com.facebook.react.defaults.DefaultReactNativeHost;
+import com.facebook.soloader.SoLoader;
+import com.facebook.react.soloader.OpenSourceMergedSoMapping
+import java.util.List;
-class MainApplication extends Application {
+class MainApplication extends Application implements ReactApplication {
+ @Override
+ public ReactNativeHost getReactNativeHost() {
+ return new DefaultReactNativeHost(this) {
+ @Override
+ protected List<ReactPackage> getPackages() { return new PackageList(this).getPackages(); }
+ @Override
+ protected String getJSMainModuleName() { return "index"; }
+ @Override
+ public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; }
+ @Override
+ protected boolean isNewArchEnabled() { return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; }
+ @Override
+ protected Boolean isHermesEnabled() { return BuildConfig.IS_HERMES_ENABLED; }
+ };
+ }
+ @Override
+ public ReactHost getReactHost() {
+ return DefaultReactHost.getDefaultReactHost(getApplicationContext(), getReactNativeHost());
+ }
@Override
public void onCreate() {
super.onCreate();
+ SoLoader.init(this, OpenSourceMergedSoMapping);
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ DefaultNewArchitectureEntryPoint.load();
+ }
}
}// package <your-package-here>
import android.app.Application
+import com.facebook.react.PackageList
+import com.facebook.react.ReactApplication
+import com.facebook.react.ReactHost
+import com.facebook.react.ReactNativeHost
+import com.facebook.react.ReactPackage
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
+import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
+import com.facebook.react.defaults.DefaultReactNativeHost
+import com.facebook.soloader.SoLoader
+import com.facebook.react.soloader.OpenSourceMergedSoMapping
-class MainApplication : Application() {
+class MainApplication : Application(), ReactApplication {
+ override val reactNativeHost: ReactNativeHost =
+ object : DefaultReactNativeHost(this) {
+ override fun getPackages(): List<ReactPackage> = PackageList(this).packages
+ override fun getJSMainModuleName(): String = "index"
+ override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
+ override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
+ override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
+ }
+ override val reactHost: ReactHost
+ get() = getDefaultReactHost(applicationContext, reactNativeHost)
override fun onCreate() {
super.onCreate()
+ SoLoader.init(this, OpenSourceMergedSoMapping)
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ load()
+ }
}
}同样可以参考MainApplication.kt 社区模板文件。
最后,我们需要创建一个新的 Activity,它将继承 ReactActivity 并承载 React Native 代码。这个 Activity 将负责启动 React Native 运行时并渲染 React 组件。
// package <your-package-here>;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactActivityDelegate;
public class MyReactActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "HelloWorld";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new DefaultReactActivityDelegate(this, getMainComponentName(), DefaultNewArchitectureEntryPoint.getFabricEnabled());
}
}// package <your-package-here>
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
class MyReactActivity : ReactActivity() {
override fun getMainComponentName(): String = "HelloWorld"
override fun createReactActivityDelegate(): ReactActivityDelegate =
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
}同样可以参考MainActivity.kt 社区模板文件。
每当创建新的 Activity 时,你需要将其添加到 AndroidManifest.xml 文件中。你还需要将 MyReactActivity 的主题设置为 Theme.AppCompat.Light.NoActionBar(或任何非 ActionBar 主题),否则你的应用会在 React Native 屏幕上方渲染一个 ActionBar:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MainApplication">
+ <activity
+ android:name=".MyReactActivity"
+ android:label="@string/app_name"
+ android:theme="@style/Theme.AppCompat.Light.NoActionBar">
+ </activity>
</application>
</manifest>现在你的 Activity 已准备好运行 JavaScript 代码了。
你已经完成了将 React Native 集成到应用中的所有基本步骤。现在我们将启动 Metro 打包器 来将你的 TypeScript 应用代码打包成 bundle。Metro 的 HTTP 服务器会从你开发环境的 localhost 上将 bundle 共享给模拟器或设备。这支持热重载。
首先,你需要在项目根目录创建一个 metro.config.js 文件,内容如下:
const {getDefaultConfig} = require('@react-native/metro-config');
module.exports = getDefaultConfig(__dirname);你可以参考社区模板中的 metro.config.js 文件。
配置文件就位后,你就可以运行打包器了。在项目根目录运行以下命令:
npm startyarn start像往常一样构建并运行你的 Android 应用。
当你在应用中打开 React 驱动的 Activity 时,它应该会从开发服务器加载 JavaScript 代码并显示:
你也可以使用 Android Studio 来创建发布版本!就像创建之前已有的原生 Android 应用的发布版本一样快捷。
React Native Gradle Plugin 会负责将 JS 代码打包到你的 APK/App Bundle 中。
如果你不使用 Android Studio,可以通过以下命令创建发布版本:
cd android
# For a Release APK
./gradlew :app:assembleRelease
# For a Release AAB
./gradlew :app:bundleRelease
