React-Native与Android、iOS原生代码交互,完
2018-05-22 本文已影响196人
小_蜡笔
首先我们先来看下iOS的代码
A4431638-2479-432B-938C-4843F8945518.png
#import <React/RCTBridgeModule.h>
@interface TakeViewManager : NSObject<RCTBridgeModule>
@end
#import "TakeViewManager.h"
@interface TakeViewManager ()
@end
@implementation TakeViewManager
// 标记宏(必要)
为了实现RCTBridgeModule协议,你的类需要包含RCT_EXPORT_MODULE()宏。这个宏也可以添加一个参数用来指定在Javascript中访问这个模块的名字。如果你不指定,默认就会使用这个Objective-C类的名字。
RCT_EXPORT_MODULE() 或者 RCT_EXPORT_MODULE(TakeViewManager)
// 对外提供调用方法(addEventCeshi为方法名,后面为参数,按顺序和对应数据类型在js进行传递)
RCT_EXPORT_METHOD(addEventCeshi:(NSString *)name callback:(RCTResponseSenderBlock)callback){
// 接收RN传过来了name
if([name isEqualToString:@"测试"]){
NSString *callbackData = [NSString stringWithFormat:@"处理结果:%@",name];
//回掉给JS
callback(@[[NSNull null],callbackData]);
}
}
@end
我们再来看下Android如何实现的,如图
56FE6AA5-9FF0-4816-AFF1-173553AB8C19.png
ReactContextBaseJavaModule : 用于自定义实现原生代码调用
继承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。
* 测试安卓的回调方法
* React Native的跨语言访问是异步进行的,所以想要给JavaScript返回一个值的唯一办法是使用回调函数或者发送事件
* */
@ReactMethod
public void addEventCeshi(String name, Callback callback) {
// 1.处理业务逻辑...
String result = "处理结果:" + name;
// 2.回调RN,即将处理结果返回给RN
callback.invoke(true,result);
}
/**
* return
* string
* 这个名字在JavaScript端标记这个模块
* 这样就可以在JavaScript中通过React.NativeModules.TakeViewManager访问到这个模块
* */
@Override
public String getName() {
return "TakeViewManager";
}
}
这个类其实就是实现原生代码的调用。
A24E2F87-AE9F-4441-ACA2-8CCB46DA86DD.png现在说另一个类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.
* 现在说另一个类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的应该对这个类并不陌生,其实就是这个Application的生命周期贯穿整个app程序。程序初始化会调用该类的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代码如何实现的
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,
},
});
最终看下实现iOS与Android的效果图
8B764809-65FC-40F6-9638-16440222C106.png