关于android:最新版Android原生集成RN

9次阅读

共计 5750 个字符,预计需要花费 15 分钟才能阅读完成。

前言

当初不少利用都是采纳了混合开发模式,不论是原生加 RN, 或是原生加 Flutter, 或是原生加 H5。原生实现主业务线,其余局部能够借助跨平台计划开发,进步开发效率,或者实现热更新,调高业务迭代效率。

上面简略介绍一下 Android 原生集成最新 RN 版本的过程。

增加 package.json 文件

首先在一个失常编译运行的原生 APP 根目录下执行 yarn init 命令,按提醒填写根本信息后会在我的项目根目录下,创立一个 package.json 文件。

增加 JavaScript 依赖, 生成 node_modules

而后,应用如下命令增加 React 和 React Native 运行环境的反对脚本。

yarn add react react-native

命令执行实现后,所有 JavaScript 依赖模块都会被装置到我的项目根目录下的 node_modules/ 目录中。

留神:node_modules 这个目录咱们原则上不复制、不挪动、不批改、不上传,随用随装,同时把 node_modules/ 目录记录到.gitignore 文件中(即不上传到版本控制系统,只保留在本地)。

接下来,在 package.json 文件中配置启动 RN Metro 服务的脚本,即 script 脚本,文件全部内容如下。
我的项目根目录 package.json 文件

{
  "name": "AndroidDemo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "react": "^18.2.0",
    "react-native": "^0.70.6"
  },
  "scripts": {"start": "yarn react-native start"}
}

原生端增加 React Native 依赖

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

dependencies {
    ...
    implementation "com.facebook.react:react-native:+"
    implementation "org.webkit:android-jsc:+"
}

在我的项目的 build.gradle 文件中为 React Native 和 JSC 引擎增加 maven 源的门路,必须写在 “allprojects” 代码块中。

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")
        }
    }
}

!!!留神这里有个问题,点击同步后,会报如下谬误:

Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by build file 'build.gradle'

起因是 gradle7.0 后,以前位于根我的项目 build.gradle 文件中的代码库设置当初迁徙到了 settings.gradle 文件中,根目录 build.gradle 文件不做更改。
settings.gradle 文件配置

dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {google()
        mavenCentral()
        maven {url "$rootDir/node_modules/react-native/android"}
        maven {url("$rootDir/node_modules/jsc-android/dist")
        }
    }
}

相干阐明:https://developer.android.com…

配置原生我的项目网络权限及开发者菜单页面

在原生 AndroidManifest.xml 文件进行增加,对应示例如下
如果须要拜访 http 申请,须要 application 中增加 usesCleartextTraffic

// 网络权限
 <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:usesCleartextTraffic="true" // 拜访 http 申请
        android:theme="@style/Theme.AndroidStudy"
        tools:targetApi="31">

        <activity
            android:name=".MainActivity"
            android:exported="true">
<!--            <intent-filter>-->
<!--                <action android:name="android.intent.action.MAIN" />-->

<!--                <category android:name="android.intent.category.LAUNCHER" />-->
<!--            </intent-filter>-->
        </activity>

        <activity
            android:name=".MyActivity"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        // 开发者调试菜单
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

创立一个 RN 入口文件 index.js

index.js 是 React Native 利用在 Android 上的入口文件。而且它是不可或缺的!它能够是个很简略的文件,简略到能够只蕴含一行 require/import 导入语句,示例代码如下。

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',
    backgroundColor: '#f9c2ff',
  },
  hello: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
    color: 'red'
  }
});

AppRegistry.registerComponent(
  'MyReactNativeApp',
  () => HelloWorld);

创立一个页面用来承载 RN 页面

须要在一个 Activity 中创立一个 ReactRootView 对象,而后在这个对象之中启动 React Native 利用,并将它设为界面的主视图,这里创立了一个 MyActivity 页面

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

import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

public class MyActivity 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);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setCurrentActivity(this)
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackage(new MainReactPackage())
                .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();

        if (mReactInstanceManager != null) {mReactInstanceManager.onHostPause(this);
        }
    }

    @Override
    protected void onResume() {super.onResume();

        if (mReactInstanceManager != null) {mReactInstanceManager.onHostResume(this, this);
        }
    }

    @Override
    protected void onDestroy() {super.onDestroy();

        if (mReactInstanceManager != null) {mReactInstanceManager.onHostDestroy(this);
        }
        if (mReactRootView != null) {mReactRootView.unmountReactApplication();
        }
    }
// 显示开发调试菜单弹框
    @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
    public void invokeDefaultOnBackPressed() {super.onBackPressed();
    }
// 后退按钮事件传递给 React Native
    @Override
    public void onBackPressed() {if (mReactInstanceManager != null) {mReactInstanceManager.onBackPressed();
        } else {super.onBackPressed();
        }
    }
}

自此原生端集成 RN 实现。

测试集成成果。

首先,须要启动开发服务器(Metro)。你只需在我的项目根目录中执行以下命令:

yarn start

而后,点击 Android Studio 运行按钮,失常运行我的项目即可。

加载完 bundle 文件之后,能够看到如下页面了。

正文完
 0