ReactNative調用aar文件(附:如何打開、查看aar文件內容)


 

轉載請注明原文地址:http://www.cnblogs.com/ygj0930/p/7275897.html

 

     ReactNative可以用來進行一些嵌入式設備的操作終端開發,比如:ATM機、自動售賣機等。其中,最重要的一步是,怎樣在ReactNative所在設備,進行一系列硬件上的操作,比如:售賣機出貨、ATM機吐錢?

    一:底層操作串口包裝

    對於機器的控制,ReactNative本身當然不可能做到。這些底層的操作一般都是用C/C++來實現的。而我們要做的,是把這些C/C++函數,包裝成java接口,導出為aar文件。(注意:*.jar:只包含了class文件與清單文件,不包含資源文件,如圖片等所有res中的文件。*.aar:包含所有資源,class以及res資源文件全部包含)

    對於底層的操作,我們不需要關心,由廠商提供或者負責嵌入式開發的人來定義。   

 

    在ReactNative中調用aar分為兩部分:首先是通過原生Android代碼調用aar中的接口,包裝成為可供ReactNative調用的方法;然后在ReactNative代碼中調用Android代碼中的對應方法。 

    二:Android調用aar

    1:首先,我們把aar文件放到項目的android目錄的一個文件夾中,比如:新建一個libs文件夾。

    2:然后,在android目錄下的build.gradle文件中添加這個aar包路徑:

allprojects {
    repositories {
        mavenLocal()
        flatDir{
                    dirs "$rootDir/libs" //在這里加上這句
 } ...... } }

    3:在android/app目錄下的build.gradle文件中依賴這個aar包

dependencies {
    ...... 
    compile(name:'aar包名', ext:'aar')//加上這句
}

    4:然后,就可以在android/app/src/main/java/com/xx目錄下新建java類,在類中  import aar包名.類名  即可使用aar包中的各種接口。

   

    附:如何打開、查看aar文件內容,獲取其中類、接口的信息?

    修改aar文件后綴為  zip  ,然后解壓它,可以得到一個classes.jar文件。

    使用java反編譯工具即可查看classes.jar包中的內容,獲取供我們調用的接口信息。

 

    三:ReactNative中的原生Android開發

    1:定義原生模塊,調用aar文件

    在android/app/src/main/java/com/xx目錄下,新建一個類文件。

    定義繼承ReactContextBaseJavaModule的Java類

import aar包名.aar中類名

import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;

public class 模塊類 extends ReactContextBaseJavaModule {
  public 模塊類(ReactApplicationContext reactContext) {
    super(reactContext);
  }

  // 要求重寫getName方法,返回一個字符串作為這個原生模塊名,用於在JavaScript端標記、使用這個模塊
  @Override
  public String getName() {
    return "模塊名";
  }

  // 定義供JavaScript調用的方法,需要使用注解@ReactMethod,返回值是void!
   @ReactMethod
   public void 方法名() {
   通過 aar中類名.方法名()  調用aar中接口。
  }
  。。。。。。
}

 

 

    2:注冊模塊

    在模塊類文件同級目錄下,新建一個  模塊名Package.java  的類文件,重寫幾個方法:

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
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 模塊名Package implements ReactPackage {
    
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new 模塊類(reactContext));/添加模塊
        return modules;
    }
}

 

    3:在IDE自動創建好的android/app/src/main/java/com/項目名   目錄下的MainApplication.java中添加Package實例

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new 模塊名Package() //在這里添加package實例
      );
    }

    4:另外,也可以在android/app/src/main/java/com/項目名   目錄下自動創建的MainActivity類中定義一些隨着app生命周期而觸發的方法。比如:onCreate()等等Android原生Activity生命周期函數。

    

    四:在ReactNative的js文件中調用原生Android模塊內方法

    1:導入本地模塊庫

   在js文件頭導入本地模塊庫

import { NativeModules } from 'react-native';

    2:通過 NativeModules.模塊名.方法名() 進行本地模塊內函數的調用

    3:獲取調用結果

    提供給js調用的原生android方法的返回類型必須是void,所以想要給JavaScript返回一個值的唯一辦法是使用回調函數或者發送事件

    使用回調函數:

    1)android代碼中定義的方法,傳進回調函數作為參數

  // android端代碼
  @ReactMethod
  public void 方法名(...參數,Callback callback){
    ......
    callback(...);//調用回調函數
    }

    2)js端調用方法時,除了傳遞數據參數,還傳遞回調函數獲取調用結果

// RN端調用代碼
NativeModules.模塊名.方法名(...參數,(回調函數參數)=>{回調函數體)});

     使用Promise發送異步任務狀態進行回調:

     向模塊方法傳遞數據一個promise對象,模塊方法中通過promise返回執行狀態以達到反饋執行結果的目的:

     1)android端

// android端代碼
@ReactMethod
  public void 方法名(數據參數, Promise promise){
    try{
      if(...){
      promise.resolve(map);//正常返回,並且攜帶返回結果
      }else{
       promise.reject(結果信息);//返回另一種結果
      }
      }catch(IllegalViewOperationException e){
         promise.reject(異常信息);//異常退出
      }
    }

     2)js端:傳遞一個匿名promise對象參數,使用 then(resolveCallBack,rejectCallBack) 來接受返回結果並執行相應回調函數

NativeModules.模塊名.方法名(數據參數,new Promise().then((resolve狀態返回值)=> {提取結果}, (reject狀態返回值)=> {提取結果});

 

 

 

   

 

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM