React Native之原生模块的开发(Android)学习笔记

 

目录

1.为何咱们须要原生模块开发

2.开发Android原生模块的主要流程

3.原生模块开发实战

 

1.为何咱们须要原生模块开发?

咱们在用RN开发App的时候,有时候须要用到一些原生模块,好比:分享、第三方登陆等。在RN的官方文档是这样谈到的:java

“有时候App须要访问平台API,但在React Native可能尚未相应的模块。或者你须要复用一些Java代码,而不想用JavaScript再从新实现一遍;又或者你须要实现某些高性能的、多线程的代码,譬如图片处理、数据库、或者一些高级扩展等等。 ”react

 

2.开发Android原生模块的主要流程

2.1 构建一个React Native Android原生模块的流程大体分为如下三大步:

  1. 编写相关的原生模块Java代码;
  2. 暴露接口与数据交互;
  3. 注册与导出React Native原生模块;

2.1 使用React Native Android原生模块

  1. 在相应js组件中导入NativeModule;
  2. 使用对应暴露的接口方法;

 

3.原生模块开发实战

咱们所要作的事情很简单,在RN组件中,点击一个按钮,触发原生模块中的咱们所编写的事件,获取当前时间并显示android

3.1 使用Android Studio导入android项目

以下图git

在android/app/src/main/java/下建立com.myNativeModule这样一个package(项目结构以下图)github


 

3.2 编写相关的原生模块Java代码

在android/app/src/main/java/com/myNativeModule目录下新建一个TextModule.java。在这个类中,咱们实现了具体的逻辑功能。数据库

package com.myNativeModule;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import java.text.SimpleDateFormat;
import java.util.Date;

public class TextModule {

    public void getTime(Context ctx) {
        SimpleDateFormat formatDate=new SimpleDateFormat("yyyy年MM月dd日  HH:mm:ss");
        Date date=new Date(System.currentTimeMillis());   //获取当前时间
        String s=formatDate.format(date);

        Log.e("HHH",s);
        Toast.makeText(ctx,s,Toast.LENGTH_SHORT).show();
    }

}

 
实现了获取当前时间功能后,咱们接下来就要暴露给React Native,以供js调用。
 react-native

3.3 暴露接口与数据交互

接下来咱们就要向React Native暴露接口以及作一些数据交互部分的操做。为了暴露接口以及进行数据交互咱们须要借助React Native的ReactContextBaseJavaModule 类。
 
(在android/app/src/main/java/com/myNativeModule目录下新建一个MyNativeModule.java。)
 android-studio

package com.myNativeModule;

import android.content.Context;
import android.widget.Toast;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class MyNativeModule extends ReactContextBaseJavaModule {
    private Context mContext;

    public MyNativeModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mContext = reactContext;
    }
    
    // 重载了getName()方法,用来暴露咱们原生模块的名字
    @Override  
    public String getName() {
        return "MyNativeModule";  // 返回的这个名字是必须的,是Native暴露给JS的名字
    }

    // 经过@ReactMethod注解来暴露接口,这样以来咱们就能够在js文件中经过MyNativeModule.rnCallNative()来调用咱们暴露给RN的接口了
    // 不能有返回值,由于被调用的原生代码是异步的,原生代码执行结束后只能经过回调函数或者发送消息给RN
    @ReactMethod 
    public void rnCallNative(String msg) {
        new TextModule().getTime(mContext);
    }
}

 

3.4 注册与导出React Native原生模块

为了向React Native注册咱们刚才建立的原生模块,咱们须要实现ReactPackage,ReactPackage主要为注册原生模块所存在,只有已经向React Native注册的模块才能在js模块使用。
 
(在android/app/src/main/java/com/myNativeModule目录下新建一个MyReactPackage.java。)
 多线程

package com.myNativeModule;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.myNativeModule.MyNativeModule;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MyReactPackage implements ReactPackage {

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {

        List<NativeModule> modules = new ArrayList<>();
        // 将咱们建立的类添加到原生模块中
        modules.add(new MyNativeModule(reactContext));
        return modules;
    }

    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

 
在上述代码中,咱们实现一个ReactPackage,接下来呢,咱们还须要在android/app/src/main/java/com/nativetest/MainApplication.java中注册咱们的MyReactPackage:
 app

@Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new MyReactPackage() // 在这里将咱们刚才建立的MyReactPackage添加进来
      );
    }

 

3.5 导出一个JS模块

原生模块注册完成以后呢,咱们接下来就须要为咱们的原生模块导出一个js模块,这样作的目的是在实际的项目中,为了更好的可读性和可维护性以及更方便地使用它。
 
在RN根目录的js/native/下建立一个native.js文件

import { NativeModules } from 'react-native';
export {
    MyNativeModule: NativeModules.MyNativeModule
}

 
接下来,咱们就能够在其余地方经过下面的方式来使用所导出的这个模块了。
 

import React, { Component } from 'react';
import {  StyleSheet, View, Button } from 'react-native';
import { MyNativeModule } from './native';

type Props = {};
export default class App extends Component<Props> {
    render() {
        return (
            <View style={styles.container}>
                <Button
                    onPress={this.call_button.bind(this)}
                    title="点击调用原生模块方法"
                />
            </View >
        );  
    }

    call_button() {
        MyNativeModule.rnCallNative('调用原生模块中的方法成功');
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    }
});

 
测试结果以下:
 

 

在上边的Demo中,主要是实现原生模块TestModule.java,而后咱们在要被RN调用的方法中调用原生类中的方法。对于N多原生类均可以直接粘贴复制过来。这样就能够实现调用复杂方法实现强大功能了。

Demo地址https://github.com/codeprolin/RN_Native_Android

相关文章
相关标签/搜索