基于開源項(xiàng)目搭建屬于自己的技術(shù)堆棧

在技術(shù)面試的時(shí)候肯定都會(huì)問到使用了哪些第三方框架昵仅,為什么使用它而不用其他的占锯。身邊朋友就有這樣的親身經(jīng)歷:

面試官:你們項(xiàng)目中加載圖片都是用的什么框架今艺?
面試者:Glide芭丁(內(nèi)心竊喜)
面試官:為什么使用Glide而不用其他的僻孝?
面試者:(沉默10s)导帝,Glide好啊,我比較喜歡穿铆。(內(nèi)心不安)
面試官:......(能不能好好聊天了)

這篇博文主要就是針對(duì)平常使用到的框架做一個(gè)整理和分析其優(yōu)劣您单。

為了從整體上進(jìn)行把握,先來看看一個(gè)完整的APP整體架構(gòu)

1. APP的整體架構(gòu)

從較高的層次將荞雏,一個(gè)APP的整體架構(gòu)可以分為兩層虐秦,即應(yīng)用層和基礎(chǔ)框架層。

  • 應(yīng)用層專注于行業(yè)領(lǐng)域的實(shí)現(xiàn)凤优,例如金融悦陋、支付、地圖導(dǎo)航别洪、社交等叨恨,它直接面向用戶,是用戶對(duì)產(chǎn)品的第一層感知挖垛。

  • 基礎(chǔ)框架層專注于技術(shù)領(lǐng)域的實(shí)現(xiàn)痒钝,提供APP公有的特性,避免重復(fù)制造輪子痢毒,它是用戶對(duì)產(chǎn)品的第二層感知送矩,例如性能、穩(wěn)定性等哪替。

一個(gè)理想的APP架構(gòu)栋荸,應(yīng)該擁有如下特點(diǎn)

  • 支持跨平臺(tái)開發(fā)
  • 具有清晰的層次劃分,同一層模塊間充分解耦凭舶,模塊內(nèi)部符合面向?qū)ο笤O(shè)計(jì)六大原則
  • 在功能晌块、性能、穩(wěn)定性等方面達(dá)到綜合最優(yōu)

基于以上設(shè)計(jì)原則帅霜,我們可以看出APP架構(gòu)圖匆背,最上層是應(yīng)用層,應(yīng)用層以下都屬于基礎(chǔ)框架層身冀,基礎(chǔ)框架層包括:組件層钝尸、基礎(chǔ)層和跨平臺(tái)層。

這里寫圖片描述

我們要討論的重點(diǎn)是基礎(chǔ)層搂根,下面開始一步一步地闡述如何基于開源函數(shù)庫搭建屬于自己的一個(gè)基礎(chǔ)技術(shù)堆棧珍促。

2. 技術(shù)選型的考量點(diǎn)

首先要明確的是,我們選擇開源函數(shù)庫或者第三方SDK剩愧、一般需要綜合考慮一下幾個(gè)方面

  • 特性:提供的特性是否滿足項(xiàng)目的需求
  • 可用性猪叙,是否提供了簡(jiǎn)潔便利的API,方便開發(fā)者集成使用。
  • 性能:性能不能太差沐悦,否則項(xiàng)目后面性能優(yōu)化會(huì)過不去成洗,可能回出現(xiàn)需要替換函數(shù)庫的情況。
  • 文檔:文檔應(yīng)該比較齊全藏否,且可讀性高瓶殃。
  • 技術(shù)支持:遇到問題或者發(fā)現(xiàn)BUG,是否能夠及時(shí)得到官方的技術(shù)支持是很重要的
  • 大懈鼻:引入函數(shù)庫會(huì)增加APK的大小遥椿,需要慎重抉擇
  • 方法數(shù):如果函數(shù)庫方法數(shù)太多,積累起來會(huì)導(dǎo)致你的APP遇到64K問題淆储,應(yīng)該盡量避免

3. 日志記錄能力

