react native与android和iOS交互 (1) - LewinJun/reactNative GitHub Wiki
关键字: RCTBridgeMethod(RCTResponseSenderBlock,RCTResponseErrorBlock,RCTPromiseResolveBlock,RCTPromiseRejectBlock) RCTDeviceEventEmitter, Callback, Promise
js主导,js调用一次,native返回一次(iOS提供给reactjs调用比android方便许多,后面再看安卓的交互方式就知道了)
- iOS原生代码,实现RCTBridgeModule类的协议
PublicReactModules.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
@interface PublicReactModules : NSObject<RCTBridgeModule>
@end
PublicReactModules.m
#import "PublicReactModules.h"
@implementation PublicReactModules
//导出此类为React NativeModules
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(twoNumberTotal:(int)a b:(int)b callback:(RCTResponseSenderBlock)callback){
callback(@[@(a + b)]);
}
RCT_EXPORT_METHOD(test:(NSString*)a){
NSLog(@"%@", a);
}
@end
- Android原生代码 PublicReactModules.java
import android.util.Log;
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 lewin on 2017/7/26.
*/
public class PublicReactModules extends ReactContextBaseJavaModule {
public PublicReactModules(ReactApplicationContext reactContext) {
super(reactContext);
}
//react NativeModules调用的名称,iOS默认为类名,这里必须iOS和安卓名称一致,不然reactjs需要区分安卓还是iOS
@Override
public String getName() {
return "PublicReactModules";
}
@ReactMethod
public void test(String msg){
Log.d("react",msg);
}
@ReactMethod
public void twoNumberTotal(int a, int b, Callback callback){
callback.invoke(a+b);
}
}添加package
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.ihr.reactnative.modules.PublicReactModules;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by lewin on 2017/7/26.
* native与react交互包管理
*/
public class AppReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules=new ArrayList<>();
modules.add(new PublicReactModules(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
/**
*
* @param reactContext
* @return 自定义View组件
*/
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}最后就是要把AppReactPackage注入到react模块里面,当然是哪里调用哪里注入
public class ReactNativeActivity extends Activity implements DefaultHardwareBackBtnHandler {
private final int MY_PERMISSIONS_REQUEST_READ_CONTACTS = 111;
/**
* react 布局view
*/
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mReactRootView = (ReactRootView)findViewById(R.id.react_view);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName(bundleAssetName)
.setJSMainModuleName(jsMainModuleName)
.addPackage(new MainReactPackage())
//把自定义的package注入到react交互中心去
.addPackage(new AppReactPackage())
/**
* 调试模式下,建议直接写成 true 吧,我就因为这个错误,调了两天原因
*/
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setUseDeveloperSupport(true)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, moduleName, null);
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.SYSTEM_ALERT_WINDOW},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause();
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.facebook.react.ReactRootView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/react_view"
/>
</LinearLayout>- reactjs调用部分代码,在 index.ios.js和index.android.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
NativeModules,
Button,
Alert,
View
} from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to zuo React Native hello react fetch get post For android!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
<Button
onPress={this._onPress}
title="测试交互"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
<Button
onPress={this._addPress}
title="5+8等于多少?"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
);
}
_onPress() {
//PublicReactModules这个就是
var publicUtil = NativeModules.PublicReactModules;
publicUtil.test(data);
}
_addPress(){
var PublicUtil= NativeModules.PublicUtil;
PublicUtil.twoNumberTotal(5, 8,(msg)=>{
Alert.alert(
'Alert Title',
"CallBack收到消息:"+msg,
)
});
}
}
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,
},
btn: {
width: 100,
height: 50,
alignItems: 'center',
justifyContent: 'center',
alignSelf: 'center',
},
btnText: {
fontSize: 18
}
});
AppRegistry.registerComponent('reactLewinDemo', () => App);