React Native使用原生组件
2017-01-08 09:25
344 查看
概述
有时候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的模块,运行时会报错名字冲突!
@Override public String getName() { return "ToastAndroid"; }
注:模块名前的RCT前缀会被自动移除。所以如果返回的字符串为”RCTToastAndroid”,在JavaScript端依然通过React.NativeModules.ToastAndroid访问到这个模块。
接下来我们需要设置一个可选的方法getContants(),用于弹出时间选择(及Toast.Length)
@Override public 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使用。
@ReactMethod public void show(String message, int duration) { Toast.makeText(getReactApplicationContext(), message, duration).show(); }
在Java这边要做的最后一件事就是注册这个模块。我们需要在应用的Package类的createNativeModules方法中添加这个模块。如果模块没有被注册,它也无法在JavaScript中被访问到。
class AnExampleReactPackage implements ReactPackage { @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } @Override public 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 使用原生 UI 组件
- 深入浅出 React Native:使用 JavaScript 构建原生应用
- React Native – 使用 JavaScript 开发原生应用
- 使用 JAVA WEB组件 与 原生HTML/CSS/JS代码 舌战
- 深入浅出 React Native:使用 JavaScript 构建原生应用
- 深入浅出 React Native:使用 JavaScript 构建原生应用
- Android使用原生组件WebView加载网页和数据的方法
- 可能是最in的React Native使用原生自定义下拉刷新组件
- React Native入门教程2 -- 基本组件使用及样式
- 深入浅出 React Native:使用 JavaScript 构建原生应用
- React Native 开发基础组件 触摸组件 类似于android原生 button
- 深入浅出 React Native:使用 JavaScript 构建原生应用
- 关于polymer原生组件paper-input的部分属性的使用心得
- 深入浅出 React Native:使用 JavaScript 构建原生应用
- React Native入门教程2 -- 基本组件使用及样式
- react native使用原生模块
- 深入浅出 React Native:使用 JavaScript 构建原生应用
- 深入浅出 React Native:使用 JavaScript 构建原生应用
- react native 学习笔记----使用Android的原生模块
- IOS-React Native 使用CocoaPods集成到原生项目中