日志記錄無論在服務(wù)端開發(fā)還是移動(dòng)端開發(fā)冠场,都是一個(gè)基礎(chǔ)且重要的能力,開發(fā)人員在代碼調(diào)試以及錯(cuò)誤定位過程中本砰,大多說都要依賴日志信息碴裙,一個(gè)簡(jiǎn)潔靈活的日志記錄模塊是相當(dāng)重要的。
Logger 是基于系統(tǒng)Log類基礎(chǔ)上進(jìn)行的封裝点额,但新增了如下超贊的特性舔株。

  • 在Logcat中完美的格式化輸出,再也不用擔(dān)心和手機(jī)其他APP或者系統(tǒng)的日志信息相混淆了
  • 包含線程还棱、類载慈、方法信息,可以清楚地看到日志記錄的調(diào)用堆棧
  • 支持跳轉(zhuǎn)到源碼處
  • 支持格式化輸出JSON珍手、XML格式信息

Logcat截圖

這里寫圖片描述

當(dāng)然Logger也不是完備的办铡,它雖然支持格式化輸出JSON、XML琳要,但并不支持諸如List寡具、Set、Map和數(shù)組等常見Java集合類的格式化輸出稚补。如何解決呢童叠?可以看下LogUtils 這個(gè)開源庫,它實(shí)現(xiàn)了Logger缺失的上述特性孔厉。

再者,Logger只支持輸出日志到Logcat帖努,但項(xiàng)目開發(fā)中往往還存在將日志保存到磁盤上的需求撰豺,如何將兩者結(jié)合起來呢?這是就遇到了timber 拼余。

timber是JakeWharton開源的一個(gè)日志記錄庫污桦,它的特點(diǎn)是可擴(kuò)展的框架,開發(fā)者可以方便快捷的集成不同類型的日志記錄方式匙监,例如凡橱,打印日志到Logcat小作、打印日志到文件、打印日志到網(wǎng)絡(luò)等稼钩,timber通過一行代碼就可以同時(shí)調(diào)用多種方式顾稀。

timber的思想很簡(jiǎn)單,就是維護(hù)一個(gè)森林對(duì)象坝撑,它由不同類型的日志樹組合而成静秆,例如,Logcat記錄樹巡李、文件記錄樹抚笔、網(wǎng)絡(luò)記錄樹等,森林對(duì)象提供對(duì)外的接口進(jìn)行日志打印侨拦。每種類型的樹都可以通過種植操作把自己添加到森林對(duì)象中殊橙,或者通過移除操作從森林對(duì)象中刪除,從而實(shí)現(xiàn)該類型日志記錄的開啟和關(guān)閉狱从。

最終我們的日志記錄模塊將由timber+Logger+LogUtils組成膨蛮,當(dāng)然輪子找到了,輪子的兼容合并就得靠我們自己實(shí)現(xiàn)了矫夯,同時(shí)我們還得增加打印到文件的日志樹和打印到網(wǎng)絡(luò)的日志樹實(shí)現(xiàn)鸽疾。

4. JSON解析能力

移動(dòng)互聯(lián)網(wǎng)產(chǎn)品與服務(wù)器端通信的數(shù)據(jù)格式,如果沒有特殊需求的話训貌,一般都使用JSON格式制肮。Android系統(tǒng)也原生的提供了JSON解析的API,但是它的速度非常慢递沪,而且沒有提供簡(jiǎn)潔方便的接口來提高開發(fā)者的效率和降低出錯(cuò)的可能豺鼻。所以我們就開始找第三方開源庫來實(shí)現(xiàn)JSON解析,比較優(yōu)秀的包括如下幾種款慨。

4.1 gson

gosn是Google出品的JSON解析函數(shù)庫儒飒,可以將JSON字符串反序列化對(duì)應(yīng)的Java對(duì)象,或者反過來將Java對(duì)象序列化為對(duì)應(yīng)的JSON字符串檩奠,免去了開發(fā)者手動(dòng)通過JSONObject和JSONArray將JSON字段逐個(gè)進(jìn)行解析的煩惱桩了,也減少了出錯(cuò)的可能性,增強(qiáng)了代碼的質(zhì)量埠戳。使用gson解析時(shí)井誉,對(duì)應(yīng)的Java實(shí)體類無需使用注解進(jìn)行標(biāo)記,支持任意復(fù)雜Java對(duì)象包括沒有源代碼的對(duì)象整胃。

4.2 jackson

