《React-Native系列》RN与native交互与数据传递

RN怎么与native交互的呢?

下面我们通过一个简单的Demo来实现:RN页面调起Native页面,Native页面选择电话本数据,将数据回传给RN展示。

首先是 Native侧

 1、MainActivity 

  1. package com.rnandroid01;  
  2.   
  3. import android.content.Intent;  
  4. import android.database.Cursor;  
  5. import android.net.Uri;  
  6. import android.provider.ContactsContract;  
  7.   
  8. import com.facebook.react.ReactActivity;  
  9.   
  10. public class MainActivity extends ReactActivity {  
  11.   
  12.     /** 
  13.      * Returns the name of the main component registered from JavaScript. 
  14.      * This is used to schedule rendering of the component. 
  15.      */  
  16.     @Override  
  17.     protected String getMainComponentName() {  
  18.         return "RNAndroid01";  
  19.     }  
  20.   
  21.   
  22.     @Override  
  23.     public void onActivityResult(int requestCode, int resultCode, Intent data) {  
  24.         super.onActivityResult(requestCode, resultCode, data);  
  25.         if(requestCode!=200 || resultCode!=RESULT_OK) return;  
  26.         Uri contactData = data.getData();  
  27.   
  28.         Cursor cursor = managedQuery(contactData, null, null, null, null);  
  29.         cursor.moveToFirst();  
  30.         String num = getContactPhone(cursor);  
  31.   
  32.   
  33.         //下面的话  就是将num发送给rn侧 需要调用nativeModule对象里面的方法  
  34.   
  35.         MainApplication.getMyReactPackage().myNativeModule.sendMsgToRn(num);  
  36.   
  37.     }  
  38.   
  39.    //这个是Native代码,与RN其实没什么关系  
  40.     private String getContactPhone(Cursor cursor) {  
  41.         // TODO Auto-generated method stub  
  42.         int phoneColumn = cursor  
  43.                 .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);  
  44.         int phoneNum = cursor.getInt(phoneColumn);  
  45.         String result = "";  
  46.         if (phoneNum > 0) {  
  47.             // 获得联系人的ID号  
  48.             int idColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID);  
  49.             String contactId = cursor.getString(idColumn);  
  50.             // 获得联系人电话的cursor  
  51.             Cursor phone = getContentResolver().query(  
  52.                     ContactsContract.CommonDataKinds.Phone.CONTENT_URI,  
  53.                     null,  
  54.                     ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "="  
  55.                             + contactId, null, null);  
  56.             if (phone.moveToFirst()) {  
  57.                 for (; !phone.isAfterLast(); phone.moveToNext()) {  
  58.                     int index = phone  
  59.                             .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);  
  60.                     int typeindex = phone  
  61.                             .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);  
  62.                     int phone_type = phone.getInt(typeindex);  
  63.                     String phoneNumber = phone.getString(index);  
  64.                     result = phoneNumber;  
  65.                 }  
  66.                 if (!phone.isClosed()) {  
  67.                     phone.close();  
  68.                 }  
  69.             }  
  70.         }  
  71.         return result;  
  72.     }  
  73.   
  74. }  


2、MainApplication

  1. package com.rnandroid01;  
  2.   
  3. import android.app.Application;  
  4. import android.util.Log;  
  5.   
  6. import com.facebook.react.ReactApplication;  
  7. import com.facebook.react.ReactInstanceManager;  
  8. import com.facebook.react.ReactNativeHost;  
  9. import com.facebook.react.ReactPackage;  
  10. import com.facebook.react.shell.MainReactPackage;  
  11.   
  12. import java.util.Arrays;  
  13. import java.util.List;  
  14.   
  15. public class MainApplication extends Application implements ReactApplication {  
  16.   
  17.   
  18.     private static final MyReactPackage myReactPackage=new MyReactPackage();  
  19.   
  20.     public static MyReactPackage getMyReactPackage() {  
  21.         return myReactPackage;  
  22.     }  
  23.   
  24.     private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {  
  25.     @Override  
  26.     protected boolean getUseDeveloperSupport() {  
  27.       return BuildConfig.DEBUG;  
  28.     }  
  29.   
  30.     @Override  
  31.     protected List<ReactPackage> getPackages() {  
  32.       return Arrays.<ReactPackage>asList(  
  33.           new MainReactPackage(),  
  34.               myReactPackage  
  35.       );  
  36.     }  
  37.   };  
  38.   
  39.   @Override  
  40.   public ReactNativeHost getReactNativeHost() {  
  41.       return mReactNativeHost;  
  42.   }  
  43. }  


3、MyReactPackage

  1. package com.rnandroid01;  
  2.   
  3. import com.facebook.react.ReactPackage;  
  4. import com.facebook.react.bridge.JavaScriptModule;  
  5. import com.facebook.react.bridge.NativeModule;  
  6. import com.facebook.react.bridge.ReactApplicationContext;  
  7. import com.facebook.react.uimanager.ViewManager;  
  8.   
  9. import java.util.ArrayList;  
  10. import java.util.Collections;  
  11. import java.util.List;  
  12.   
  13. public class MyReactPackage implements ReactPackage {  
  14.   
  15.     public MyNativeModule myNativeModule;  
  16.   
  17.     @Override  
  18.     public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {  
  19.         List<NativeModule> modules=new ArrayList<>();  
  20.         myNativeModule=new MyNativeModule(reactContext);  
  21.         modules.add(myNativeModule);  
  22.         return modules;  
  23.     }  
  24.   
  25.     @Override  
  26.     public List<Class<? extends JavaScriptModule>> createJSModules() {  
  27.         return Collections.emptyList();  
  28.     }  
  29.   
  30.     @Override  
  31.     public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {  
  32.         return Collections.emptyList();  
  33.     }  
  34. }  


