RN怎么与native交互的呢? 下面我们通过一个简单的Demo来实现:RN页面调起Native页面,Native页面选择电话本数据,将数据回传给RN展示。 首先是 Native侧 1、MainActivity package com.rnandroid01; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; import com.facebook.react.ReactActivity; public class MainActivity extends ReactActivity { /** * Returns the name of the main component registered from JavaScript. * This is used to schedule rendering of the component. */ @Override protected String getMainComponentName() { return "RNAndroid01"; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode!=200 || resultCode!=RESULT_OK) return; Uri contactData = data.getData(); Cursor cursor = managedQuery(contactData, null, null, null, null); cursor.moveToFirst(); String num = getContactPhone(cursor); //下面的话 就是将num发送给rn侧 需要调用nativeModule对象里面的方法 MainApplication.getMyReactPackage().myNativeModule.sendMsgToRn(num); } //这个是Native代码,与RN其实没什么关系 private String getContactPhone(Cursor cursor) { // TODO Auto-generated method stub int phoneColumn = cursor .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER); int phoneNum = cursor.getInt(phoneColumn); String result = ""; if (phoneNum > 0) { // 获得联系人的ID号 int idColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID); String contactId = cursor.getString(idColumn); // 获得联系人电话的cursor Cursor phone = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null); if (phone.moveToFirst()) { for (; !phone.isAfterLast(); phone.moveToNext()) { int index = phone .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); int typeindex = phone .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE); int phone_type = phone.getInt(typeindex); String phoneNumber = phone.getString(index); result = phoneNumber; } if (!phone.isClosed()) { phone.close(); } } } return result; } } 2、MainApplication package com.rnandroid01; import android.app.Application; import android.util.Log; import com.facebook.react.ReactApplication; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.shell.MainReactPackage; import java.util.Arrays; import java.util.List; public class MainApplication extends Application implements ReactApplication { private static final MyReactPackage myReactPackage=new MyReactPackage(); public static MyReactPackage getMyReactPackage() { return myReactPackage; } private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override protected boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), myReactPackage ); } }; @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } } 3、MyReactPackage package com.rnandroid01; 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.ArrayList; import java.util.Collections; import java.util.List; public class MyReactPackage implements ReactPackage { public MyNativeModule myNativeModule; @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules=new ArrayList<>(); myNativeModule=new MyNativeModule(reactContext); modules.add(myNativeModule); return modules; } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } } 4、MyNativeModule package com.rnandroid01; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.provider.ContactsContract; import android.widget.Toast; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.modules.core.DeviceEventManagerModule; public class MyNativeModule extends ReactContextBaseJavaModule { private ReactApplicationContext mContext; public MyNativeModule(ReactApplicationContext reactContext) { super(reactContext); mContext = reactContext; } @Override public String getName() { //一定要有这个名字的 在rn代码里面是需要这个名字来调用该类的方法的 return "MyNativeModule"; } //函数不能有返回值,因为被调用的原生代码是异步的,原生代码执行结束之后只能通过回调函数或者发送消息给rn那边 //有一个错误 @ReactMethod public void rnCallNative(String msg) { Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show(); // Intent intent = new Intent(mContext, MyActivity.class); // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//一定要加上这句 否则报错 // mContext.startActivity(intent); Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); Bundle bundle = new Bundle(); mContext.startActivityForResult(intent,200,bundle); } public void sendMsgToRn(String msg){ //将消息msg发送给RN侧 mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("AndroidToRNMessage",msg); } }
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, NativeModules, DeviceEventEmitter, View } from 'react-native'; class RNAndroid01 extends Component { componentWillMount(){ DeviceEventEmitter.addListener('AndroidToRNMessage',this.handleAndroidMessage); } componentWillunMount(){ DeviceEventEmitter.remove('AndroidToRNMessage',this.handleAndroidMessage); } handleAndroidMessage=(msg)=>{ //RN端获得native端传递的数据 console.log(msg); } render() { return ( <View style={styles.container}> <Text style={styles.welcome} onPress={this.CallAndroid} > Welcome to React Native!RN与Android的通信 </Text> <Text style={styles.instructions}> To get started, edit index.android.js </Text> <Text style={styles.instructions}> Shake or press menu button for dev menu </Text> </View> ); } CallAndroid=()=>{ NativeModules.MyNativeModule.rnCallNative('rn调用原生模块的方法-成功啦'); } } 上面的例子实现了RN与Native端的交互及数据传递。
重点使用了React Native的RCTDeviceEventEmitter,通过消息机制来实现。 好了,RN与native的交互还可以通过Promise和Callback回调方式实现,我们下篇文章再看。
|
|
来自: 就这样了__ > 《react-native》