jcakson是Java語言的一個(gè)流行的JSON函數(shù)庫颗圣,在Android開發(fā)中使用時(shí),主要包含三部分。

  • jackson-core:JSON流處理核心庫
  • jackson-databind:數(shù)據(jù)綁定函數(shù)庫在岂,實(shí)現(xiàn)Java對(duì)象和JSON字符串流的相互轉(zhuǎn)換奔则。
  • jackson-annotations:databind使用的注解函數(shù)庫

由于jackson是針對(duì)Java語言通用的JSON函數(shù)庫,并沒有為Android優(yōu)化定制過蔽午,因此函數(shù)保重包含很多非必要的API易茬,相比其他的JSON函數(shù)庫,用于Android平臺(tái)會(huì)更顯著的增大最終生成的APK的體積祠丝。

4.3 Fastjson

Fastjson是阿里巴巴出品的一個(gè)Java語言編寫的高性能且功能完善的JSON函數(shù)庫疾呻。它采用一種“假定有序快速匹配”的算法,把JSON Parse的性能提升到極致写半,號(hào)稱是目前Java語言中最快的JSON庫岸蜗。Fastjson接口簡(jiǎn)單易用,已經(jīng)被廣泛使用在緩存序列化叠蝇、協(xié)議交互璃岳、Web輸出、Android客戶端等多種應(yīng)用場(chǎng)景悔捶。

由于是Java語言通用的铃慷,因此,以前在Android上使用時(shí)蜕该,F(xiàn)astjson不可避免的引入了很多對(duì)于Android而言冗余的功能犁柜,從而增加了包大小,很多人使用的就是標(biāo)準(zhǔn)版的fastjson堂淡,但事實(shí)上馋缅,fastjson還存在一個(gè)專門為Android定制的版本---fastjson.android 。和標(biāo)準(zhǔn)版本相比绢淀,Android版本去掉了一些Android虛擬機(jī)dalvik不支持的功能萤悴,使得jar更小。

4.4 LoganSquare

LoganSquare是近兩年崛起的快速解析和序列化JSON的Android函數(shù)庫皆的,其底層基于jackson的streaming API覆履,使用APT(Android Annotation Tool)實(shí)現(xiàn)編譯時(shí)注解,從而提高JSON解析和序列化的性能费薄。官網(wǎng)上可以看到LoganSquare和gson硝全、jackson databind的性能對(duì)比。

這里寫圖片描述

從性能方面看楞抡,LoganSquare是完勝gson和jackson的伟众。如果和fastjson相比較,兩者應(yīng)該是不相上下的拌倍。

再來看下jar包的大小

  • gson:232KB
  • jackson:259+47+1229 = 1.5M
  • Fastjson:417KB
  • Fastjson.android:256KB
  • LoganSquare:48+259 = 307KB

從性能和包大小綜合考慮赂鲤,最終我們會(huì)選擇Fastjson.android作為基礎(chǔ)技術(shù)堆棧中的JSON解析和序列化庫。

5. 數(shù)據(jù)庫操作能力

無論是iOS還是Android柱恤,底層數(shù)據(jù)庫都是基于開源的SQLite實(shí)現(xiàn)数初,然后在系統(tǒng)層封裝成用于應(yīng)用層的API。雖然直接使用系統(tǒng)的數(shù)據(jù)庫API性能很高梗顺,但是這些API接口并不是很方便開發(fā)者使用泡孩,一不小心就會(huì)引入Bug,而且代碼的視覺效果也不佳寺谤。為了解決這個(gè)問題仑鸥,對(duì)象關(guān)系映射(ORM)框架出現(xiàn)了,比較好的有ActiveAndroid变屁,ormlite和greenDAO眼俊。

5.1 ActiveAndroid

ActiveAndroid是一種Active Record風(fēng)格的ORM框架,Active Record(活動(dòng)目錄)是Yii,Rails等框架中對(duì)ORM實(shí)現(xiàn)的典型命名方式粟关。它極大的簡(jiǎn)化數(shù)據(jù)庫的使用疮胖,使用面向?qū)ο蟮姆绞焦芾頂?shù)據(jù)庫,告別手寫SQL的歷史闷板。每一個(gè)數(shù)據(jù)庫表都可以被映射為一個(gè)類澎灸,開發(fā)者只需使用類似save()或者delete()這樣的函數(shù)即可。

