《React-Native系列》RN與native交互與數據傳遞
阿新 • • 發佈:2017-09-20
lis 寫博客 android undle tco intent pack instance isa
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);
- }
- }
在RN側
- /**
- * 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回調方式實現,我們下篇文章再看。
引用原文:http://blog.csdn.net/codetomylaw/article/details/51926421
寫博客是為了記住自己容易忘記的東西,另外也是對自己工作的總結,文章可以轉載,無需版權。希望盡自己的努力,做到更好,大家一起努力進步!
如果有什麽問題,歡迎大家一起探討,代碼如有問題,歡迎各位大神指正!
《React-Native系列》RN與native交互與數據傳遞