概述

有时候App需要访问平台API,但React Native可能还没有相应的模块包装;或者你需要复用一些Java代码,而不是用Javascript重新实现一遍;又或者你需要实现某些高性能的、多线程的代码,譬如图片处理、数据库、或者各种高级扩展等等。
我们知道React Native本身对这种偏业务和底层调用是不关心的,这时候我们就想到了原生组件,我们通过调用原生组件,然后经过特定的封装来达到效果。如我们在原生开发中常见的Toast为例:

原生模块封装

假设我们希望可以从Javascript发起一个Toast消息,Android会显示在屏幕的下方,会停留一段时间。我们来看一下官方给出的例子。

创建一个继承了ReactContextBaseJavaModule的Java类,它可以实现一些JavaScript所需的功能。我们这里的目标是可以在JavaScript里写ToastAndroid.show('Awesome', ToastAndroid.SHORT);,来调起一个Toast通知。

package com.facebook.react.modules.toast;import android.widget.Toast;import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;import java.util.Map;public class ToastModule extends ReactContextBaseJavaModule {private static final String DURATION_SHORT_KEY = "SHORT";private static final String DURATION_LONG_KEY = "LONG";public ToastModule(ReactApplicationContext reactContext) {super(reactContext);}
}

ReactContextBaseJavaModule要求派生类实现getName方法,这个名字返回的字符串可以自取,但是不能命名为'ToastAndroid',因为RN已经内置了一个名为ToastAndroid的模块,运行时会报错名字冲突!

  @Overridepublic String getName() {return "ToastAndroid";}

注:模块名前的RCT前缀会被自动移除。所以如果返回的字符串为"RCTToastAndroid",在JavaScript端依然通过React.NativeModules.ToastAndroid访问到这个模块。
接下来我们需要设置一个可选的方法getContants(),用于弹出时间选择(及Toast.Length)

 @Overridepublic Map<String, Object> getConstants() {final Map<String, Object> constants = new HashMap<>();constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);return constants;}

最后导出一个方法给JavaScript使用。

 @ReactMethodpublic void show(String message, int duration) {Toast.makeText(getReactApplicationContext(), message, duration).show();}

在Java这边要做的最后一件事就是注册这个模块。我们需要在应用的Package类的createNativeModules方法中添加这个模块。如果模块没有被注册,它也无法在JavaScript中被访问到。

class AnExampleReactPackage implements ReactPackage {@Overridepublic List<Class<? extends JavaScriptModule>> createJSModules() {return Collections.emptyList();}@Overridepublic List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {return Collections.emptyList();}@Overridepublic List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {List<NativeModule> modules = new ArrayList<>();modules.add(new ToastModule(reactContext));return modules;}

这个package需要在MainApplication.java文件的getPackages方法中提供。这个文件位于你的react-native应用文件夹的android目录中。具体路径是: android/app/src/main/java/com/your-app-name/MainApplication.java.

protected List<ReactPackage> getPackages() {return Arrays.<ReactPackage>asList(new MainReactPackage(),new AnExampleReactPackage()); // <-- 添加这一行,类名替换成你的Package类的名字.
}

那么在React Native中怎么使用呢?为了让你的功能从JavaScript端访问起来更为方便,通常我们都会把原生模块封装成一个JavaScript模块。

'use strict';import { NativeModules } from 'react-native';export default NativeModules.ToastAndroid;

最后调用javascript模块就好了。

import ToastAndroid from './ToastAndroid';
ToastAndroid.show('Awesome', ToastAndroid.SHORT);

未完待续..

React Native调用原生模块相关推荐

  1. React Native Android原生模块开发实战|教程|心得|怎样创建React Native Android原生模块...

    尊重版权,未经授权不得转载 本文出自:贾鹏辉的技术博客(http://blog.csdn.net/fengyuzhengfan/article/details/54691503) 告诉大家一个好消息. ...

  2. Android React Native使用原生UI组件

    Android React Native 已经将几个常用的原生组件进行了封装,比如 ScrollView 和 TextInput,但是并不是所有系统的原始组件都被封装了,因此有的时候我们不得不自己动手 ...

  3. React Native调用Android接口

    由于工作需要近期研究了下React Native调用Android接口,该文章将介绍自己在RN环境搭建和封装第三方SDK接口以及RN调用Android接口的趟坑过程.(第一次写博客,写的不好请大家勿喷 ...

  4. React Native与原生的图片交互问题

    项目中的一个需求:在原生系统中调用第三方SDK识别身份证后将获取的信息和图片返回到React Native JSX页面上展示. 首先React Native与原生通信的方式可以采用CallBack 和 ...

  5. Android方法调用实体类的值,React Native调用Android原生方法和传值

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 创建react native 项目:react-native init callAndroidProject cd ca ...

  6. React Native调用Android原生代码实现车牌识别功能【附效果图附源码】

    转载请注明出处,原文地址:http://blog.csdn.net/lucherr/article/details/71908180 这段时间研究了下React Native,Facebook推出的, ...

  7. React Native之AppRegistry模块

    我们在写react native的js的时候,在最后总会加上一段代码: AppRegistry.registerComponent('ReactDemo', () => ReactDemo); ...

  8. android ios 混合编程,React Native与原生(Android、iOS)混编,三端痛点解析

    在做RN混编项目的时候或者面试的时候经常会遇到一些问题,总结起来有以下几种: 1.过多的注册RN组件( AppRegistry.registerComponent() ); 2.从原生跳转指定的RN页 ...

  9. react native 调用手机内置地图

    GitHub:https://github.com/starlight36/react-native-map-linking Android: 高德地图 百度地图 iOS: 高德地图 百度地图 苹果地 ...

最新文章

  1. 让VBCommenter支持自定义用户名
  2. ueditor编辑器java使用_ueditor编辑器的用法图文教程
  3. PGA内存作用和构成
  4. 连锁反应装置积木好玩到尖叫!
  5. 当集合a为空集时a的取值范围_高中数学必修一第一章集合分节练习和章末测试题含答案[1] 2...
  6. 计算机如何学会自动地进行图像美学增强?
  7. Intellij Idea: Thymeleaf 命名空间th报错
  8. spring 扫描所有_自定义Spring事件监听机制
  9. 逐步实现智慧人居,AIoT 是如何做到的?
  10. php如何优雅地把数组传递给前端js脚本?
  11. JAVA获得当前时间的几种方法
  12. opencv2.4.7.2画圆,画十字,画矩形
  13. 绝地大逃杀服务器维护多少时间,绝地求生4月12日维护到几点/维护多长时间 绝地求生4.12维护什么时候好/能进游戏...
  14. nsis出错_NSIS错误(NSIS Error)的原因和解决方法总结
  15. 高等数学知识框架梳理
  16. android自动打开软键盘,Android打开关闭软键盘
  17. Logstash:从grok到5.X版本的dissect
  18. 盘点2017全球最优秀的6款免费远程桌面软件
  19. 什么是内联电子商务_什么是电子商务
  20. SSLHandshakeException: No appropriate protocol

热门文章

  1. jvm十五:java虚拟机内存图
  2. 设计模式:设计模式七大原则
  3. Linux系统基础调优
  4. 数据库密码加密 使用的是 druid加密
  5. DataGridView新特色、常用操作
  6. Effective C# 原则11:选择foreach循环
  7. QT 调用QWebEngineView显示网页
  8. STC89C52单片机 LCD1602液晶显示屏
  9. oracle磁盘使用率很高,oracle安装磁盘使用率100%导致数据插入等操作报错
  10. ComponentOne Ultimate 2020中文版