不過ActiveAndroid已經(jīng)基本上處于維護(hù)階段了遮晚,最新的一個(gè)Release版本是在2012年發(fā)布的性昭。

5.2 ormlite

ormlite是Java平臺(tái)的一個(gè)ORM框架,支持JDBC連接县遣、Spring和Android平臺(tái)糜颠。在Android中使用時(shí),它包含兩部分艺玲。

  • ormlite-core:核心模塊括蝠,無論在哪個(gè)平臺(tái)使用,都必須基于這個(gè)核心庫饭聚,是實(shí)現(xiàn)ORM映射的關(guān)鍵模塊忌警。
  • ormlite-android:基于ormlite-core封裝的針對(duì)Android平臺(tái)的適配器模塊,Android開發(fā)中主要跟這個(gè)模塊打交道秒梳。

與ActiveAndroid類似法绵,ormlite也已經(jīng)不是一個(gè)活躍的開源庫,最近一次Release版本是在2013年發(fā)布的酪碘。

5.3 greenDAO

greenDAO是一個(gè)輕量級(jí)且快速的ORM框架朋譬,專門為Android高度優(yōu)化和定制,它能夠支持每秒數(shù)千條記錄的CRUD操作兴垦。官網(wǎng)上給出一張性能對(duì)比圖

這里寫圖片描述

縱軸表示每秒執(zhí)行的操作數(shù)徙赢。而且greenDAO處在高度活躍中字柠,最新Release版本是在2017年3月份發(fā)布的

5.4 Realm

Realm是一個(gè)全新的移動(dòng)數(shù)據(jù)庫引擎,它既不是基于iOS平臺(tái)的Core Data狡赐,也不是基于SQLite窑业,它擁有自己的數(shù)據(jù)庫存儲(chǔ)引擎,并實(shí)現(xiàn)了高效快速的數(shù)據(jù)庫構(gòu)建操作枕屉,相比Core Data和SQLite常柄,Realm操作要快很多,跟ORM框架相比就更不用說了搀擂。

Realm的好處如下:

  • 跨平臺(tái):Android和iOS已經(jīng)是事實(shí)上的兩大移動(dòng)互聯(lián)網(wǎng)操作系統(tǒng)西潘,絕大多數(shù)應(yīng)用都會(huì)支持這兩個(gè)平臺(tái)。使用Realm哨颂,Android和iOS開發(fā)者無需考慮內(nèi)部數(shù)據(jù)的架構(gòu)喷市,調(diào)用Realm提供的API即可輕松完成數(shù)據(jù)的交換。
  • 用法簡(jiǎn)單:相比Core Data和SQLite所需的入門知識(shí)威恼,Realm可以極大降低開發(fā)者的學(xué)習(xí)成本东抹,快速實(shí)現(xiàn)數(shù)據(jù)庫存儲(chǔ)功能。
  • 可視化操作:Realm為開發(fā)者提供了一個(gè)輕量級(jí)的數(shù)據(jù)庫可視化操作工具沃测,開發(fā)者可以輕松查看數(shù)據(jù)庫中的內(nèi)容缭黔,并實(shí)現(xiàn)簡(jiǎn)單地插入和刪除等操作。

我們看下上述四種數(shù)據(jù)庫包大小蒂破。

  • activeandroid:40KB
  • greendao:100KB
  • ormlite-android:57KB
  • realm-android:4.2M

可以看出馏谨,前三個(gè)還是正常范圍,但Realm的大小一般項(xiàng)目可能無法接受附迷。這是因?yàn)椴煌珻PU架構(gòu)平臺(tái)的 .so 文件增加了整個(gè)包的大小惧互,由于arm平臺(tái)的so在其他平臺(tái)上面能夠以兼容模式運(yùn)行的,雖然會(huì)損失性能喇伯,但是可以極大地減少函數(shù)庫占用的空間喊儡。因此,可以選擇只保留armeabi-v7a和x86兩個(gè)平臺(tái)的 .so 文件稻据,直接刪除無用的 .so 文件艾猜,或者通過工程的build.gradle文件中增加 ndk abi 過濾,語句如下:

android {
    ...
    defaultConfig {
        ...
        ndk {
            abiFilters "armeabi-v7a", "x86"
        } 
    }
}

