React-Native與Android、iOS原生代碼交互,完成JS發(fā)給原生,原生回調(diào)給RN頁面

首先我們先來看下iOS的代碼


A4431638-2479-432B-938C-4843F8945518.png
#import <React/RCTBridgeModule.h>

@interface TakeViewManager : NSObject<RCTBridgeModule>

@end
#import "TakeViewManager.h"

@interface TakeViewManager ()

@end
@implementation TakeViewManager

// 標(biāo)記宏(必要)
為了實現(xiàn)RCTBridgeModule協(xié)議,你的類需要包含RCT_EXPORT_MODULE()宏。這個宏也可以添加一個參數(shù)用來指定在Javascript中訪問這個模塊的名字。如果你不指定,默認(rèn)就會使用這個Objective-C類的名字。
RCT_EXPORT_MODULE() 或者   RCT_EXPORT_MODULE(TakeViewManager) 
//  對外提供調(diào)用方法(addEventCeshi為方法名,后面為參數(shù),按順序和對應(yīng)數(shù)據(jù)類型在js進(jìn)行傳遞)
RCT_EXPORT_METHOD(addEventCeshi:(NSString *)name callback:(RCTResponseSenderBlock)callback){
  //  接收RN傳過來了name
  if([name isEqualToString:@"測試"]){
    NSString *callbackData = [NSString stringWithFormat:@"處理結(jié)果:%@",name];
   //回掉給JS
    callback(@[[NSNull null],callbackData]);
  }
}
@end

我們再來看下Android如何實現(xiàn)的,如圖


56FE6AA5-9FF0-4816-AFF1-173553AB8C19.png

ReactContextBaseJavaModule : 用于自定義實現(xiàn)原生代碼調(diào)用
繼承ReactContextBaseJavaModule

package com.videodemo;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
/**
 * Created by wangjiawei on 2018/5/21.
 * 原生的代碼,之后與JS交互
 */

public class TakeViewModule extends ReactContextBaseJavaModule {

    public TakeViewModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }
    /**
     * 該方法就是給js使用
     * Java方法需要使用注解@ReactMethod。
     * 方法的返回類型必須為void。
     * 測試安卓的回調(diào)方法
     * React Native的跨語言訪問是異步進(jìn)行的,所以想要給JavaScript返回一個值的唯一辦法是使用回調(diào)函數(shù)或者發(fā)送事件
     * */
    @ReactMethod
    public void addEventCeshi(String name, Callback callback) {

        // 1.處理業(yè)務(wù)邏輯...
        String result = "處理結(jié)果:" + name;
        // 2.回調(diào)RN,即將處理結(jié)果返回給RN
        callback.invoke(true,result);
    }
    /**
     * return
     * string
     * 這個名字在JavaScript端標(biāo)記這個模塊
     * 這樣就可以在JavaScript中通過React.NativeModules.TakeViewManager訪問到這個模塊
     * */
    @Override
    public String getName() {
        return "TakeViewManager";
    }
}

這個類其實就是實現(xiàn)原生代碼的調(diào)用。

A24E2F87-AE9F-4441-ACA2-8CCB46DA86DD.png

現(xiàn)在說另一個類ReactPackage,其實該類的基本作用就是把繼承ReactContextBaseJavaModule類的方法注冊到JS里。如圖


2D013072-B04D-464E-BBA0-A85F7545F1B4.png

代碼如下

package com.videodemo;

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 java.util.List;
import java.util.Arrays;
import java.util.Collections;
/**
 * Created by wangjiawei on 2018/5/21.
 * 現(xiàn)在說另一個類ReactPackage,其實該類的基本作用就是把繼承ReactContextBaseJavaModule類的方法注冊到JS里
 */

public class TakeViewPackage implements ReactPackage {
//    其中就把TakeViewModule對象添加到modules這個list上。
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        return Arrays.<NativeModule>asList(new TakeViewModule(reactContext));
    }
//   返回Collections.emptyList();
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }
//  返回Collections.emptyList();
    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

最后一個java類Application,這個寫過Android的應(yīng)該對這個類并不陌生,其實就是這個Application的生命周期貫穿整個app程序。程序初始化會調(diào)用該類的onCreate方法。


48870AE4-144A-47D6-9124-CD42E2B7CFE7.png
package com.videodemo;

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 com.facebook.soloader.SoLoader;

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

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
              new TakeViewPackage() //自定義的package
      );
    }

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

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

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

原生的代碼到此寫完
來看下我們JS代碼如何實現(xiàn)的


B0D2D79E-D776-44CD-A5E1-EEC3F9BBBE5E.png

代碼如下

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  NativeModules,
  TouchableOpacity,
} from 'react-native';
var TakeViewManager = NativeModules.TakeViewManager;
type Props = {};
export default class App extends Component<Props> {
  ceshi(){
        TakeViewManager.addEventCeshi(('測試'),(error,events) =>{
            alert(events);
        });
  }
  render() {
    return (
      <View style={styles.container}>
         <TouchableOpacity onPress={()=>this.ceshi()}>
           <Text>測試</Text>
         </TouchableOpacity>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

最終看下實現(xiàn)iOS與Android的效果圖

8B764809-65FC-40F6-9638-16440222C106.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容