[RN-Android] ReactNative集成进Android项目 2018-04-17

ReactNative集成进Android项目

ReactNative已经发展了一段时间.现在最新版本是 version 0.55 虽然还没有稳定的v 1.0版本,但是现在的功能已经可以承担起项目跨平台的开发任务. 丰富的第三方组件库提供了全面的功能解决方案的同时解决了大部分Androidios平台兼容的问题. 这使得ReactNative生态不断发展,更加完美.
现在,我们一起探索一下ReactNative & Android混合开发.
首先,我们要将ReactNative集成进一个现有的Android项目

一. 环境搭建和Hello World RN项目的创建

这个主题网上有近乎完美的文档,这里不再赘述.以下是可以参考的文档.

  • ReactNative中文网-搭建开发环境
  • ReactNative官网-搭建开发环境
    [RN-Android] ReactNative集成进Android项目 2018-04-17_第1张图片
    image.png

    [RN-Android] ReactNative集成进Android项目 2018-04-17_第2张图片
    image.png

    [RN-Android] ReactNative集成进Android项目 2018-04-17_第3张图片
    image.png

    [RN-Android] ReactNative集成进Android项目 2018-04-17_第4张图片
    image.png

二. 项目合并

在做这一步之前,我们已经有了使用react-native init HelloWorld产生的RN 项目 和一个已经存在的Android项目,现在我们的文件夹里两个项目像下图一样:

[RN-Android] ReactNative集成进Android项目 2018-04-17_第5张图片
image.png

2.1 新建合并工程 RNAndroid合并文件

  1. 新建RNAndroid文件夹.并在里面新建一个android文件夹.
  2. 复制AndroidRNDemo文件夹下的所有文件复制到上面新建出来的android文件夹中
  3. HelloWorld文件夹中的**App.js, app.json, index.js, package.json, ios(文件夹), 复制到RNAndroid文件夹里.

完成后的RNAndroid文件夹是这样的:

[RN-Android] ReactNative集成进Android项目 2018-04-17_第6张图片
image.png

至此,文件合并结束.

2.2 修改Android项目的build.gradle 文件

以下操作都在android文件夹里面进行
使用AndroidStudio打开android文件夹,然后开始修改文件.

  1. 打开项目层级的build.gradle文件,在里面添加如下代码:
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
[RN-Android] ReactNative集成进Android项目 2018-04-17_第7张图片
打开项目层级的`build.gradle`文件

[RN-Android] ReactNative集成进Android项目 2018-04-17_第8张图片
添加代码后
  1. 打开module层级的build.gradle文件
    在里面添加依赖代码
//noinspection GradleCompatible
    compile 'com.android.support:appcompat-v7:23.1.0'
    compile "com.facebook.react:react-native:+" // From node_modules.
[RN-Android] ReactNative集成进Android项目 2018-04-17_第9张图片
添加代码前

[RN-Android] ReactNative集成进Android项目 2018-04-17_第10张图片
添加代码后

至此我们完成里android构建文件的修改

2.3 让android Application实现 ReactApplication接口

这一步实现接口并实现一个getReactNativeHost()方法.
MainActivity.java 同级目录下新建'MyApplication.java'文件,完成后的代码如下:

package com.gomorrow.androidrndemo;

import android.app.Application;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;

import java.util.Arrays;
import java.util.List;

/**
 * 作者: Panda8
 * 日期: 2018/4/20 15:02.
 */

public class MyApplication extends Application implements ReactApplication{

    ReactNativeHost  mReactNativeHostnew = new
            ReactNativeHost(this){
                @Override
                protected String getJSMainModuleName() {
                    return "index";
                }

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

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

设置应用使用MyApplication启动


[RN-Android] ReactNative集成进Android项目 2018-04-17_第11张图片
image.png

2.4 MainActivity 继承ReactActivity

完成后的MainActivity代码如下:

package com.gomorrow.androidrndemo;

import com.facebook.react.ReactActivity;

import javax.annotation.Nullable;

public class MainActivity  extends ReactActivity {
    @Nullable
    @Override
    protected String getMainComponentName() {
//这里返回index.js里面export的module name
        return "HelloWorld";
    }
}

2.5 同步下代码确定React-Native的版本是不是最新的0.55.3

确定RN库版本

2.6 添加so库的支持

在app/gradle 文件里添加如下代码

 {
....

    ndk {
        abiFilters "armeabi-v7a", "x86", 'armeabi', 'arm64-v8a'
    }

    packagingOptions {
            exclude '/lib/mips64/**'
            exclude '/lib/arm64-v8a/**'
            exclude '/lib/x86_64/**'
    }
}

不添加运行时的报错信息如下:


[RN-Android] ReactNative集成进Android项目 2018-04-17_第12张图片
不添加运行时的报错信息

2.7 配置adb端口

在终端中运行下面的语句

adb reverse tcp:8081 tcp:8081

2.8 添加开发者页面

在清单文件中添加一行


2.9 添加网络权限

在清单文件中添加一行


至此: 清单文件的所有内容如下




    

    
        
            
                

                
            
        

        
    


最后,终于可以Run一下了.这个时候会完全没有错误的启动AndroidAPP. 但是这个APP还不能真正的称得上是混合开发的APP. 混合开发意味着两种语言可以无缝通信. 接下来我们来进行ReactNative代码和Android原生java代码实现通信的部分.

三. Android和ReactNative的互相调用和通信.

两种语言通信,通常需要协议支持,而在ReactNative的开发中这个协议已经实现高内聚封装.我们需要操作的协议部分被浓缩成了两个类(对于Android的Java),一个对象(对于RN的JavaScript).

3.1 两个类.

  • ReactPackage

  • ReactContextBaseJavaModule

在js和java的通信中. ReactNative将协议封装成'package'和'module'两个部分.
其中module负责定义可以在JavaScript层调用的方法,'package'负责将module打包供ReactNative(js)层调用

3.2 module

package com.gomorrow.androidrndemo;

import android.content.Intent;

import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
/**
 * 作者: Panda8
 * 日期: 2018/4/20 15:02.
 */

public class JSBundleManager extends ReactContextBaseJavaModule {

    public JSBundleManager(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return "JSBundleManager";
    }

/*
* 定义一个可以被js调用的方法使用注解@ReactMethod声明
*/
    @ReactMethod
    public void startNativeActivity() {
        Intent intent = new Intent(getReactApplicationContext(),SplashActivity.class);
        getCurrentActivity().startActivity(intent);
    }
}

3.3 package

Package负责打包module


public class JSBundlePackage implements ReactPackage {

    @Override
    public List createNativeModules(ReactApplicationContext reactContext) {
        List modules = new ArrayList<>();
        modules.add(new JSBundleManager(reactContext));
        return modules;
    }

    @Override
    public List createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

3.4 建立js vs java

[RN-Android] ReactNative集成进Android项目 2018-04-17_第13张图片
image.png

3.5 在Rn端调用Native方法.

你可能感兴趣的:([RN-Android] ReactNative集成进Android项目 2018-04-17)