天天看點

Android App 瘦身總結 第二章 jni動态庫及cpu相容Android進階之路系列:http://blog.csdn.net/column/details/16488.htmlAndroid進階之路系列:http://blog.csdn.net/column/details/16488.html

Android進階之路系列:http://blog.csdn.net/column/details/16488.html

在前一章主要分析了圖檔資源部分的優化(http://blog.csdn.net/chzphoenix/article/details/75227590),這一章重點分析jni動态庫部分。

由于我們的app業務較複雜,存在地圖定位、圖檔處理、第三方浏覽器核心等功能,這些功能都不可避免的引入了jni動态庫 ——  ".so"檔案。

我們知道jni動态庫是用c\c++編寫,目的是利用native層在運算等方面的優勢提高應用性能。但是随着業務的增多,越來越多的jni動态庫的加入就會導緻這部分膨脹并占據很大一部分空間。

以百度地圖為例,隻使用基礎地圖和定位功能,每種平台下的幾個.so檔案加起來有2M多,如果将所有平台加入就會有10M多。

解決動态庫的問題,要從幾點着手:

一、利弊分析,按需引用

從兩個例子來說。

(1)我們app中的圖檔處理業務,早期采用了一套第三方庫。但是經過幾次疊代業務穩定下來後,我們發現大部分功能都已經變了,絕大多數處理可以在java層進行也不影響性能,而唯一的裁剪功能可以使用一套更加精緻的庫來替換,因為原來的第三方庫是一套非常完整的圖檔解決方案,90%以上的功能我們都用不上。

(2)使用百度地圖,可以在平台上根據app需要的功能定制動态庫,沒必要将所有功能一起打包進app

上面兩個例子說明,在預開發階段,我們要明确所需,以最小的代價完成功能;在疊代過程中,我們要持續的審視app各項業務功能,根據變更及時調整。

這點很難總結出具體方法,需要大家對業務功能深入了解,多思考分析。

二、平台相容

Android系統中有以下幾種平台:ARMv5,ARMv7,x86 ,MIPS ,ARMv8,MIPS64和x86_64。分别對應:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64

需要考慮下面幾點:

(1)相容關系

它們之間的相容關系是:x86、x8664、armeabi-v7a、arm64-v8a都支援armeabi,但是x86裝置不保證100%不發生crash,特别是對舊裝置;64位(arm64-v8a, x8664, mips64)能夠運作32位的函數庫,但無法得到64位優化過的性能。

(2)占有率

目前Android裝置中以arm系列處理器為主流;x86系列處理器占有率較少,其中微軟旗下的Lumia系列上使用較多,另外在部分平闆裝置上有使用;MIPS系列處理器占有率極少,這個處理器主要用在嵌入式。

由于arm是主流甚至成為标準,x86和mips處理器會通過一個特殊的轉換軟體去相容arm指令集。

(3)性能優化

除了上面提到的64位處理器的相對于32位的優化,另外還有arm-v7處理器所支援的硬體浮點運算,arm雖然相容但是也會損失性能。

這部分優化就需要我們根據自身app的功能、使用者分析等方面全面去考慮。

比如MIPS裝置,根據我們的統計沒有使用者使用這類cpu,可預測的時間内也不會超過萬分之一,而且還有相容性存在,是以我們果斷忽略了這部分。

比如x86裝置,根據統計我們使用者中這類CPU占有率少于萬分之一,同樣短期内不會增長,在一些x86機器上測試通過後我們也選擇忽略。

至于arm系列,由于地圖等功能的存在,對運算等功能的性能要求較高,是以我們全部保留了。

如果你的app中動态庫沒有使用浮點運算或64位優化的相關功能,可以考慮去掉armeabi-v7a、arm64-v8a。

使用gradle可以選擇打包時隻打包某幾個平台的動态庫,這也解決了使用gradle依賴引入的lib中的動态庫無法清除的問題,具體代碼如下:

android {
    ...

    defaultConfig {    
        ...
        ndk {
            // 設定支援的 SO 庫構架,注意這裡要根據你的實際情況來設定
            abiFilters 'armeabi'// 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64'
        }
    }

}
           

注意需要在gradle.properties中添加android.useDeprecatedNdk=true

一定要注意保留的平台對應的目錄下包含了全部需要的動态庫!

注:目前國内主流的app中基本上隻保留了armeabi或armeabi-v7a,不過他們應該對這些動态庫重新編譯過,大家有興趣可以研究參考下。

三、動态加載

如果存在特别大的動态庫,可以考慮不打包進apk,通過預下載下傳動态延遲加載來實作,因為一般使用動态庫的功能都不是啟動app就需要的。

四、總結

動态庫部分差不多就這些情況,這裡沒有什麼便捷的工具來使用,更主要是靠我們對業務熟悉程度進行全面細緻的分析權衡。下一章會從代碼方面來進行部分探讨。

Android進階之路系列:http://blog.csdn.net/column/details/16488.html