4、MyNativeModule

  1. package com.rnandroid01;  
  2.   
  3. import android.content.Context;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.provider.ContactsContract;  
  7. import android.widget.Toast;  
  8.   
  9. import com.facebook.react.bridge.ReactApplicationContext;  
  10. import com.facebook.react.bridge.ReactContextBaseJavaModule;  
  11. import com.facebook.react.bridge.ReactMethod;  
  12. import com.facebook.react.modules.core.DeviceEventManagerModule;  
  13.   
  14.   
  15. public class MyNativeModule extends ReactContextBaseJavaModule {  
  16.   
  17.     private ReactApplicationContext mContext;  
  18.   
  19.     public MyNativeModule(ReactApplicationContext reactContext) {  
  20.         super(reactContext);  
  21.   
  22.         mContext = reactContext;  
  23.     }  
  24.   
  25.     @Override  
  26.     public String getName() {  
  27.         //一定要有这个名字的 在rn代码里面是需要这个名字来调用该类的方法的  
  28.         return "MyNativeModule";  
  29.     }  
  30.   
  31.     //函数不能有返回值,因为被调用的原生代码是异步的,原生代码执行结束之后只能通过回调函数或者发送消息给rn那边  
  32.   
  33.     //有一个错误  
  34.   
  35.     @ReactMethod  
  36.     public void rnCallNative(String msg) {  
  37.         Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();  
  38.   
  39.   
  40. //        Intent intent = new Intent(mContext, MyActivity.class);  
  41. //        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//一定要加上这句 否则报错  
  42. //        mContext.startActivity(intent);  
  43.   
  44.   
  45.         Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);  
  46.         Bundle bundle = new Bundle();  
  47.         mContext.startActivityForResult(intent,200,bundle);  
  48.   
  49.   
  50.     }  
  51.   
  52.     public void sendMsgToRn(String msg){  
  53.         //将消息msg发送给RN侧  
  54.         mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("AndroidToRNMessage",msg);  
  55.   
  56.     }  
  57.   
  58. }  

 

在RN侧

 
  1. /** 
  2.  * Sample React Native App 
  3.  * https://github.com/facebook/react-native 
  4.  * @flow 
  5.  */  
  6.   
  7. import React, { Component } from 'react';  
  8. import {  
  9.   AppRegistry,  
  10.   StyleSheet,  
  11.   Text,  
  12.   NativeModules,  
  13.   DeviceEventEmitter,  
  14.   View  
  15. } from 'react-native';  
  16.   
  17. class RNAndroid01 extends Component {  
  18.    
  19.   
  20.   componentWillMount(){  
  21.     DeviceEventEmitter.addListener('AndroidToRNMessage',this.handleAndroidMessage);  
  22.   }  
  23.   
  24.   componentWillunMount(){  
  25.      DeviceEventEmitter.remove('AndroidToRNMessage',this.handleAndroidMessage);  
  26.   }  
  27.   
  28.   
  29.   handleAndroidMessage=(msg)=>{  
  30.      //RN端获得native端传递的数据  
  31.      console.log(msg);  
  32.   }  
  33.   
  34.   
  35.   render() {  
  36.     return (  
  37.       <View style={styles.container}>  
  38.         <Text style={styles.welcome}  
  39.         onPress={this.CallAndroid}  
  40.         >  
  41.           Welcome to React Native!RN与Android的通信  
  42.         </Text>  
  43.         <Text style={styles.instructions}>  
  44.           To get started, edit index.android.js  
  45.         </Text>  
  46.         <Text style={styles.instructions}>  
  47.           Shake or press menu button for dev menu  
  48.         </Text>  
  49.       </View>  
  50.     );  
  51.   }  
  52.   
  53.   
  54.   CallAndroid=()=>{  
  55.     NativeModules.MyNativeModule.rnCallNative('rn调用原生模块的方法-成功啦');  
  56.   }  
  57. }  



上面的例子实现了RN与Native端的交互及数据传递。

 

重点使用了React Native的RCTDeviceEventEmitter,通过消息机制来实现。

好了,RN与native的交互还可以通过Promise和Callback回调方式实现,我们下篇文章再看。

 

引用原文:http://blog.csdn.net/codetomylaw/article/details/51926421

 

写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,文章可以转载,无需版权。希望尽自己的努力,做到更好,大家一起努力进步!

如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!

posted @ 2017-09-20 08:52  緈諨の約錠  阅读(539)  评论(0编辑  收藏  举报
//用户复制动作发生0.1秒以后再去改粘贴板中的内容。100ms只是一个经常取值,写1000、10、50、200……都行。