1. 程式人生 > >React Native 橋接原生 iOS 以及 Android 獲取 APP 版本號

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