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

相關文章
相關標籤/搜索