React Native调用原生模块
概述
有時(shí)候App需要訪問(wèn)平臺(tái)API,但React Native可能還沒(méi)有相應(yīng)的模塊包裝;或者你需要復(fù)用一些Java代碼,而不是用Javascript重新實(shí)現(xiàn)一遍;又或者你需要實(shí)現(xiàn)某些高性能的、多線程的代碼,譬如圖片處理、數(shù)據(jù)庫(kù)、或者各種高級(jí)擴(kuò)展等等。
我們知道React Native本身對(duì)這種偏業(yè)務(wù)和底層調(diào)用是不關(guān)心的,這時(shí)候我們就想到了原生組件,我們通過(guò)調(diào)用原生組件,然后經(jīng)過(guò)特定的封裝來(lái)達(dá)到效果。如我們?cè)谠_發(fā)中常見的Toast為例:
原生模塊封裝
假設(shè)我們希望可以從Javascript發(fā)起一個(gè)Toast消息,Android會(huì)顯示在屏幕的下方,會(huì)停留一段時(shí)間。我們來(lái)看一下官方給出的例子。
創(chuàng)建一個(gè)繼承了ReactContextBaseJavaModule的Java類,它可以實(shí)現(xiàn)一些JavaScript所需的功能。我們這里的目標(biāo)是可以在JavaScript里寫ToastAndroid.show('Awesome', ToastAndroid.SHORT);,來(lái)調(diào)起一個(gè)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要求派生類實(shí)現(xiàn)getName方法,這個(gè)名字返回的字符串可以自取,但是不能命名為'ToastAndroid',因?yàn)镽N已經(jīng)內(nèi)置了一個(gè)名為ToastAndroid的模塊,運(yùn)行時(shí)會(huì)報(bào)錯(cuò)名字沖突!
@Overridepublic String getName() {return "ToastAndroid";}注:模塊名前的RCT前綴會(huì)被自動(dòng)移除。所以如果返回的字符串為"RCTToastAndroid",在JavaScript端依然通過(guò)React.NativeModules.ToastAndroid訪問(wèn)到這個(gè)模塊。
接下來(lái)我們需要設(shè)置一個(gè)可選的方法getContants(),用于彈出時(shí)間選擇(及Toast.Length)
最后導(dǎo)出一個(gè)方法給JavaScript使用。
@ReactMethodpublic void show(String message, int duration) {Toast.makeText(getReactApplicationContext(), message, duration).show();}在Java這邊要做的最后一件事就是注冊(cè)這個(gè)模塊。我們需要在應(yīng)用的Package類的createNativeModules方法中添加這個(gè)模塊。如果模塊沒(méi)有被注冊(cè),它也無(wú)法在JavaScript中被訪問(wèn)到。
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;}這個(gè)package需要在MainApplication.java文件的getPackages方法中提供。這個(gè)文件位于你的react-native應(yīng)用文件夾的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端訪問(wèn)起來(lái)更為方便,通常我們都會(huì)把原生模塊封裝成一個(gè)JavaScript模塊。
'use strict';import { NativeModules } from 'react-native';export default NativeModules.ToastAndroid;最后調(diào)用javascript模塊就好了。
import ToastAndroid from './ToastAndroid'; ToastAndroid.show('Awesome', ToastAndroid.SHORT);未完待續(xù)..
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的React Native调用原生模块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: svn 部署问题总结
- 下一篇: time、deltaTime、fixed