最新最全的将ReactNative集成到现有原生Android应用指南(2018/6)

写在一开始

为什么要写这篇文章?
现有的许多教程文章大多基于ReactNative中文网的,鱼龙混杂,有些甚至是照搬,在我们开始上手,总会遇到问题,而面对网上的文章千篇一律、不能帮助到我们,心情一定是着急的。所以我希望集成教程有我这一篇就够了!当你在集成过程中遇到问题时,或者你正打算开始集成的时候,我希望你能够找到这篇文章。
ps:我没有吐槽ReactNaive中文网,相反我相信以及认可它的权威性,它上面的大部分教程写的非常好,有很高的参考意义,有些步骤我将引用中文网,我将本着精益求精的态度写下这边文章。好了,废话就说到这里,现在,年轻人,让我们开始吧!

一.开发环境准备

首先按照开发环境搭建教程来安装React Native在安卓平台上所需的一切依赖软件(比如npm)。

二.把React Native添加到你的应用中

1. 设置项目目录结构

首先创建一个空目录用于存放React Native项目,然后在其中创建一个/android子目录,把你现有的Android项目拷贝到/android子目录中。

项目结构

2. 安装JavaScript依赖包

在项目根目录下创建一个名为package.json的空文本文件,然后填入以下内容:

{
  "name": "MyApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "babel-preset-react-native": "^2.1.0",
    "react": "16.3.1",
    "react-native": "0.55.3",
    "react-navigation": "^2.3.1"
  },
  "jest": {
    "preset": "react-native"
  }
}

要想继续了解package.json请移步到阮一峰大神的博客中项目的配置信息

接下来我们使用npm(node包管理器)来安装React和React Native模块。 请打开一个终端/命令提示行,进入到项目目录中(即包含有package.json文件的目录),然后运行下列命令来安装,这些模块会被安装到项目根目录下的node_modules/目录中:

npm install

3.配置maven

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

 dependencies {
     ...
     compile "com.facebook.react:react-native:+" // From node_modules.
 }

在项目的 build.gradle 文件中为 React Native 添加一个 maven 依赖的入口,必须写在 "allprojects" 代码块中:

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

如果maven中url有多个的写法:

allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}

4.配置权限

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


如果需要访问DevSettingsActivity界面(即开发者菜单),则还需要在 AndroidManifest.xml中声明:


如果你的应用会运行在Android 6.0(API level 23)或更高版本,需要动态去申请打开悬浮窗(overlay)权限,一般写在应用的开屏页:

public class SplashActivity extends BaseActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ....
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!Settings.canDrawOverlays(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                        Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!Settings.canDrawOverlays(this)) {
                    // SYSTEM_ALERT_WINDOW permission not granted...
                }
            }
        }
    }
}

三.集成RN代码

1. 创建一个index.js文件

首先在项目根目录中创建一个空的index.js文件。

import {AppRegistry} from 'react-native';
import App from './ui/App';
import React, {Component, Text} from 'react';
import {DeviceEventEmitter} from 'react-native';

export default class Index extends Component {
    // 构造
    constructor(props) {
        super(props);
    }

    render() {
        return ();
    }
}

//注册组件到RN中去,使得原生可以访问到这个组件
AppRegistry.registerComponent('NbbApp', () => Index);

本案例使用了react-navigation,每个页面的配置都在App.js类中

import {StackNavigator, TabNavigator, TabBarBottom} from 'react-navigation';
import React, {Component} from 'react';
import Second from './Second';

const MyApp = StackNavigator({
    //每一个页面的配置,第一个即是首页
    Second: {
        screen: Second,
        path: "app/second"
    }
});
const prefix = 'scheme://app/';
const App = () => 
export default App;

2.实现ReactApplication

这步比较重要,也是中文网中没有提到的,否则会报错


image.png
public class NBBApplication extends Application implements ReactApplication {

    @Override
    public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
    }


    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {

        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List getPackages() {
            return Arrays.asList(
                    new MainReactPackage()
            );
        }

        @Override
        protected String getJSMainModuleName() {
            return "index";
        }
    };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }
}

3.启动RN界面

我们还需要添加一些原生代码来启动React Native的运行时环境并让它开始渲染。
在0.4版本之后,RN新增了ReactActivity这类,不需要我们自己去实现ReactRootView

public class MyReactActivity extends ReactActivity {

    public static void start(Context context) {
        Intent intent = new Intent(context, MyReactActivity.class);
        context.startActivity(intent);
    }

    @Nullable
    @Override
    protected String getMainComponentName() {
        return "NbbApp";
    }

    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
        return new ReactActivityDelegate(this,getMainComponentName());
    }
}

现在当我们在原生应用中打开MyReactActivity页面,就跳转到在index.js文件中
registerComponent注册过别名为NbbApp的RN页面。

四.运行

react-native run-android 运行到android设备中。

五.错误集锦

Starting: Intent { com.awesome_project/.MainActivity }
Error type 3
Error: Activity class {com.awesome_project/ com.awesome_project.MainActivity} does not exist.

请将项目的MainActivity移动到在根目录下

image.png

你可能感兴趣的:(最新最全的将ReactNative集成到现有原生Android应用指南(2018/6))