首先我們先來看下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