• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

React Native集成到现有原生应用

武飞扬头像
环山绕水
帮助5

核心概念

把 React Native 组件集成到现有 Android 应用中有如下几个主要步骤:

1. 配置React Native依赖和项目结构。
2. 安装JavaScript依赖包。
3. 把React Native添加到你的应用中。
4. 在应用中添加一个ReactRootView。
5. 启动 React Native 的 Metro 服务,运行应用。

1. 配置React Native依赖和项目结构

首先创建一个空目录用于存放 React Native 项目,然后在其中创建一个/android子目录,把你现有的Android项目拷贝到/android子目录中(项目根目录内开始拷贝,不包括根文件夹)。 目录结构看起来是这样:

-/ReactAppDir/
-/ReactAppDir/android/

2. 安装JavaScript依赖包

2.1 创建package.json

在项目根目录下,打开打开一个终端/命令提示行,然后运行 npm init,会自动创建名为package.json的文本文件,内容如下:

PS E:\React_Project\ReactAppDir> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (067manniu3)
version: (1.0.0)
description: entry point: (index.js)
test command: testcom
git repository: keywords: author: license: (ISC)
About to write to E: \React_Project\ReactAppDir\package.json: {
"name": "067manniu3",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "testcom"
},
"author": "",
"license": "ISC"
}

Is this OK? (yes)
PS E: \React_Project\ReactAppDir>
学新通

此时目录结构如下:

-/ReactAppDir/
-/ReactAppDir/android/
-/ReactAppDir/package.json

2.2 初始化react-native

npm install –save react react-native@0.67.0     ###指定版本
npm install –save react react-native            ###不指定版本

在项目根目录下,打开打开一个终端/命令提示行,然后运行 npm install react-native,自动安装react-native的最新依赖,或者运行:

PS E:\React_Project\ReactAppDir> npm install –save react react-native@0.67.0
npm WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated sane@4.1.0: some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated uglify-es@3.3.9: support for ECMAScript is superseded by `uglify-js` as of v3.13.0

added 695 packages in 2m
PS E:\React_Project\ReactAppDir>

此时目录结构如下:

-/ReactAppDir/
-/ReactAppDir/android/
-/ReactAppDir/node_modules/
-/ReactAppDir/package.json
-/ReactAppDir/package-lock.json

此时package.json的内容如下:

{
  "name": "067manniu3",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "testcom"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^17.0.2",
    "react-native": "^0.67.0",
    "save": "^2.5.0"
  }
}
学新通

打开package.json文件,在scripts中添加"start": “yarn react-native start”,然后保存。

{
  "name": "067manniu3",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "testcom",
    "start": "yarn react-native start"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^17.0.2",
    "react-native": "^0.67.0",
    "save": "^2.5.0"
  }
}
学新通

3 把React Native添加到你的应用中。

3.1 配置 maven

在你的 app 中 build.gradle 文件中添加 React Native 和 JSC 引擎依赖:

dependencies {
    implementation 'androidx.appcompat:appcompat:1.2.0'
    ...
    implementation "com.facebook.react:react-native: " // From node_modules
    implementation "org.webkit:android-jsc: "
}
如果想要指定特定的 React Native 版本,可以用具体的版本号替换  ,当然前提是你从 npm 里下载的是这个版本。

3.2 添加 maven 源的路径

在项目的 build.gradle 文件中为 React Native 和 JSC 引擎添加 maven 源的路径,必须写在 “allprojects”
代码块中。如果是gradle-7.0以上版本时则需要写在settings.gradle中。

allprojects {
    repositories {
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }
        ...
    }
    ...
}

或者

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        谷歌()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
        ...
        // mavenLocal() 以下加载本地仓库
        mavenLocal() 
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }
    }
}
rootProject.name = "ManNiuTest2"
include ':app'
学新通

3.3 启用原生模块的自动链接

要使用自动链接的强大功能,我们必须在几个地方应用它。 首先将以下条目添加到 settings.gradle:

apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); 
applyNativeModulesSettingsGradle(settings)

接下来在 app/build.gradle 的最底部添加以下条目

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

4 应用中添加一个ReactRootView。

在应用中添加一个ReactRootView。这个ReactRootView正是用来承载你的 React Native 组件的容器。

4.1 配置权限

在 AndroidManifest.xml 清单文件中声明网络权限:

<uses-permission android:name="android.permission.INTERNET" />

如果需要访问 DevSettingsActivity 界面(即开发者菜单),则还需要在 AndroidManifest.xml 中声明:
开发者菜单一般仅用于在开发时从 Packager 服务器刷新 JavaScript 代码,所以在正式发布时你可以去掉这一权限。

<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

4.2 允许明文传输(http 接口) (API level 28 )

在src/debug/AndroidManifest.xml中添加usesCleartextTraffic选项:

... 
<application
  android:usesCleartextTraffic="true" tools:targetApi="28" >
  ...
  ...
</application>
... 

4.3 代码集成

4.3.1 创建一个index.js文件

首先在项目根目录中创建一个空的index.js文件。 index.js是 React Native 应用在 Android 上的入口文件。而且它是不可或缺的!

4.3.2 添加你自己的 React Native 代码

在index.js中添加你自己的组件。

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(
  'MyReactNativeApp',
  () => HelloWorld
);
学新通

4.3.3 核心组件:ReactRootView

我们还需要添加一些原生代码来启动 React Native 的运行时环境并让它开始渲染。首先需要在一个Activity中创建一个ReactRootView对象,然后在这个对象之中启动 React Native 应用,并将它设为界面的主视图。

public class MyReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SoLoader.init(this, false);

        mReactRootView = new ReactRootView(this);
        List<ReactPackage> packages = new PackageList(getApplication()).getPackages();
        // 有一些第三方可能不能自动链接,对于这些包我们可以用下面的方式手动添加进来:
        // packages.add(new MyReactNativePackage());
        // 同时需要手动把他们添加到`settings.gradle`和 `app/build.gradle`配置文件中。

        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setCurrentActivity(this)
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackages(packages)
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        // 注意这里的MyReactNativeApp 必须对应"index.js"中的
        // "AppRegistry.registerComponent()"的第一个参数
        mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);

        setContentView(mReactRootView);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 把一些 activity 的生命周期回调传递给ReactInstanceManager
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 把一些 activity 的生命周期回调传递给ReactInstanceManager
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 把一些 activity 的生命周期回调传递给ReactInstanceManager
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy(this);
        }
        if (mReactRootView != null) {
            mReactRootView.unmountReactApplication();
        }
    }

    @Override
    public void onBackPressed() {
        // 后退按钮事件传递给 React Native
        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);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        // 最后,必须重写 onActivityResult() 方法(如下面的代码所示)以处理权限 Accepted 或 Denied 情况以实现一致的 UX。
        // 此外,为了集成使用 startActivityForResult 的 Native Modules,我们需要将结果传递给我们的 ReactInstanceManager
        mReactInstanceManager.onActivityResult(this, requestCode, resultCode, data);
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }
}
学新通

5 测试结果

在MainActivity中加入一个按钮,实现跳转到MyReactActivity。

public void gotoHelloReactActivity(View view) {
    startActivity(new Intent(this, MyReactActivity.class));
}

5.1 运行 Metro 服务

$ yarn start

5.2. 运行你的应用

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfhbfeb
系列文章
更多 icon
同类精品
更多 icon
继续加载