因此捻悯,綜合性能考慮匆赃,包大小以及開源庫的可持續(xù)發(fā)展等因素,我們最終選擇greenDAO今缚。

6. 網(wǎng)絡(luò)通信能力

現(xiàn)在的APP幾乎都需要從服務(wù)器獲取數(shù)據(jù)算柳,不可避免的需要具備網(wǎng)絡(luò)通信的能力,否則就是一個(gè)死界面姓言。

6.1 android-async-http

Android最經(jīng)典的網(wǎng)絡(luò)異步通信函數(shù)庫瞬项,它對(duì)Apache的HttpClient API的封裝使得開發(fā)者可以簡(jiǎn)潔優(yōu)雅地實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求和響應(yīng)蔗蹋,并且同時(shí)支持同步和異步請(qǐng)求。主要特性如下:

  • 支持異步HTTP請(qǐng)求囱淋,并在匿名回調(diào)函數(shù)中處理響應(yīng)
  • 在子線程中發(fā)起HTTP請(qǐng)求
  • 內(nèi)部采用線程池來處理并發(fā)請(qǐng)求
  • 通過RequestParams類實(shí)現(xiàn)GET/POST參數(shù)構(gòu)造
  • 無需第三方庫支持即可實(shí)現(xiàn)Multipart文件上傳
  • 庫的大小只有60KB
  • 支持多種移動(dòng)網(wǎng)絡(luò)環(huán)境下自動(dòng)智能的請(qǐng)求重試機(jī)制
  • HTTP響應(yīng)中實(shí)現(xiàn)自動(dòng)的gzip解碼纸颜,實(shí)現(xiàn)快速請(qǐng)求響應(yīng)
  • 內(nèi)置多種形式的響應(yīng)解析,有原生的字節(jié)流绎橘、String、JSON對(duì)象唠倦,甚至可以將response寫入到文件中称鳞。
  • 可選的永久cookie保存,內(nèi)部實(shí)現(xiàn)使用的是Android的SharedPreferences稠鼻。

但是在6.0之后冈止,系統(tǒng)對(duì)開發(fā)者隱藏了HttpClient函數(shù)庫,這顯著增大了使用android-async-http的代價(jià)候齿。 如果鐵了心想繼續(xù)使用HttpClient熙暴,官方推薦的做法是在編譯期引入org.apache.http.legacy 這個(gè)庫,庫目錄在Android SDK目錄下的platforms\android-23\optional中找到慌盯,它的作用是確保在編譯時(shí)不會(huì)出現(xiàn)找不到HttpClient相關(guān)API的錯(cuò)誤周霉,在應(yīng)用運(yùn)行時(shí)可以不依賴這個(gè)庫,因?yàn)?.0以上的Android系統(tǒng)還沒有真正移除HttpClient的代碼亚皂,只不過API設(shè)置為對(duì)開發(fā)者不可見俱箱。我們查看android-async-http源碼發(fā)現(xiàn),需要使用下面這個(gè)函數(shù)庫來替換之前的Apache的HttpClient灭必。

dependencies {
    compile 'cz.msebera.android:httpclient:4.3.6'
}

這樣顯著的增加了APP的包的大小狞谱,如果想繼續(xù)使用android-async-http,那么你的APP需要額外增加1.1MB左右的大小禁漓。

6.2 OkHttp

OkHttp是一個(gè)高效的HTTP客戶端跟衅,具有如下特性。

  • 支持HTTP/2和SPDY播歼,對(duì)同一臺(tái)主機(jī)的所有請(qǐng)求共享同一個(gè)socket伶跷。
  • 當(dāng)SPDY不可用時(shí),使用連接池減少請(qǐng)求的延遲秘狞。
  • 透明的GZIP壓縮減少下載數(shù)據(jù)大小
  • 緩存響應(yīng)避免重復(fù)的網(wǎng)絡(luò)請(qǐng)求

OkHttp在網(wǎng)絡(luò)性能很差的情況下能夠很好地工作撩穿,它能夠避免常見的網(wǎng)絡(luò)連接問題。如果你的HTTP服務(wù)有多個(gè)IP地址谒撼,OkHttp在第一次連接失敗是食寡,會(huì)嘗試其他可選的地址。這對(duì)于IPv4+IPv6以及托管在冗余數(shù)據(jù)中心的服務(wù)來說是必要的廓潜。OkHttp使用現(xiàn)代的TLS特性(SNI,ALPN)初始化HTTP連接抵皱,當(dāng)握手失敗時(shí)善榛,會(huì)降低使用TSL1.0初始化連接。

