將so打包進apk ,網上常見的就是 在源碼中有c代碼,編譯出一個so,然後打進apk,也是網上大家轉來轉去的那幾篇文章,因爲一致只做純java開發,這種方法沒有試過。
如果是第三方so ,則有諸多麻煩。
一種就是 其他同事現在的方法,在eclipse開發,那麼libs/armeabi下的so 自動弄進去了,真是簡單又方便。
另外一種就是要把so拷貝到編譯環境的某個目錄,在編譯代碼時整合進去。
客戶方給了一個so,不知道開發細節,需要編進去。我習慣了在代碼樹下開發,剛開始並沒有注意配置so,結果編譯正常,安裝正常,但是一旦 loadLibary ,就exception: load library renturn null。
解壓發現apk發現,裏面並沒有源碼對應的libs/armeabi/xxx.so,看來並沒有打包進去。
在糾結中實戰,找到如下實用方法;
1 copy 你的so 到out/target/product/generic/system/lib 。 這個目錄是你沒有修改過TARGET_PRODUCT的情況下。
如果你的TARGET_PRODUCT是 XXXYYY,則要去out/target/product/XXXYYY/system/lib 。
ps:這一步其實可以在第二步中的mk文件中用代碼執行,同事給的參考爲:
$(shell mkdir -p $(TARGET_OUT)/../obj/STATIC_LIBRARIES/$(LOCAL_MODULE)_intermediates )
$(shell cp $(LOCAL_PATH)/lib/libmap-encrypt.a $(TARGET_OUT)/../obj/STATIC_LIBRARIES/$(LOCAL_MODULE)_intermediates/$(LOCAL_MODULE).a)
晚上回去試一試。
2 在app代碼中創建mk文件,文件名可隨意,但建議和so同名吧 。 格式如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= libmupdf
紅色的libmupdf是你要加載的so名稱,也就是out/target/product/generic/system/lib下的so名稱。
一個so對應一個mk,我們習慣把n個mk放在jni目錄下。這個jni目錄與app的android.mk 同級。
3 在app的Android.mk中 需要有這樣的聲明
LOCAL_JNI_SHARED_LIBRARIES := libmupdf ,libmupdf爲第二步中聲明的LOCAL_MODULE如果是多個 ,用空格隔開
還有這一句:
include $(call all-makefiles-under,$(LOCAL_PATH))
4 這樣編譯後,即使你的源碼中沒有so,在生成的apk會自動建eStore.apk_FILES/lib/armeabi ,下面便是你想加載的so,只可能是第一步中的目錄拷貝而來。
5 install -r 時可能報 INSTALL_FAILED_DEXOPT 。 原來在模擬器下開發,/data太小, 重新啓動模擬器加 wipe-data 解決。
這個問題是解決了,但是對Android.mk的語法並不瞭解。以後遇到此類問題,估計還要糾結 ,555
有時間學習學習去