iOS技术我爱编程

React-Native与Android、iOS原生代码交互,完

2018-05-22  本文已影响196人  小_蜡笔

首先我们先来看下iOS的代码


A4431638-2479-432B-938C-4843F8945518.png
#import <React/RCTBridgeModule.h>

@interface TakeViewManager : NSObject<RCTBridgeModule>

@end
#import "TakeViewManager.h"

@interface TakeViewManager ()

@end
@implementation TakeViewManager

// 标记宏(必要)
为了实现RCTBridgeModule协议,你的类需要包含RCT_EXPORT_MODULE()宏。这个宏也可以添加一个参数用来指定在Javascript中访问这个模块的名字。如果你不指定,默认就会使用这个Objective-C类的名字。
RCT_EXPORT_MODULE() 或者   RCT_EXPORT_MODULE(TakeViewManager) 
//  对外提供调用方法(addEventCeshi为方法名,后面为参数,按顺序和对应数据类型在js进行传递)
RCT_EXPORT_METHOD(addEventCeshi:(NSString *)name callback:(RCTResponseSenderBlock)callback){
  //  接收RN传过来了name
  if([name isEqualToString:@"测试"]){
    NSString *callbackData = [NSString stringWithFormat:@"处理结果:%@",name];
   //回掉给JS
    callback(@[[NSNull null],callbackData]);
  }
}
@end

我们再来看下Android如何实现的,如图


56FE6AA5-9FF0-4816-AFF1-173553AB8C19.png

ReactContextBaseJavaModule : 用于自定义实现原生代码调用
继承ReactContextBaseJavaModule

package com.videodemo;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
/**
 * Created by wangjiawei on 2018/5/21.
 * 原生的代码,之后与JS交互
 */

public class TakeViewModule extends ReactContextBaseJavaModule {

    public TakeViewModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }
    /**
     * 该方法就是给js使用
     * Java方法需要使用注解@ReactMethod。
     * 方法的返回类型必须为void。
     * 测试安卓的回调方法
     * React Native的跨语言访问是异步进行的,所以想要给JavaScript返回一个值的唯一办法是使用回调函数或者发送事件
     * */
    @ReactMethod
    public void addEventCeshi(String name, Callback callback) {

        // 1.处理业务逻辑...
        String result = "处理结果:" + name;
        // 2.回调RN,即将处理结果返回给RN
        callback.invoke(true,result);
    }
    /**
     * return
     * string
     * 这个名字在JavaScript端标记这个模块
     * 这样就可以在JavaScript中通过React.NativeModules.TakeViewManager访问到这个模块
     * */
    @Override
    public String getName() {
        return "TakeViewManager";
    }
}

这个类其实就是实现原生代码的调用。

A24E2F87-AE9F-4441-ACA2-8CCB46DA86DD.png

现在说另一个类ReactPackage,其实该类的基本作用就是把继承ReactContextBaseJavaModule类的方法注册到JS里。如图


2D013072-B04D-464E-BBA0-A85F7545F1B4.png

代码如下

package com.videodemo;

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.List;
import java.util.Arrays;
import java.util.Collections;
/**
 * Created by wangjiawei on 2018/5/21.
 * 现在说另一个类ReactPackage,其实该类的基本作用就是把继承ReactContextBaseJavaModule类的方法注册到JS里
 */

public class TakeViewPackage implements ReactPackage {
//    其中就把TakeViewModule对象添加到modules这个list上。
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        return Arrays.<NativeModule>asList(new TakeViewModule(reactContext));
    }
//   返回Collections.emptyList();
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }
//  返回Collections.emptyList();
    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

最后一个java类Application,这个写过Android的应该对这个类并不陌生,其实就是这个Application的生命周期贯穿整个app程序。程序初始化会调用该类的onCreate方法。


48870AE4-144A-47D6-9124-CD42E2B7CFE7.png
package com.videodemo;

import android.app.Application;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

import java.util.Arrays;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
              new TakeViewPackage() //自定义的package
      );
    }

    @Override
    protected String getJSMainModuleName() {
      return "index";
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
  }
}

原生的代码到此写完
来看下我们JS代码如何实现的


B0D2D79E-D776-44CD-A5E1-EEC3F9BBBE5E.png

代码如下

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  NativeModules,
  TouchableOpacity,
} from 'react-native';
var TakeViewManager = NativeModules.TakeViewManager;
type Props = {};
export default class App extends Component<Props> {
  ceshi(){
        TakeViewManager.addEventCeshi(('测试'),(error,events) =>{
            alert(events);
        });
  }
  render() {
    return (
      <View style={styles.container}>
         <TouchableOpacity onPress={()=>this.ceshi()}>
           <Text>测试</Text>
         </TouchableOpacity>
      </View>
    );
  }
}

const styles = 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,
  },
});

最终看下实现iOS与Android的效果图

8B764809-65FC-40F6-9638-16440222C106.png
上一篇下一篇

猜你喜欢

热点阅读