将React Native组件集成到本地应用程序中的方法

397 阅读5分钟

简介

将React Native集成到一个原生的应用程序中,无论是Android还是iOS,如果做得不正确,都会很复杂。在这篇文章中,我们的目标是将React Native组件集成到一个原生的Android应用程序中。

在创建移动应用程序时,集成React Native的最大好处之一是能够在iOS和Android应用程序中重复使用代码。这在React Native被集成到现有应用中后,几乎提供了完全的代码重用性,大大减少了开发时间和开发成本。

我们将介绍以下内容。

前提条件

  • React Native开发环境(React Native CLI);请点击此链接了解如何使用React Native CLI启动和运行
  • 安卓开发环境 (Android Studio)

开始使用我们的React Native项目

首先,让我们初始化我们的React Native项目。

npx react-native init nativeandroid
cd nativeandroid

启动Metro Bundler,在我们的React Native项目文件夹中运行以下命令。

npx react-native start

现在,启动应用程序。

npx react-native run-android

如果设置正确完成,Android应用程序应该在Android Studio模拟器上启动。

Welcome page for React Native

设置项目目录

如果没有使用Android Studio创建本地Android应用程序,可以创建一个新的应用程序。

Using Android Studio to create basic fragment Android mobile application

使用Android Studio,一个基本的片段式Android移动应用程序已经被创建。

Android mobile application

设置文件集成目录

这个目录将存放我们的React Native应用程序和Native Android应用程序。创建一个Android文件夹。

mkdir ReactNativeIntegration
cd ReactNativeIntegration
mkdir android

导航到用Android Studio创建的Android应用程序的根文件夹,复制AndroidStudioProjects 文件中的Android应用程序的所有文件,并将其粘贴到我们刚刚创建的Android文件夹。

Moving Android Application files into new Android folder

ReactNativeIntegration 文件夹中创建一个package.json

cd ..
touch package.json
code package.json

将下面的代码块添加到空的package.json 文件中。

{
  "name": "nativeandroid",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "npx react-native start",
    "android": "npx react-native run-android"
  }
}

在最后,文件目录应该是这样的。

File directory at the end

安装依赖项

在这里,我们安装。

  • react-native@0.61.5
  • React - 用于构建用户界面的JavaScript库
  • [hermesvsm](https://www.npmjs.com/package/hermesvm)- 运行我们React Native应用程序的JavaScript
  • jsc-android - 可维护的构建脚本,允许React Native将JSC的最新版本纳入框架中

yarn add react-native@0.61.5 react hermesvm jsc-android @react-native-community/cli-platform-android@3.0.3

配置Maven

Maven是管理和构建项目的首选工具。它很方便,因为它能根据项目的需要自动获取依赖关系,也能处理横向依赖关系。

要开始,在本地应用程序的build.gradle 文件中打开Android Studio。

Native application's build.gradle file

将这几行代码添加到依赖项部分。

dependencies {
   //noinspection GradleCompatible
   implementation "com.android.support:appcompat-v7:27.1.1"
   implementation "com.facebook.react:react-native:+" // From node_modules
   implementation "org.webkit:android-jsc:+"
}

我们将利用自动链接的力量,使我们的应用程序能够访问本地模块,并使用React Native库提供的本地模块。将这行代码添加到build.gradle 文件的底部,在依赖关系部分下面。

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

导航到我们的androidApplication 文件中的build.gradle 文件。

Gradle.properties is highlighted

build.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")
       }
       google()
       jcenter()

   }
}

task clean(type: Delete) {
   delete rootProject.buildDir
}

settings.gradle ,添加底部的这行代码以启用自动链接。

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

注释掉dependencyResolutionManagement 的代码块。

pluginManagement {
   repositories {
       gradlePluginPortal()
       google()
       mavenCentral()
   }
}

//dependencyResolutionManagement {
//    repositorMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
//    repositories {
//        google()
//        mavenCentral()
//    }
//}

同步Gradle的变化。应该不会有错误。

允许访问互联网的权限

通过在AndroidManifest.xml 文件中添加以下代码,可以在AndroidManifest.xml 文件中启用互联网权限。

<uses-permission android:name="android.permission.INTERNET" />
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.androidapplication">

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

DevSettings的访问权限也应该被启用。

然后,将下面的代码添加到AndroidManifest.xml 文件中。

<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
       </intent-filter>
   </activity>
   <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>

当创建生产版构建时,建议剥离dev settings权限,因为只有在从开发服务器重新加载JavaScript时才需要它。

在调试构建中启用明文

由于Android 9(API级别28)中引入的一些变化,默认情况下禁用明文流量。我们的应用程序因此无法连接到Metro Bundler。

AndroidManifest.xml 文件中,将useCleartextTraffic 选项加入到调试中。

<application
   android:usesCleartextTraffic="true">
</application>

在创建发布版本时,这不是必须的。

为了完善集成过程,将修改本地Android应用的代码,以集成React Native。

将React Native代码集成到原生Android应用中

在我们的React NativeIntegrate 文件夹的根部,创建一个index.js 文件。

touch index.js

将下面的代码块输入到index.js 文件中。

import React from "react";
import { AppRegistry, StyleSheet, Text, View } from "react-native";

const Integration = () => {
  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("IntegratedApp", () => Integration);

编写本地代码

为了启动React Native运行时间并告诉它渲染我们的JS组件,我们必须在Android Studio中创建一个名为ReactActivity 的文件。

在Android Studio中打开Android项目,创建一个名为ReactActivity 的类,它扩展了Activity,并创建了一个ReactRootView ,它启动了一个React应用程序并将其设置为Creating ReactActivity class in Android project

将下面的代码块添加到ReactActivity.java 文件中。

package com.example.androidapplication;

import android.app.Activity;
import android.os.Bundle;

import com.facebook.react.PackageList;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.soloader.SoLoader;

import java.util.List;

public class MyReactActivity extends Activity 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 that cannot be autolinked yet can be added manually here, for example:
        // packages.add(new MyReactNativePackage());
        // Remember to include them in `settings.gradle` and `app/build.gradle` too.

        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setCurrentActivity(this)
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackages(packages)
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        // The string here (e.g. "IntegratedApp") has to match
        // the string in AppRegistry.registerComponent() in index.js
        mReactRootView.startReactApplication(mReactInstanceManager, "IntegratedApp", null);

        setContentView(mReactRootView);
    }
    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }
}

现在,启动该应用程序。

npm run start

Application displays Hello, World

结论

集成React Native组件可能是一个相当大的任务,但开发的好处超过了挑战。由于React Native是一个开源框架,开发者在将他们的应用程序与React Native集成后,可以获得大量的共享代码库,这改善了开发者的体验,有助于加快应用程序的开发。

我希望这篇文章能为你提供足够的指导。