在一個Android系統中,尤爲是開發各個app模塊的開發人員,可能會用到同一個第三方的sdk,好比xutils、volley、gson、amap、imageloader等。目前你們一般的作法是把第三方sdk集成到本身的app中,與app一塊兒打包生成一個apk。這樣作當然沒有問題,可是會給系統帶來一些額外的很差影響:好比多個app都用了同一個sdk,形成了sdk的冗餘,增大了整個系統ota包的大小;在寫Andriod.mk時,須要注意聲明使用的sdk是否與系統中其餘app使用的sdk重名;不一樣的app可能使用了不一樣版本的sdk,致使sdk版本不統一。那是否有一種方案能解決這個問題呢?答案是確定的,並且Android系統自己就給咱們提供了這鐘機制,那就是「uses-library」。"uses-library"只是解決了使用的問題,具體還涉及到系統源碼和編譯腳本的一些修改,下邊就來具體說一說,如何作到解決編譯時依賴、運行時動態加載sdk的問題:java
一、在系統源碼裏聲明sdk,實際上是sdk中的jar包。這個能夠參考編譯好的rom中的/system/etc/permission/xxx.xml,咱們能夠考慮修改/framework/base/data/etc/platform.xml,能夠添加如下內容:android
<!-- This is a list of all the amap libraries available for application code to link against. --> <library name="android.amap.location" file="/system/framework/android.amap.location.jar" /> <library name="android.amap.services" file="/system/framework/android.amap.services.jar"/> <library name="android.amap.map" file="/system/framework/android.amap.map.jar"/> <library name="android.amap.2dmap" file="/system/framework/android.amap.2dmap.jar"/>
二、將第三方sdk的jar包集成到系統的/system/framework/下,這個能夠在vendor/xxx/prebuilt/(不一樣的項目對應的目錄可能不一樣)中新建一個項目,把第三方sdk的jar和so提取出來,編寫Android.mk腳本,以android.amap.map爲例,app
include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, .) LOCAL_NO_STANDARD_LIBRARIES := true LOCAL_STATIC_JAVA_LIBRARIES := amap_loc LOCAL_MODULE := android.amap.location LOCAL_MODULE_CLASS := JAVA_LIBRARIES LOCAL_NO_EMMA_INSTRUMENT := true LOCAL_NO_EMMA_COMPILE := true LOCAL_DX_FLAGS := --core-library include $(BUILD_JAVA_LIBRARY) ################################################# include $(CLEAR_VARS) LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := amap_loc:libs/AMap_Location_v1.4.0_20150830.jar include $(BUILD_MULTI_PREBUILT) ################################################# include $(CLEAR_VARS) LOCAL_MODULE := libamapv304 LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_CERTIFICATE := PRESIGNED LOCAL_MODULE_SUFFIX := .so LOCAL_SRC_FILES := so/libamapv304.so include $(BUILD_PREBUILT)
三、在以上步驟以後,還須要將編譯出來的module集成到系統中,也就是在prebuilt.mk或者其餘什麼地方PRODUCT_PACKAGES中添加上對應的module name,否則系統編譯沒有問題,生成的rom包中確沒有對應的文件內容。ui
四、修改完系統的編譯問題後,接下來須要解決APP的編譯問題,將Android.mk中聲明的JAVA_STATIC_LIBRARIES依賴去除,改成使用LOCAL_JAVA_LIBRARIES,以下:code
LOCAL_JAVA_LIBRARIES := android.amap.location
五、最後要修改的是AndroidManifest.xml中使用library問題,在application元素內聲明以下,必定要在application標籤內哦:orm
<uses-library android:name="android.amap.location" />
最後,須要注意一個坑:若是jar包中有asset怎麼辦?好比map sdk中有一些依賴的asset資源,在以前靜態編譯依賴時沒有問題,可是使用uses-library方式時,因爲jar包是動態加載,asset資源在運行時沒法被找到,因此解決方法是:事先將sdk中的asset解壓出來放到app的asset中,系統集成的sdk中能夠將asset目錄刪除了。
xml