OkHttp依賴于okio呻畸,okio作為java.io和java.nio的補(bǔ)充移盆,是square公司開發(fā)的一個(gè)函數(shù)庫。okio使得開發(fā)者可以更好地訪問伤为、存儲(chǔ)和處理數(shù)據(jù)咒循。一開始是作為OkHttp的一個(gè)組件存在的,當(dāng)然我們也可以單獨(dú)使用它绞愚。

使用Okhttp需要引入Jar包叙甸,包的大小為:326+66 = 392KB

6.3 Volley

Volley是Google在2013年發(fā)布的用于Android平臺(tái)的網(wǎng)絡(luò)通信庫,能使網(wǎng)絡(luò)通信更快位衩、更簡(jiǎn)單裆蒸、更健壯。官網(wǎng)配出一張弓箭發(fā)射圖來說明Volley特別使用于數(shù)據(jù)量小等通信頻繁的場(chǎng)景糖驴。

這里寫圖片描述

具體的將僚祷,Volley是為了簡(jiǎn)化網(wǎng)絡(luò)任務(wù)而設(shè)計(jì)的,用于幫助開發(fā)者處理請(qǐng)求贮缕、加載辙谜、緩存、多線程感昼、同步等任務(wù)筷弦。Volley設(shè)計(jì)了一個(gè)靈活的網(wǎng)絡(luò)棧適配器,在Android2.2及之前的版本中抑诸,Volley底層使用Apache HttpClient烂琴,在Android2.3及以上版本中,它使用HttpURLConnection來發(fā)起網(wǎng)絡(luò)請(qǐng)求蜕乡,而且開發(fā)者也很容易將網(wǎng)絡(luò)棧切換成使用OkHttp奸绷。
Volley 官方源碼托管在Google Source上面,使用時(shí)只能直接以Jar包形式引入层玲,如果想在Gradle中使用compile在線引入号醉,可以考慮使用mcxiaoke在Github上面的Volley Mirror,然后再build.gradle中使用如下語句即可辛块。

compile 'com.mcxiaoke.volley:library:1.0.19'

6.4 Retrofit

確切的說畔派,Retrofit并不是一個(gè)完整的網(wǎng)絡(luò)請(qǐng)求函數(shù)庫,而是將REST API轉(zhuǎn)換成Java接口的一個(gè)開源函數(shù)庫润绵,它要求服務(wù)器API接口遵循REST規(guī)范线椰。基于注解使得代碼變得很簡(jiǎn)潔尘盼,Retrofit默認(rèn)情況下使用GSON作為JSON解析器憨愉,使用OkHttp實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求烦绳,三者通常配合使用,當(dāng)然我們也可以將這兩者換成其他的函數(shù)庫配紫。

通過以上分析径密,HttpURLConnection、Apache HttpClient 和OkHttp封裝了底層的網(wǎng)絡(luò)請(qǐng)求躺孝,而android-async-http享扔,Volley和Retrofit是基于前面三者的基礎(chǔ)上二次開發(fā)而成。

最后看下函數(shù)庫的大小

  • android-async-http:106KB+1.1MB = 1.2MB
  • OkHttp:326KB+66KB = 392KB
  • Volley:94KB
  • Retrofit:122KB+211KB = 333KB

7. 圖片緩存和顯示能力

圖片緩存函數(shù)庫有很多非常優(yōu)秀的植袍,開發(fā)人員可以根據(jù)需求進(jìn)行選擇惧眠。傳統(tǒng)的圖片緩存方案中設(shè)置有兩級(jí)緩存,分別是內(nèi)存緩存和磁盤緩存奋单。在Facebook推出的Fresco中,它增加了一級(jí)緩存猫十,也就是Native緩存览濒,這極大地降低了使用Fresco的APP出現(xiàn)OOM的概率。

7.1 BitmapFun

