欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在Android原生应用中嵌入ReactNative页面

程序员文章站 2022-05-29 19:58:11
...

1、编译环境和SDK的准备

  • Android Studio 3.0.1
  • NodeJS
  • Android SDK 7.0

2、创建项目目录结构

首先创建一个空目录用于存放React Native项目,在里面创建一个名称为android的目录,将现有的工程全部拷贝进去。

3、初始化package.json

在项目根目录下创建文件’package.json’,内容编辑如下:

{
    "name": "reactnativedemo",
    "version": "0.0.1",
    "private": true,
    "scripts": {
      "start": "node node_modules/react-native/local-cli/cli.js start"
    },
    "dependencies": {
      "react": "16.0.0-alpha.12",
      "react-native": "0.45.1"
    }
  }

其中react和react-native的版本号要匹配,否则编译会报错,然后启动一个命令提示行,运行npm install命令安装reactnative组件

4、修改Gradle配置

  • 修改Android路径下的build.gradle文件
    在allprojects内配置react-native的本地代码路径
allprojects {
    ...
    repositories {
        ...
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}
  • 修改android/app路径下的build.gradle文件
    添加NDK配置
apply plugin: 'com.android.application'

android {
    ...
    defaultConfig {
        ...
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
    }
    ...
}

在依赖库配置里添加react-native,版本要和package.json的一致

dependencies {
    ...
    compile "com.facebook.react:react-native:0.45.1" // From node_modules.
}
  • 修改android目录下的gradle.properties,在最下方添加一句
android.useDeprecatedNdk=true

5、创建JS文件

在项目的根目录下创建一个index.android.js文件,并添加要显示的控件。注意最后一行的registerComponent的参数要同安卓package.json的项目名称一致

'use strict';

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('reactnativedemo', () => HelloWorld);

6、修改安卓代码

添加一个activity,作为加载react-native实例的容器

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModuleName("index.android")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        // 注意这里的reactnativedemo必须对应“index.android.js”中的
        // “AppRegistry.registerComponent()”的第一个参数
        mReactRootView.startReactApplication(mReactInstanceManager, "reactnativedemo", null);

        setContentView(mReactRootView);
    }

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

添加其他的生命周期状态接口

    @Override
    protected void onResume() {
        super.onResume();
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause(MyReactActivity.this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy(MyReactActivity.this);
        }
    }

    @Override
    public void onBackPressed() {
        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);
    }
  • 在其他界面上添加一个跳转到MyReactActivity的接口
        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // Android6.0以上,开发版本需要判断是否有打开悬浮窗(overlay)权限
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (!Settings.canDrawOverlays(MainActivity.this)) {
                        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                                Uri.parse("package:" + getPackageName()));
                        startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
                        return;
                    }
                }

                Intent intent = new Intent();
                intent.setClass(MainActivity.this, MyReactActivity.class);
                startActivity(intent);
            }
        });

7、修改AndroidManifest.xml配置文件

  • 权限清单里添加网络权限、系统悬浮窗权限、允许在其他应用上的上层显示权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
  • 添加activity清单
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
<activity
    android:name=".MyReactActivity"
    android:label="@string/app_name"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar">
</activity>

8、程序运行

  1. 运行react-native start,启动服务器

在Android原生应用中嵌入ReactNative页面

  1. 保持JS服务器端的窗口不要关掉,直接在android-studio中运行项目即可.执行跳转到MyReactActivity的接口即可打开JS页面

在Android原生应用中嵌入ReactNative页面

9、程序打包

你也可以使用Android Studio来打release包!其步骤基本和原生应用一样,只是在每次编译打包之前需要先执行js文件的打包(即生成离线的jsbundle文件)。具体的js打包命令如下:

$ react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/com/your-company-name/app-package-name/src/main/assets/index.android.bundle --assets-dest android/com/your-company-name/app-package-name/src/main/res/

注意把上述命令中的路径替换为你实际项目的路径。如果assets目录不存在,则需要提前自己创建一个。

然后在Android Studio中正常生成release版本即可!