ReactNative呼叫Android原生模組
有時候App需要訪問平臺API,但React Native可能還沒有相應的模組包裝;或者你需要複用一些Java程式碼,而不是用Javascript重新實現一遍;又或者你需要實現某些高效能的、多執行緒的程式碼,譬如圖片處理、資料庫、或者各種高階擴充套件等等。
我們把React Native設計為可以在其基礎上編寫真正的原生程式碼,並且可以訪問平臺所有的能力。要想實現訪問Android原生API,總結一下,主要有以下幾個步驟:
1. 建立一個原生模組
這個原生模組是一個繼承ReactContextBaseJavaModule的Java類,它可以實現一些JavaScript所呼叫的原生功能。我們的目標是可以在JavaScript裡寫ToastAndroid.show(`Awesome`, ToastAndroid.SHORT);,來調起一個Toast通知。例如:
public class RnTest extends ReactContextBaseJavaModule {
public RnTest(ReactApplicationContext reactContext) {
super(reactContext);
}
// ReactContextBaseJavaModule要求派生類實現getName方法。這個函式用於返回一個字串
// 這個字串用於在JavaScript端標記這個原生模組
@Override
public String getName() {
return "ToastByAndroid";
}
// 獲取應用包名
// 要匯出一個方法給JavaScript使用,Java方法需要使用註解@ReactMethod
@ReactMethod
public void getPackageName() {
String name = getReactApplicationContext().getPackageName();
Toast.makeText(getReactApplicationContext(),name,Toast.LENGTH_LONG).show();
}
}
ReactContextBaseJavaModule要求派生類實現getName方法。這個函式用於返回一個字串名字,這個名字在JavaScript端標記這個模組。這裡我們把這個模組叫做ToastByAndroid,這樣就可以在JavaScript中通過React.NativeModules.ToastByAndroid訪問到這個模組。
注意:模組名前的RCT字首會被自動移除。所以如果返回的字串為”RCTToastAndroid”,在JavaScript端依然通過React.NativeModules.ToastByAndroid訪問到這個模組。
2. 註冊模組
要使JavaScript端呼叫到原生模組還需註冊這個原生模組,需要實現一個類實現ReactPackage介面,並實現其中的抽象方法。例如:
public class ExampleReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new RnTest(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
MainApplication宣告
除了上面的步驟外,還需在MainApplication.java檔案中的getPackages方法中,例項化上面的註冊類。例如:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
// 例項化註冊類
new ExampleReactPackage());
}
};
3. JS呼叫android原生方法
3.1 引入NativeModules模組
import { NativeModules } from `react-native`;
3.2 呼叫Android原生方法
var rnToastAndroid = NativeModules.ToastByAndroid;
rnToastAndroid.getPackageName();
4. 獲取android返回值
提供給js呼叫的原生android方法的返回型別必須是void,React Native的跨語言訪問是非同步進行的,所以想要給JavaScript返回一個值的唯一辦法是使用回撥函式或者傳送事件。
4.1 回撥函式
Callback是React.bridge中的一個介面,它作為ReactMethod的一個傳參,用來對映JavaScript的回撥函式(function)。Callback介面只定義了一個方法invoke,invoke接受多個引數,這個引數必須是react.bridge中支援的引數。
Android端程式碼:
@ReactMethod
public void tryCallBack(String name,String psw,Callback errorCallback,Callback successCallback){
try{
if(TextUtils.isEmpty(name)&&TextUtils.isEmpty(psw)){
// 失敗時回撥
errorCallback.invoke("user or psw is empty");
}
// 成功時回撥
successCallback.invoke("add user success");
}catch(IllegalViewOperationException e){
// 失敗時回撥
errorCallback.invoke(e.getMessage());
}
}
rn端程式碼:
var rnToastAndroid = NativeModules.ToastByAndroid;
rnToastAndroid.tryCallBack("luo","131",(errorCallback)=>{alert(errorCallback)},(successCallback)=>{alert(successCallback);});
5.呼叫測試
android主動向rn傳送訊息。
5.1 android端程式碼
public static void sendEvent(ReactContext reactContext, String eventName, int status)
{
System.out.println("reactContext="+reactContext);
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName,status);
}
5.2 RN端程式碼
// eventName為5.1中的eventName,reminder為5.1中的status
DeviceEventEmitter.addListener(eventName, (reminder) => {
console.log(reminder):
});
RN呼叫Android原生模組的程式碼如下:
const RNBridgeModule = NativeModules.RNBridgeModule;
nativeLanuchApp(message) {
RNBridgeModule.nativePlayVideo(message);
}
<TouchableOpacity onPress={() => {
this.nativeLanuchApp("111");
}} >
<Text >
try
</Text>
</TouchableOpacity>
相關文章
- 從Android到ReactNative開發(二、通訊與模組實現)AndroidReact
- ReactNative自定義NetworkingModule網路模組React
- R呼叫python模組Python
- 從Android到ReactNative開發(三、自定義原生控制元件支援)AndroidReact控制元件
- java中呼叫npm模組JavaNPM
- Nodejs如何呼叫Dll模組NodeJS
- 編寫Node原生模組
- ReactNative 踩坑之 iOS 原生元件ReactiOS元件
- Lua封裝函式模組並由其他模組呼叫封裝函式
- Android ReactNative資料互動AndroidReact
- Android模組化改造以及模組化通訊框架Android框架
- electron 使用 Node.js 原生模組Node.js
- 純原生元件化-模組化的探索元件化
- 原生應用新增 Flutter 模組依賴Flutter
- Android實現模組 api 化AndroidAPI
- Android模組化框架介紹Android框架
- Android模組化與元件化–多模組區分編譯Android元件化編譯
- python 3呼叫paramiko模組報錯AttributeError: modulePythonError
- Flutter學習(9)——Flutter外掛實現(Flutter呼叫Android原生FlutterAndroid
- React Native 原生模組封裝:支付寶示例React Native封裝
- Android模組化開發實踐Android
- python如何呼叫subprocess模組實現外部命令?Python
- 聊一聊原生瀏覽器中的模組瀏覽器
- Flutter外掛開發《iOS原生模組開發》FlutteriOS
- Python原生資料結構增強模組collectionsPython資料結構
- 你想要的全平臺全棧開源專案 – Vue、React、小程式、Android原生、ReactNative、java後端全棧VueReactAndroidJava後端
- 你想要的全平臺全棧開源專案 - Vue、React、小程式、Android原生、ReactNative、java後端全棧VueReactAndroidJava後端
- Android HAL模組的載入過程Android
- Android模組開發框架 LiveData+ViewModelAndroid框架LiveDataView
- Android工程化實踐:模組化Android
- node中使用C++模組呼叫呼叫speex完成語音檔案壓縮C++
- Android 通過 APT 解耦模組依賴AndroidAPT解耦
- android IM模組-語音-錄製篇1Android
- Android模組化之MicroModule(微信Pins工程)Android
- Android開發筆記[18]-使用本地模組Android筆記
- uni-app&H5&Android混合開發三 || uni-app呼叫Android原生方法的三種方式APPH5Android
- python3 筆記17.呼叫模組from...import...Python筆記Import
- python使用ctypes呼叫擴充套件模組的例項方法Python套件
- HTMLTestRunnerNew模組原始碼及呼叫自定義報告封裝HTML原始碼封裝