React Native 橋接原生 iOS 以及 Android 獲取 APP 版本號
在使用React Native進行跨平臺開發過程中,或多或少需要涉及到原生開發,這裡主要說一下如何橋接原生 iOS 以及 Android,在此以獲取 APP 版本號為例。
iOS 橋接
iOS 橋接比較簡單,只需要建立一個 Module 類,實現 RCTBridgeModule 協議就好。 首先我們需要建立一個 RNBridgeManager 類
RNBridgeManager.h 中的程式碼:
#import <Foundation/Foundation.h> #import <React/RCTBridgeModule.h> @interface RNBridgeManager : NSObject <RCTBridgeModule> @end 複製程式碼
然後在 RNBridgeManager.m 中實現相應方法
為了實現 RCTBridgeModule 協議,你的類需要包含 RCT_EXPORT_MODULE()巨集。這個巨集也可以新增一個 指定引數用來指定在使用 Javascript 中訪問這個模組的名字
RNBridgeManager.m 中的程式碼
#import "RNBridgeManager.h" @implementation RNBridgeManager @synthesize bridge = _bridge; RCT_EXPORT_MODULE(ToolModule); //對外提供呼叫方法,Callback RCT_EXPORT_METHOD(getAppVersion:(RCTResponseSenderBlock)callback) { NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];//獲取專案版本號 callback(@[[NSNull null],version]); } @end 複製程式碼
最後在RN中呼叫
import React, { Component } from 'react'; import { NativeModules } from 'react-native'; var iOSToolModule = NativeModules.ToolModule; export default class Me extends Component { constructor(props) { super(props); this.state = { version: '', } this.getVerSion(); } // 獲取版本號 getVerSion() { iOSToolModule.getAppVersion((error,event)=>{ if(error){ console.log(error) }else{ this.setState({ version:event }) } }) } } 複製程式碼
至此,iOS 部分的橋接工作就全部完成了。
Android
Android 相對 iOS 較為複雜,我們首先需要在 Android/app/src/main/java/com 資料夾下新建一個 reactnative 資料夾,在該資料夾下建立 RNBridgeManager.java 檔案以及RNReactPackage.java 檔案,具體程式碼如下:
RNBridgeManager.java中的程式碼
package com.reactnative; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.uimanager.IllegalViewOperationException; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; public class RNBridgeManager extends ReactContextBaseJavaModule { public RNBridgeManager(ReactApplicationContext reactContext) { super(reactContext); } //重寫getName方法宣告Module類名稱,在RN呼叫時用到 @Override public String getName() { return "BridgeManager"; } //宣告的方法,外界呼叫 @ReactMethod public void getAppVersion(Callback successCallback) { try { PackageInfo info = getPackageInfo(); if(info != null){ successCallback.invoke(info.versionName); }else { successCallback.invoke(""); } } catch (IllegalViewOperationException e){ } } //獲取 APP 資訊 private PackageInfo getPackageInfo(){ PackageManager manager = getReactApplicationContext().getPackageManager(); PackageInfo info = null; try{ info = manager.getPackageInfo(getReactApplicationContext().getPackageName(),0); return info; }catch (Exception e){ e.printStackTrace(); }finally { return info; } } } 複製程式碼
RNReactPackage.java中的程式碼
package com.reactnative; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class RNReactPackage implements ReactPackage { @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } @Override public List<NativeModule> createNativeModules( ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); //新增一個安卓原生的activity模組 modules.add(new RNBridgeManager(reactContext)); return modules; } } 複製程式碼
然後在 MainApplication.java 中新增剛剛註冊過的包名
@Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new RNReactPackage() ); } 複製程式碼
最後,在RN中呼叫
import React, { Component } from 'react'; import { NativeModules } from 'react-native'; export default class Me extends Component { constructor(props) { super(props); this.state = { version: '', } this.getVerSion(); } // 獲取版本號 getVerSion() { NativeModules.BridgeManager.getAppVersion((event) =>{ this.setState({ version:event }) }); } 複製程式碼
注意事項
- iOS 橋接時,不要漏了 @synthesize bridge = _bridge;
- Android 橋接時,暴露的方法需在前面加上 @ReactMethod
- 在實現相關功能方法時,儘量用 Callback 的形式,網上好多文章使用 return 的形式,在開發時有參考過,但未成功
- iOS 中的 RCT_EXPORT_MODULE(ToolModule) 以及 Android 中 getName 繫結的名稱,即為RN 呼叫的類名
- Android 橋接記得在 MainApplication 中繫結相應 Package