在Android原生应用中引用RN页面

1,062 阅读2分钟

这是我参与8月更文挑战的第8,活动详情查看:8月更文挑战

1、前言

有时候我们可能会基于现有的项目,开发心的功能模块。那这个时候我可以选择用RN开发。这样做有2个优势:用一套代码久可以完成新模块多端的开发;同时,在性能上基本接近于原生。

2、基础配置

  1. 初始化一个RN项目
react-native init 项目名称
  1. 将你的android原生项目拷贝至,RN项目的android目录下
  2. android\app\build.gradle文件中添加 React Native 和 JSC 引擎依赖:
dependencies {
    implementation "com.android.support:appcompat-v7:27.1.1"
    ...
    implementation "com.facebook.react:react-native:+" // From node_modules
    implementation "org.webkit:android-jsc:+"
}
  1. android\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")
        }
        ...
    }
    ...
}
  1. 启用原生模块的自动链接
//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)
  1. AndroidManifest.xml配置权限
//网络权限
<uses-permission android:name="android.permission.INTERNET" />
//开发者菜单权限
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

3、代码编写

3.1 RN层代码编写

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

//向React Native注册一个名为MyReactNativeApp的组件,我们原生端使用这个名字调用RN组件。
AppRegistry.registerComponent(
  'MyReactNativeApp',
  () => HelloWorld
);

3.2 android原生层代码编写

新建MyReactActivity.java文件

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.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)这样些可能会报错
                //参考 https://blog.csdn.net/bearin/article/details/105681705
                .setInitialLifecycleState(LifecycleState.BEFORE_CREATE)
                .build();
         // 注意这里的MyReactNativeApp 必须对应"index.js"中的
        // "AppRegistry.registerComponent()"的第一个参数
        mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);

        setContentView(mReactRootView);
    }

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

3.3 在中AndroidManifest.xml注册MyReactActivity

<activity
  android:name=".MyReactActivity"
  android:label="@string/app_name"
  android:theme="@style/Theme.AppCompat.Light.NoActionBar">
</activity>

3.4 MinActivity中设置启动RN页面

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = new Intent(MainActivity.this, MyReactActivity.class);
        startActivity(intent);
    }

参考

reactnative.cn/docs/integr…

blog.csdn.net/denghuizi/a…