BitmapFun函數(shù)庫是Android官方教程中的一個(gè)圖片加載和緩存實(shí)例拖云,對(duì)于簡(jiǎn)單的圖片加載需求來說贷笛,使用BitmapFun就夠了,在早期用的多宙项,現(xiàn)在漸漸退出了實(shí)際項(xiàng)目開發(fā)的舞臺(tái)乏苦。

7.2 Picasso

Picasso是著名的square公司眾多開源項(xiàng)目中的一個(gè),它除了實(shí)現(xiàn)圖片的下載和二級(jí)緩存功能尤筐,還解決了常見的一些問題汇荐。

  • 在adapter中正常的處理ImageView回收和下載的取消
  • 使用盡量小的內(nèi)存實(shí)現(xiàn)復(fù)雜的圖像變換

在Picasso中,我們使用一行代碼即可實(shí)現(xiàn)圖片下載并渲染到ImageView中盆繁。

Picasso.with(context).load(url).into(imageView);

7.3 Glide

Glide是Google推薦的用于Android平臺(tái)上的圖片加載和緩存函數(shù)庫掀淘。這個(gè)庫被廣泛應(yīng)用在Google的開源項(xiàng)目中,Glide和Picasso有90%的相似度油昂,只是在細(xì)節(jié)上還是存在不少區(qū)別革娄。Glide為包含圖片的滾動(dòng)列表做了盡可能流暢的優(yōu)化。除了靜態(tài)圖片冕碟,Glide也支持GIF格式圖片的顯示。Glide提供了靈活的API可以讓開發(fā)者方便地替換下載圖片所用的網(wǎng)絡(luò)函數(shù)庫,默認(rèn)情況下昧穿,它使用HttpUrlConnection作為網(wǎng)絡(luò)請(qǐng)求模塊第美,開發(fā)者也可以根據(jù)自己項(xiàng)目的實(shí)際需求靈活使用Google的Volley或者Square的OkHttp等函數(shù)庫進(jìn)行替換。

Glide的使用也可以使用一行代碼來完成挑庶,語句如下

Glide.with(context).load(url).into(imageView);

7.4 Fresco

Fresco是Facebook開源的功能強(qiáng)大的圖片加載和緩存函數(shù)庫叹放,相比其他圖片緩存庫饰恕,F(xiàn)resco最顯著的特點(diǎn)是具有三級(jí)緩存:兩級(jí)內(nèi)存緩存和一級(jí)磁盤緩存。主要特性如下:

  • 漸進(jìn)式地加載JPEG圖片
  • 顯示GIF和WebP動(dòng)畫
  • 可擴(kuò)展井仰,可自定義圖片加載和顯示
  • 在Android 4.X和一下的系統(tǒng)上埋嵌,將圖片放在Android內(nèi)存一個(gè)特殊的區(qū)域,從而使得應(yīng)用運(yùn)行更流暢俱恶,同時(shí)極大減低出現(xiàn)OutOfMemoryError的錯(cuò)誤雹嗦。

7.5 Android-Universal-Image-Loader

Android-Universal-Image-Loader簡(jiǎn)稱UIL,是Android平臺(tái)老牌的圖片下載和緩存函數(shù)庫合是,功能強(qiáng)大靈活且高度可自定義了罪,它提供一系列配置選項(xiàng),并能很好地控制圖片加載和緩存的過程聪全。使用者甚多泊藕,現(xiàn)在項(xiàng)目仍在使用。UIL也支持二級(jí)緩存难礼,特性如下:

  • 同步或異步的多線程圖片加載
  • 高度可自定義:線程池娃圆、下載器、解碼器蛾茉、內(nèi)存和磁盤緩存讼呢、圖片顯示選項(xiàng)等。
  • 每張圖片的顯示支持多種自定義選項(xiàng):默認(rèn)存根圖片谦炬、解碼選項(xiàng)悦屏、Bitmap處理和顯示等。
  • 圖片可緩存在內(nèi)存或者磁盤(設(shè)備的文件系統(tǒng)或者SD卡)上键思。
  • 可實(shí)時(shí)監(jiān)聽圖片加載流程础爬,包括下載進(jìn)度。

最后看下幾個(gè)庫的包大小

  • BitmapFun:71KB
  • Picasso:120KB
  • Glide:475KB
  • Fresco:47KB+93KB+93KB+10KB+3MB+62KB+8KB+111KB = 3.4MB
  • Android-Universal-Image-Loader:162KB

