1. 程式人生 > >《React-Native系列》RN與native交互與數據傳遞

《React-Native系列》RN與native交互與數據傳遞

lis 寫博客 android undle tco intent pack instance isa

RN怎麽與native交互的呢?

下面我們通過一個簡單的Demo來實現:RN頁面調起Native頁面,Native頁面選擇電話本數據,將數據回傳給RN展示。

首先是 Native側

1、MainActivity

  1. package com.rnandroid01;
  2. import android.content.Intent;
  3. import android.database.Cursor;
  4. import android.net.Uri;
  5. import android.provider.ContactsContract;
  6. import com.facebook.react.ReactActivity;
  7. public class MainActivity extends ReactActivity {
  8. /**
  9. * Returns the name of the main component registered from JavaScript.
  10. * This is used to schedule rendering of the component.
  11. */
  12. @Override
  13. protected String getMainComponentName() {
  14. return "RNAndroid01";
  15. }
  16. @Override
  17. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  18. super.onActivityResult(requestCode, resultCode, data);
  19. if(requestCode!=200 || resultCode!=RESULT_OK) return;
  20. Uri contactData = data.getData();
  21. Cursor cursor = managedQuery(contactData, null, null, null, null);
  22. cursor.moveToFirst();
  23. String num = getContactPhone(cursor);
  24. //下面的話 就是將num發送給rn側 需要調用nativeModule對象裏面的方法
  25. MainApplication.getMyReactPackage().myNativeModule.sendMsgToRn(num);
  26. }
  27. //這個是Native代碼,與RN其實沒什麽關系
  28. private String getContactPhone(Cursor cursor) {
  29. // TODO Auto-generated method stub
  30. int phoneColumn = cursor
  31. .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
  32. int phoneNum = cursor.getInt(phoneColumn);
  33. String result = "";
  34. if (phoneNum > 0) {
  35. // 獲得聯系人的ID號
  36. int idColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID);
  37. String contactId = cursor.getString(idColumn);
  38. // 獲得聯系人電話的cursor
  39. Cursor phone = getContentResolver().query(
  40. ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
  41. null,
  42. ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "="
  43. + contactId, null, null);
  44. if (phone.moveToFirst()) {
  45. for (; !phone.isAfterLast(); phone.moveToNext()) {
  46. int index = phone
  47. .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
  48. int typeindex = phone
  49. .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
  50. int phone_type = phone.getInt(typeindex);
  51. String phoneNumber = phone.getString(index);
  52. result = phoneNumber;
  53. }
  54. if (!phone.isClosed()) {
  55. phone.close();
  56. }
  57. }
  58. }
  59. return result;
  60. }
  61. }


2、MainApplication

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


3、MyReactPackage

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


4、MyNativeModule

  1. package com.rnandroid01;
  2. import android.content.Context;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.provider.ContactsContract;
  6. import android.widget.Toast;
  7. import com.facebook.react.bridge.ReactApplicationContext;
  8. import com.facebook.react.bridge.ReactContextBaseJavaModule;
  9. import com.facebook.react.bridge.ReactMethod;
  10. import com.facebook.react.modules.core.DeviceEventManagerModule;
  11. public class MyNativeModule extends ReactContextBaseJavaModule {
  12. private ReactApplicationContext mContext;
  13. public MyNativeModule(ReactApplicationContext reactContext) {
  14. super(reactContext);
  15. mContext = reactContext;
  16. }
  17. @Override
  18. public String getName() {
  19. //一定要有這個名字的 在rn代碼裏面是需要這個名字來調用該類的方法的
  20. return "MyNativeModule";
  21. }
  22. //函數不能有返回值,因為被調用的原生代碼是異步的,原生代碼執行結束之後只能通過回調函數或者發送消息給rn那邊
  23. //有一個錯誤
  24. @ReactMethod
  25. public void rnCallNative(String msg) {
  26. Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
  27. // Intent intent = new Intent(mContext, MyActivity.class);
  28. // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//一定要加上這句 否則報錯
  29. // mContext.startActivity(intent);
  30. Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
  31. Bundle bundle = new Bundle();
  32. mContext.startActivityForResult(intent,200,bundle);
  33. }
  34. public void sendMsgToRn(String msg){
  35. //將消息msg發送給RN側
  36. mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("AndroidToRNMessage",msg);
  37. }
  38. }

在RN側

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



上面的例子實現了RN與Native端的交互及數據傳遞。

重點使用了React Native的RCTDeviceEventEmitter,通過消息機制來實現。

好了,RN與native的交互還可以通過Promise和Callback回調方式實現,我們下篇文章再看。

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

寫博客是為了記住自己容易忘記的東西,另外也是對自己工作的總結,文章可以轉載,無需版權。希望盡自己的努力,做到更好,大家一起努力進步!

如果有什麽問題,歡迎大家一起探討,代碼如有問題,歡迎各位大神指正!

《React-Native系列》RN與native交互與數據傳遞