React native 與Android原生互動方式(一)
前言##
最近在做React Native開發的時候避免不了的需要原生模組和JS之間進行互動,其實RN和原生的通訊大致分為兩種情況;一種是Android主動向RN端傳送事件和資料,另外一種是RN端被動向Android詢問獲取事件和資料,接下來的幾篇文章將向大家分享原生模組向JS互動的幾種方式。
1、傳送事件的方式
2、callback方式
3、Promise方式
由於篇幅原因本文只對傳送事件的方式進行詳細介紹
傳送事件的方式
使用了React Native的RCTDeviceEventEmitter,通過訊息機制來實現,原生可以向JS傳遞事件而不需要直接的呼叫,就像我們android中的廣播。
下面通就像大家暫時通過RCTDeviceEventEmitter來向JS傳遞事件。
原生模組中(Android端):
首先定義Module類:MyModule.java
public class MyModule extends ReactContextBaseJavaModule {
private final String TAG = MyModule.class.getName();
public MyModule(ReactApplicationContext reactContext) {
super(reactContext);
//給上下文物件賦值
Test.mContext = reactContext;
}
//不能用return tag 來實現 不然不能呼叫方法...原因不理解
@Override
public String getName() {
return "MyModule";
}
@ReactMethod
public void callNativeBySend(){
//呼叫Test類中的原生方法。
Log.e("wangfang","called send");
new Test().fun();
}
}
傳送事件的程式碼在Test類中,
Test.java程式碼段如下:
public class Test {
public static ReactContext mContext;
public void fun()
{
//在該方法中開啟執行緒,並且延遲3秒,然後向JavaScript端傳送事件。
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//傳送事件,事件名為EventName
WritableMap et= Arguments.createMap();
sendEvent(mContext,"EventName",et);
}
}).start();
}
//定義傳送事件的函式
public void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params)
{
System.out.println("reactContext="+reactContext);
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName,params);//原生調Rn
}
}
從上述程式碼可以看到,原生向JS模組傳送了一個名為“EventName”的事件,並攜帶了"et"作為引數,那大家肯定會問JS中如何接收事件並進行處理呢,別急。。。。
先把原生的程式碼說完,得把模組新增到包中
MyPackage程式碼如下:
public class MyPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new MyModule(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
接著RN依附的Activity程式碼如下:
public class RnAndroidCommuActivity extends ReactActivity{
@Override
public String getMainComponentName() {
return "testNative";
}
}
原生的Activity的程式碼:
public class NativeActivity extends Activity {
private Button btnGoReact;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnGoReact = (Button)this.findViewById(R.id.btn_go_react);
btnGoReact.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(NativeActivity.this,RnAndroidCommuActivity.class);
intent.putExtra("result","native go to react");
startActivity(intent);
}
});
}
activity_main資原始檔的程式碼:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.wangfang.rnproject.MainActivity">
<Button
android:id="@+id/btn_go_react"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="原生介面跳轉React介面"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
還有清單檔案 這裡就不貼程式碼了,相信做過Android的專案都知道咋寫吧。。。
RN端的程式碼:
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
DeviceEventEmitter,
NativeModules,
View,
TextInput
} from 'react-native';
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
DeviceEventEmitter,
NativeModules,
View,
TextInput
} from 'react-native';
export class RnAndroidCommunication extends React.Component{
componentWillMount(){
DeviceEventEmitter.addListener("EventName",()=>{
this.showState();
alert("send event success");
});
}
constructor(props){
super(props);
this.state={
content:"這是個預定的接受訊息"
}
}
render(){
return (
<View style = {myStyles.container}>
<Text style = {myStyles.welcome} onPress={this.callNative.bind(this)}>
當你點我的時候會呼叫原生方法,原生方法延遲3s後會向前端傳送事件。
前端一直在監聽該事件,如果收到,則給出alert提示! send 方式
</Text>
<Text style = {myStyles.instructions}>
{this.state.content}
</Text>
</View>
);
}
callNative(){
console.log(" js called by send");
NativeModules.MyModule.callNativeBySend();
}
showState(){
this.setState({content:"已經收到了原生模組傳送來的事件,send event 方式"});
}
}
const myStyles = 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,
},
});
AppRegistry.registerComponent('testNative', () => RnAndroidCommunication);
在JS中通過 DeviceEventEmitter 註冊監聽了名為“”的事件,當原生模組發出名為“EventName”的事件後,繫結在該事件上的 EventName = () 會被回撥。 然後通過就可獲得事件所攜帶的資料,並執行回撥函式,進行頁面顯示燈。
心得:如果在JS中有多處註冊了 EventName 事件,那麼當原生模組發出事件後,這些地方會同時收到該事件。不過大家也可以通過 DeviceEventEmitter.removeListener('onScanningResult',this.onScanningResult) 來移除對名為“EventName”事件的監聽。
相關文章
- react native 和原生平臺 android的互動React NativeAndroid
- React Native與Android通訊互動React NativeAndroid
- Flutter 與Native原生互動Flutter
- RN 與android原生互動Android
- Android中程式與Service互動的方式——互動方式Android
- Android 原生 WebView 與 JavaScript 互動AndroidWebViewJavaScript
- React Native 互動元件之 SwitchReact Native元件
- 原生移動應用框架React Native與Flutter比較框架React NativeFlutter
- React-native 橋接Android原生開發React橋接Android
- flutter和Android原生互動FlutterAndroid
- 隨手記Android JS與Native互動實踐AndroidJS
- React Native填坑之旅--使用原生檢視AndroidReact NativeAndroid
- 深入淺析React Native與web的基本互動(附程式碼)React NativeWeb
- oc 與js 的原生互動JS
- React Native Android 啟動異常React NativeAndroid
- iOS原生專案整合 React Native 一 導航iOSReact Native
- 在 React Native 中原生實現動態匯入React Native
- Android中程式與Service互動的方式——綜述Android
- Android中程式與Service互動的方式——總結Android
- react native ScrollView巢狀WebView 互動問題React Native巢狀WebView
- Android 原生和 JS 互動實踐AndroidJS
- React Native學習指南:React Native嵌入到原生應用的一次嘗試React Native
- 使用React Native和Expo快速構建原生移動iOS和Android應用程式React NativeiOSAndroid
- 利用 Native.js 實現 Android 與 HTML 資料的互動JSAndroidHTML
- React Native 橋接原生 iOS 以及 Android 獲取 APP 版本號React Native橋接iOSAndroidAPP
- [譯] React Native 與 iOS 和 Android 通訊React NativeiOSAndroid
- Android 與前端互動Android前端
- 使 React Native App 更具原生質感React NativeAPP
- React Native整合到原生專案示例React Native
- JS原生互動JS
- js和原生應用常用的資料互動方式JS
- 一次掌握 React 與 React Native 兩個框架React Native框架
- react-native 仿原生自定義彈窗|iOS/Android 彈窗效果ReactiOSAndroid
- react-native 在匯入android原生庫容易遇到的問題ReactAndroid
- 在Android原生應用中整合React Native版本的豆瓣電影AndroidReact Native
- C#與Python互動方式C#Python
- Http(s)與後臺互動方式HTTP
- h5與native互動總結1H5