圖片函數(shù)庫的選擇需要根據(jù)APP的具體情況而定吼鳞,對(duì)于嚴(yán)重依賴圖片緩存的APP,例如壁紙類幕帆,圖片社交類APP來說,可以選擇最專業(yè)的Fresco赖条。對(duì)于一般的APP失乾,選擇Fresco會(huì)顯得比較重,畢竟Fresco 3.4MB的體量擺在這纬乍。

根據(jù)APP對(duì)圖片顯示和緩存的需求從低到高我們可以對(duì)以上函數(shù)庫做一個(gè)排序

BitmapFun < Picasso < Android-Universal-Image-Loader < Glide < Fresco

值得一提的是碱茁,如果你的APP計(jì)劃使用React Native進(jìn)行部分模塊功能的開發(fā)的話,那么在基礎(chǔ)函數(shù)庫選擇方面需要考慮和React Native的依賴庫的復(fù)用仿贬,這樣可以減少引入React Native 所增加的APP的大小纽竣,可以復(fù)用的函數(shù)庫有:OkHttp,F(xiàn)resco,jackson-core.

Thanks

《Android高級(jí)進(jìn)階》顧浩鑫
csdn:基于開源項(xiàng)目搭建屬于自己的技術(shù)堆棧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蜓氨,隨后出現(xiàn)的幾起案子聋袋,更是在濱河造成了極大的恐慌,老刑警劉巖穴吹,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件幽勒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡港令,警方通過查閱死者的電腦和手機(jī)啥容,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顷霹,“玉大人咪惠,你說我怎么就攤上這事×艿恚” “怎么了遥昧?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)朵纷。 經(jīng)常有香客問我炭臭,道長(zhǎng),這世上最難降的妖魔是什么柴罐? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任徽缚,我火速辦了婚禮憨奸,結(jié)果婚禮上革屠,老公的妹妹穿的比我還像新娘。我一直安慰自己排宰,他們只是感情好似芝,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著板甘,像睡著了一般党瓮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盐类,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天寞奸,我揣著相機(jī)與錄音,去河邊找鬼在跳。 笑死枪萄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的猫妙。 我是一名探鬼主播瓷翻,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了齐帚?” 一聲冷哼從身側(cè)響起妒牙,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎对妄,沒想到半個(gè)月后湘今,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饥伊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年象浑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琅豆。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡愉豺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茫因,到底是詐尸還是另有隱情蚪拦,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布冻押,位于F島的核電站驰贷,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏洛巢。R本人自食惡果不足惜括袒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稿茉。 院中可真熱鬧锹锰,春花似錦、人聲如沸漓库。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渺蒿。三九已至痢士,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茂装,已是汗流浹背怠蹂。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留少态,地道東北人城侧。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像况增,于是被迫代替她去往敵國(guó)和親赞庶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,498評(píng)論 25 707
  • 太長(zhǎng)了,還是轉(zhuǎn)載吧...今天在看博客的時(shí)候歧强,無意中發(fā)現(xiàn)了@Trinea在GitHub上的一個(gè)項(xiàng)目Android開源...
    龐哈哈哈12138閱讀 20,140評(píng)論 3 283
  • 網(wǎng)絡(luò)相關(guān) ion– 一個(gè)異步網(wǎng)絡(luò)請(qǐng)求和圖片加載的庫澜薄,一個(gè)庫能搞定幾乎所有的網(wǎng)絡(luò)請(qǐng)求。 多線程下載– Android...
    justCode_閱讀 1,715評(píng)論 1 22
  • 10月31日摊册,萬圣節(jié)肤京,國(guó)際規(guī)定為第一個(gè)人口問題犧牲者紀(jì)念日。國(guó)際電臺(tái)首席播音員希瑟的工作車緩緩行駛在1313號(hào)國(guó)際...
    卡沙薩閱讀 1,627評(píng)論 0 1
  • 容貌是一扇門茅特。 成也它忘分,拜也它。 愛它白修,事事順心妒峦,厭它時(shí),事事不順兵睛。 花無百日紅肯骇。 人無千日好。 看不得它擁有半點(diǎn)...
    uiu閱讀 269評(píng)論 0 1