目录
2.1.3定义JavaScript同步访问到的预定义值(非必须实现该方法)
2.2.1封装RN内部访问的注册模块(ToastExample)
3.1.1类型转换(Java与JS-React Native类型对应关系)
3.1.2JS给Java传递对象或数组值接收类型(主动传值给Java并接受回调)
1.为什么需要调用Android原生代码
有时候 App 需要访问平台 API,但 React Native 可能还没有相应的模块包装;或者你需要复用一些 Java 代码,而不是用 Javascript 重新实现一遍;又或者你需要实现某些高性能的、多线程的代码,譬如图片处理、数据库、或者各种高级扩展等等。
我们把 React Native 设计为可以在其基础上编写真正的原生代码,并且可以访问平台所有的能力。这是一个相对高级的特性,我们并不认为它应当在日常开发的过程中经常出现,但具备这样的能力是很重要的。如果 React Native 还不支持某个你需要的原生特性,你应当可以自己实现该特性的封装。-我们需要的某部分功能RN未提供,就需要调用原生的功能;
2.如何调用Android原生代码
以RN调用Android原生的Toast通知为例说明调用过程;(其他Android原生功能调用流程类似)
2.1Android原生代码配置(注册供RN调用方法)
2.1.1创建原生模块
我们首先来创建一个原生模块。一个原生模块是一个继承了ReactContextBaseJavaModule
的 Java 类,它可以实现一些 JavaScript 所需的功能。我们这里的目标是可以在 JavaScript 里写ToastExample.show('Awesome', ToastExample.SHORT);
,来调起一个短暂的 Toast 通知。
创建一个新的 Java 类并命名为ToastModule.java
,放置到android/app/src/main/java/com/your-app-name/
目录下,其具体代码如下:
// ToastModule.java
package com.your-app-name;
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;
import java.util.HashMap;
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);
}
}
2.1.2为原生模块指定RN调用的名字(必须实现该方法)
ReactContextBaseJavaModule
要求派生类实现getName
方法。这个函数用于返回一个字符串名字,这个名字在 JavaScript 端标记这个模块。这里我们把这个模块叫做ToastExample
,这样就可以在 JavaScript 中通过NativeModules.ToastExample
访问到这个模块。译注:RN 已经内置了一个名为 ToastAndroid 的模块,所以在练习时请勿使用 ToastAndroid 的名字,否则运行时会报错名字冲突!
@Override
public String getName() {
return "ToastExample";
}
2.1.3定义JavaScript同步访问到的预定义值(非必须实现该方法)
一个可选的方法getContants
返回了需要导出给 JavaScript 使用的常量。它并不一定需要实现,但在定义一些可以被 JavaScript 同步访问到的预定义的值时非常有用。
@Override
public Map<Str