aar與source.jar,aar檔案jar檔案區別,以及Android.mk如何引用aar檔案和jar檔案
1,aar與source.jar的區別 原文地址:http://blog.csdn.net/csdn_yudong/article/details/48090535
關於.jar與sources.jar到底是什麼,區別是什麼,我為大家講解一下。
首先,當我們在下載jar包與引入jar包的時候可能會發現,存在jar檔案與相應的cources jar檔案。如下圖所示:
這個時候,到底該下載哪一個,或者我們需要的是哪一個。是junit-4.7.jar還是junit-4.7-sources.jar?
明確的告訴你,我們需要的是junit-4.7.jar,也就是我們需要在專案中引入的是junit-4.7.jar。
------------------------------------------------------------------------------------------------------------
那這個source.jar有什麼用呢?
我們知道,我們在項目中引入外部jar檔案,肯定是要用到這個jar檔案裡面的類庫才引入的,雖然我們只需要能引入進來,完成我們需要的功能即可,但有時候,我們還是想看看功能具體的實現,看看別人的原始碼是怎麼寫的。這個時候我們開啟jar包。
比如,開啟mysql-connector-java-5.1.5-bin.jar。
開啟com.mysql.jdbc這個包。
發現裡面都是編譯後的class檔案。
這種檔案是看不到原始碼的(當然,你可以選擇反編譯)
開啟第一個class檔案,
如果,我們想看原始碼怎麼辦,這個時候就需要點選Attach Source.關聯原始碼。
原始碼在哪裡,沒錯,就在對應的source.jar裡面。
Attach Source完了以後,就可以直接看jar包中的類的原始碼了,是不是整個世界都明亮了。
Attach Source的過程很簡單,相信大家可以自己完成。
-----------------------------------------------------------------------
2,jar和aar區別:
*.jar:只包含了class檔案與清單檔案,不包含資原始檔,如圖片等所有res中的檔案。
*.aar:包含所有資源,class以及res資原始檔全部包含
如果你只是一個簡單的類庫那麼使用生成的*.jar檔案即可;如果你的是一個UI庫,包含一些自己寫的控制元件佈局檔案以及字型等資原始檔那麼就只能使用*.aar檔案。
3,這才是重點最近遇到一個問題,在更改Android的系統應用時,要引用一個aar檔案。之前引用的主要是jar包,而aar檔案包含Android的資原始檔,如:佈局、樣式、圖片等,如果按照原始碼中jar的引用方式會遇到編譯不過的問題,提示找不到相關的資原始檔。
LOCAL_STATIC_JAVA_AAR_LIBRARIES:= <aar alias>
.
.
.
include $(BUILD_PACKAGE)
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := <aar alias>:libs/<lib file>.aar
include $(BUILD_MULTI_PREBUILT)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
其中,LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := <aar alias>:libs/<lib file>.aar
也可以如下面這樣寫:
include $(CLEAR_VARS)
LOCAL_MODULE := <aar alias>
LOCAL_SRC_FILES := <lib file>.aar
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
LOCAL_BUILT_MODULE_STEM := javalib.jar
include $(BUILD_PREBUILT)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
這裡主要是LOCAL_STATIC_JAVA_AAR_LIBRARIES,剩下的和jar包大同小異,注意在manifest檔案裡minSdkVersion要滿足aar檔案的要求。
搜尋Android原始碼,也可以發現:
#LOCAL_STATIC_JAVA_AAR_LIBRARIES are special LOCAL_STATIC_JAVA_LIBRARIES
LOCAL_STATIC_JAVA_LIBRARIES := (strip(LOCAL_STATIC_JAVA_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES))
這一步完成後,程式碼可以順利編譯過了,不過在執行apk時如果使用到aar檔案裡面的資源可能會crash,所以還需要加上以下語句:
LOCAL_AAPT_FLAGS := \
--auto-add-overlay \
--extra-packages <aar package name>
- 1
- 2
- 3
關於LOCAL_AAPT_FLAGS,可以參考以下網址,在開發Android系統應用時可能會遇到和這個相關的一些小坑,比如修改完相關程式碼後,push進機器卻不起作用。
這裡把相關aar檔案的資源打包到我們的apk裡,apk即可正常執行。
另外一點是在make檔案中可以指定具體的manifest檔案: LOCAL_MANIFEST_FILE := <manifest file path>
參考連結:
4,自己總結LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_STATIC_JAVA_AAR_LIBRARIES:= easyrecyclerview design
LOCAL_STATIC_JAVA_LIBRARIES := amap map3d core butterknife eventbus glide
LOCAL_STATIC_JAVA_LIBRARIES += \
android-support-v4 \
android-support-v7-recyclerview \
android-support-v7-appcompat
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res \
frameworks/support/v7/appcompat/res
LOCAL_AAPT_FLAGS = --auto-add-overlay \
--extra-packages android.support.v7.appcompat \
--extra-packages com.jude.easyrecyclerview
LOCAL_PACKAGE_NAME := DamiManager
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true
$(warning $(shell mkdir -p $(PRODUCT_OUT)/system/lib))
$(warning $(shell cp -R $(LOCAL_PATH)/libs/armeabi/* $(PRODUCT_OUT)/system/lib))
# LOCAL_MULTILIB := 32
LOCAL_PREBUILT_JNI_LIBS := \
libs/arm64-v8a/libGNaviData.so \
libs/arm64-v8a/libGNaviMap.so \
libs/arm64-v8a/libGNaviMapex.so \
libs/arm64-v8a/libGNaviSearch.so \
libs/arm64-v8a/libGNaviUtils.so \
libs/arm64-v8a/libRoadLineRebuildAPI.so
include $(BUILD_PACKAGE)
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
amap:libs/AMap_Location_V3.6.0_20170918.jar \
core:libs/core-3.0.0.jar \
map3d:libs/Android_Map3D_SDK_V5.3.0_20170815.jar \
butterknife:libs/butterknife-7.0.1.jar \
eventbus:libs/eventbus-3.0.0.jar \
easyrecyclerview:libs/easyrecyclerview-4.2.3.aar \
glide:libs/glide-3.7.0.jar \
design:libs/design-24.2.1.aar
include $(BUILD_MULTI_PREBUILT)
include $(call all-makefiles-under,$(LOCAL_PATH))
上面是我的makefile
1,LOCAL_STATIC_JAVA_LIBRARIES := amap map3d core butterknife eventbus glide
這一行的,都是第三方的沒有資源的jar然後在下面LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES寫一下就好了,對應的是 別名:路徑
2,
LOCAL_STATIC_JAVA_LIBRARIES += \
android-support-v4 \
android-support-v7-recyclerview \
android-support-v7-appcompat
上面這型別是android自帶的包,按這寫法就可以,但是如果用到裡面的資源可以參考這個連結:http://blog.csdn.net/a4262562/article/details/51469979
內容貼出來:
由於新版本Eclips中ADT外掛的升級,Google為了相容舊版本的Activity Action樣式,特意匯入了android-support-v7-appcompat.jar庫。
更新ADT版本後,使用新版Eclips所建立的Android工程,預設會改為繼承ActionBarActivity,而不是以前舊的Activity類。 這樣導致的直接結果是:使用新版本Eclips所生成的原始碼放入Android原始碼中,使用mmm編譯通常都會報錯。 特意花了些時間研究了一下。下面針對大家常見的三種情況,分別給出解決辦法: 1、準備從頭開始編寫新APK?
這種情況下最簡單的解決辦法是:新建apk的時候,將sdk最低版本選擇為4.0以上,這樣會預設生成繼承Activity類的apk,使用該方法寫出的apk,放入原始碼中就能和舊時一樣,修改Android.mk後直接使用mmm去成功編譯apk src了。
2、直接將Eclips中編譯好的apk檔案放入原始碼,計劃使用mmm打sign?
如果別人雖然用了新的Eclips編寫code,但提供的不是原始碼,而是pre-build apk檔案,那麼對這種apk的原始碼編譯操作方法也同舊時一樣處理即可(mmm搭配Android.mk)。
3、最麻煩的就是別人提供了寫好的apk src,並且這種src剛好也使用了新的v7庫,那我們應該怎麼辦呢?
針對這種情況。首先,需要對常見的Android.mk新增res檔案和lib檔案的支援(尤其是res檔案的支援,一般新版apk 編譯不過的根本原因是由於 Theme中所定義的資源無法找到)
(修改好的Android.mk原始檔如下)
##################################################
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_LIBRARIES := telephony-common
LOCAL_STATIC_JAVA_LIBRARIES := \ //增加lib的支援
android-support-v7-gridlayout \
android-support-v7-mediarouterLOCAL_RESOURCE_DIR = \
$(LOCAL_PATH)/res \
frameworks/support/v7/appcompat/res \
frameworks/support/v7/gridlayout/res \
frameworks/support/v7/mediarouter/res //增加res的支援 (若不填寫,則預設會自動查詢工程路徑下的res目錄,所以很多v7的資源包會找不到。(補充下,假設僅僅只添加了v7的lib而未新增res資原始檔,則由於res資原始檔本身並不包含在lib裡面的,故mmm編譯時一樣會報找不到res的相關錯誤)
LOCAL_AAPT_FLAGS := \
–auto-add-overlay \
–extra-packages android.support.v7.appcompat:android.support.v7.gridlayout:android.support.v7.mediarouter //將編譯出的三種資源包元件,使用aapt tool打包到即將生成的Apk中,從而保證生成的Apk執行正常! What?? aapt tool你不知道是什麼?? 哈哈,好吧,這個tool確實用的不多,例如與telephony相關有個叫做PhoneCommon的Apk中也用到了,該Apk被使用aapt tool整合到了call相關Apk中(由於Android L有變化,所以就不實名舉例了)。綜合,該tool的目的就是把另外一個Apk功能直接整合到一個Apk中。
#LOCAL_SDK_VERSION := current
LOCAL_PACKAGE_NAME := myapk
include $(BUILD_PACKAGE)
##################################################
include $(call all-makefiles-under,$(LOCAL_PATH))
最後的最後,我需要為大多數剛入門的朋友做一下補充:
那就是由於絕大多數情況下,Android Source Code編譯過程中,預設並不去編譯V7包相關的這三個lib,所以需要在編譯apk之前手動mmm編譯一次。
命令如下:
mmm framework/support/v7/appcompat
mmm framework/support/v7/gridlayout
mmm framework/support/v7/mediarouter(各個平臺的v7包所放位置可能需要自行去查詢)
最後,我們再用mmm去編譯前面的apk就成功了。
世界又美好了!!!
3,第三方的aar,新增方法LOCAL_STATIC_JAVA_AAR_LIBRARIES:= easyrecyclerview design
下面這一行是編譯資原始檔
LOCAL_AAPT_FLAGS = --auto-add-overlay \
--extra-packages android.support.v7.appcompat \
--extra-packages com.jude.easyrecyclerview
下面是java程式碼編譯
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
amap:libs/AMap_Location_V3.6.0_20170918.jar \
core:libs/core-3.0.0.jar \
map3d:libs/Android_Map3D_SDK_V5.3.0_20170815.jar \
butterknife:libs/butterknife-7.0.1.jar \
eventbus:libs/eventbus-3.0.0.jar \
easyrecyclerview:libs/easyrecyclerview-4.2.3.aar \
glide:libs/glide-3.7.0.jar \
design:libs/design-24.2.1.aar