當前位置:編程學習大全網 - 熱門推薦 - ndk-Android NDk 怎麽編譯時動態鏈接第三方so庫,有頭文件

ndk-Android NDk 怎麽編譯時動態鏈接第三方so庫,有頭文件

問題描述:Android如何調用第三方SO庫;

已知條件:SO庫為Android版本連接庫(*.so文件),並提供了詳細的接口說明;

已了解解決方案:

1.將SO文件直接放到libs/armeabi下,然後代碼中System.loadLibrary("xxx");再public native static int xxx_xxx_xxx();接下來就可以直接調用xxx_xxx_xxx()方法;

2.第二種方案,創建自己的SO文件,在自己的SO文件裏調用第三方SO,再在程序中調用自己的SO,這種比較復雜,需要建java類文件,生成.h文件,編寫C源文件include之前生成的.h文件並實現相應方法,最後用android NDK開發包中的ndk-build腳本生成對應的.so***享庫;

求解:

1.上面兩種方案是否可行?不可行的話存在什麽問題?

2.兩種方案有什麽區別?為什麽網上大部都是用的第二種方案?

3.只有壹個*.so文件,並提供了詳細的接口說明,是否可在ANDROID中使用它?

首先要看這個SO是不是JNI規範的SO,比如有沒有返回JNI不直接支持的類型。也就是說這個SO是不是可以直接當作JNI來調用。如果答案是否定的,妳只能選第二個方案。

如果答案是肯定的,還要看妳是不是希望這個SO的庫直接暴露給JAVA層,如果答案是否定的,妳只能選第二個方案,比如妳本身也是壹個庫的提供者。

壹般如果妳只有SO,就說明這個是別人提供給妳的,妳可以要求對方給妳提供配套的JAVA調用文件。

1、這個要看這個SO是不是符合JNI調用的規範。還要看妳自己的意願。

2、因為第二種方法最靈活,各種情況都可以實現。

3、可以

看能不能直接從JAVA調用的最簡單的方法就是看SO裏的函數名是不是Java_XXX_XXX_XXX格式的

是就可以,妳可以自己寫壹個配套的JAVA文件,註意壹下SO函數名和JAVA函數名的轉換規則,或者向SO提供方索要;

不是的話就選第二種方案吧。

1、檢查所需文件是否齊全

使用第三方動態庫,應該至少有2個文件,壹個是動態庫(.so),另壹個是包含

動態庫API聲明的頭文件(.h)

2、封裝原動態庫

原動態庫文件不包含jni接口需要的信息,所以我們需要對其進行封裝,所以我

們的需求是:將libadd.so 裏面的API封裝成帶jni接口的動態

3、編寫庫的封裝函數libaddjni.c

根據前面生成的com_android_libjni_LibJavaHeader.h 文件,編寫libaddjni.c,用

來生成libaddjni.so

Android中集成第三方軟件包(.jar, .so)

Android中可能會用到第三方的軟件包,這包括Java包.jar和Native包.so。jar包既可通過Eclipse開發環境集成,也可通過編譯源碼集成,看妳的工作環境。

假定自己開發的程序為MyMaps,需要用到BaiduMaps的庫,包括baidumapapi.jar和libBMapApiEngine_v1_3_1.so。

壹、Eclipse中集成第三方jar包及.so動態庫

MyMaps工程下創建目錄libs以及libs/armeabi,把baidumapapi.jar放在的libs/目錄下,把libBMapApiEngine_v1_3_1.so放在libs/armeabi/下。

Eclipse中把第三方jar包baidumapapi.jar打包到MyMaps的步驟:

1. 右擊工程,選擇Properties;

2. Java Build Path,選擇Libraries;

3. Libraries頁面點擊右面按鈕“Add Library…”;

4. 選擇“User Library”,點擊“Next”;

5. 點擊“User Libraries”按鈕;

6. 在彈出界面中,點擊“New…”;

7. 輸入“User library name”,點擊“OK”確認;

8. 返回之後,選擇剛剛創建的User library,右面點擊“AddJARs”;

9. 選擇MyMaps/libs/下的baidumapapi.jar;

10. 確認,返回。

這樣,編譯之後,該jar包就會被打進MyMaps.apk中,libBMapApiEngine_v1_3_1.so也被打包在lib/armeabi/中。

程序運行過程中,libBMapApiEngine_v1_3_1.so被放在/data/data/<yourAppPackage>/lib/下,加載動態庫時系統會從程序的該lib/目錄下查找.so庫。

二、源碼中集成第三方集成jar包及.so動態庫

Android源碼中MyMaps放在packages/apps下。MyMaps下創建目錄libs以及libs/armeabi,並把baidumapapi.jar放在libs/,把libBMapApiEngine_v1_3_1.so放在libs/armeabi。

2.1 修改Android.mk文件

Android.mk文件如下:

[plain] view plaincopy

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_STATIC_JAVA_LIBRARIES := libbaidumapapi

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := MyMaps

include $(BUILD_PACKAGE)

##################################################

include $(CLEAR_VARS)

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libbaidumapapi:libs/baidumapapi.jar

LOCAL_PREBUILT_LIBS :=libBMapApiEngine_v1_3_1:libs/armeabi/libBMapApiEngine_v1_3_1.so

LOCAL_MODULE_TAGS := optional

include $(BUILD_MULTI_PREBUILT)

# Use the following include to make our testapk.

include $(callall-makefiles-under,$(LOCAL_PATH))

1 集成jar包

LOCAL_STATIC_JAVA_LIBRARIES取jar庫的別名,可以任意取值;

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES指定prebuiltjar庫的規則,格式:別名:jar文件路徑。註意:別名壹定要與LOCAL_STATIC_JAVA_LIBRARIES裏所取的別名壹致,且不含.jar;jar文件路徑壹定要是真實的存放第三方jar包的路徑。

編譯用BUILD_MULTI_PREBUILT。

2 集成.so動態庫

LOCAL_PREBUILT_LIBS指定prebuilt so的規則,格式:別名:so文件路徑。註意:別名壹般不可改變,特別是第三方jar包使用.so庫的情況,且不含.so;so文件路徑壹定要是真實的存放第三方so文件的路徑。

編譯拷貝用BUILD_MULTI_PREBUILT。

2.2 加入到GRANDFATHERED_USER_MODULES

在文件user_tags.mk中,把libBMapApiEngine_v1_3_1加入到GRANDFATHERED_USER_MODULES中

[plain] view plaincopy

GRANDFATHERED_USER_MODULES += \

… \

libBMapApiEngine_v1_3_1

user_tags.mk可以是build/core下的,也可以是$(TARGET_DEVICE_DIR)下的,推薦修改$(TARGET_DEVICE_DIR)下的。

2.3 編譯結果

MyMaps.apk編譯生成在out/target/product/<YourProduct>/system/app/下;

libBMapApiEngine_v1_3_1.so放在out/target/product/<YourProduct>/system/lib/下,這也是系統加載動態庫時搜索的路徑。

  • 上一篇:黑色艉流各按鍵是什麽功能
  • 下一篇:《我是誰》這部電影是否值得壹看?
  • copyright 2024編程學習大全網