Android源碼分析計(jì)劃

1. okhttp3 源碼分析

  • 好處
    • 擁有自動(dòng)維護(hù)的socket連接池
    • 擁有隊(duì)列線程池
    • 擁有Interceptors(攔截器)輕松處理請(qǐng)求與響應(yīng)
    • 基于Headers的緩存策略
  • 流程
    當(dāng)我們用OkHttpClient.newCall(request)進(jìn)行execute/enenqueue時(shí),實(shí)際是將請(qǐng)求Call放到了Dispatcher中,okhttp使用Dispatcher進(jìn)行線程分發(fā),它有兩種方法,一個(gè)是普通的同步單線程;另一種是使用了隊(duì)列進(jìn)行并發(fā)任務(wù)的分發(fā)(Dispatch)與回調(diào),我們下面主要分析第二種,也就是隊(duì)列這種情況,這也是okhttp能夠競爭過其它庫的核心功能之一
  • 核心
  • 設(shè)計(jì)模式
    1 .CacheStrategy使用Factory模式進(jìn)行構(gòu)造
    2 .Interceptor責(zé)任鏈模式(事件傳遞就是責(zé)任鏈機(jī)制)
    Interceptor是 OkHttp 核心類,它把網(wǎng)絡(luò)請(qǐng)求、緩存、透明壓縮等功能都統(tǒng)一了起來,每一個(gè)功能都是一個(gè) Interceptor,它們?cè)龠B接成一個(gè) Interceptor.Chain,如鏈條一般,分工明確,完美完成一次網(wǎng)絡(luò)請(qǐng)求。
    3 . Request與Response都是使用Builder模式創(chuàng)建
    4 .ExecutorService使用單例獲取線程池(標(biāo)準(zhǔn)懶漢模式)
public synchronized ExecutorService executorService() {
 if (executorService == null) {
   executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
       new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
 }
 return executorService;
}
  • 注意事項(xiàng)(遇到的坑)
    post方式不支持緩存
    在獲取到ResponseBody對(duì)象后,注意要復(fù)制一個(gè)新的,否則消費(fèi)掉了就沒了
    enqueue異步執(zhí)行,onResponse是在子線程中,不能直接刷新UI
  • 項(xiàng)目使用案例
    okgo

2. retrofit

  • 定義

  • 流程

    • 通過解析 網(wǎng)絡(luò)請(qǐng)求接口的注解 配置 網(wǎng)絡(luò)請(qǐng)求參數(shù)
    • 通過 動(dòng)態(tài)代理 生成 網(wǎng)絡(luò)請(qǐng)求對(duì)象
    • 通過 網(wǎng)絡(luò)請(qǐng)求適配器 將 網(wǎng)絡(luò)請(qǐng)求對(duì)象 進(jìn)行平臺(tái)適配
      平臺(tái)包括:Android、Rxjava、Guava和java8
    • 通過 網(wǎng)絡(luò)請(qǐng)求執(zhí)行器 發(fā)送網(wǎng)絡(luò)請(qǐng)求
    • 通過 數(shù)據(jù)轉(zhuǎn)換器 解析服務(wù)器返回的數(shù)據(jù)
    • 通過 回調(diào)執(zhí)行器 切換線程(子線程 ->>主線程)
    • 用戶在主線程處理返回結(jié)果
  • 設(shè)計(jì)模式

  • 注意事項(xiàng)(遇到的坑)

  • 項(xiàng)目使用案例

3. Glide

  • 優(yōu)點(diǎn)
    • 多樣化媒體加載
      Glide 不僅是一個(gè)圖片緩存,它支持 Gif、WebP、縮略圖。甚至是 Video

    • 生命周期集成
      通過設(shè)置綁定生命周期,我們可以更加高效的使用Glide提供的方式進(jìn)行綁定,這樣可以更好的讓加載圖片的請(qǐng)求的生命周期動(dòng)態(tài)管理起來

    • 高效的緩存策略
      A. 支持Memory和Disk圖片緩存
      B. Picasso 只會(huì)緩存原始尺寸的圖片,而 Glide 緩存的是多種規(guī)格,也就意味著 Glide 會(huì)根據(jù)你 ImageView 的大小來緩存相應(yīng)大小的圖片尺寸
      C. 內(nèi)存開銷小
      默認(rèn)的 Bitmap 格式是 RGB_565 格式,而 Picasso 默認(rèn)的是 ARGB_8888 格式,這個(gè)內(nèi)存開銷要小一半。

  • 緩存策略
    • 1 .DiskCacheStrategy.NONE 不做磁盤緩存
    • 2 .DiskCacheStrategy.SOURCE 只緩存圖像原圖
    • 3 .DiskCacheStrategy.RESULT 只緩存加載后的圖像,即處理后最終顯示時(shí)的圖像
    • 4 .DiskCacheStrategy.ALL 緩存所有版本的圖像(默認(rèn)行為
只從緩存中讀取,如果緩存沒有,則失敗.
private void retrieveFromCache(){
    GlideApp.with(this)
            .asBitmap()
            .load(URL)
            .placeholder(R.drawable.default_avatar)
            .error(R.drawable.image_error)
            .fallback(R.drawable.fallback_nodata)
            .onlyRetrieveFromCache(true)
            .into(mImageView);
}
跳過緩存. 每次都從服務(wù)端獲取最新.
/**
 * 跳過緩存. 每次都從服務(wù)端獲取最新.
 * diskCacheStrategy: 磁盤緩存
 * skipMemoryCache:內(nèi)存緩存
 */
private void skipCache(){
    GlideApp.with(this)
            .asBitmap()
            .load(URL)
            .diskCacheStrategy(DiskCacheStrategy.NONE)
            .skipMemoryCache(true)
            .into(mImageView);
}

Glide 需要緩存的 圖片資源 分為兩類:
原始圖片(Source) :即圖片源的圖片初始大小 & 分辨率
轉(zhuǎn)換后的圖片(Result) :經(jīng)過 尺寸縮放 和 大小壓縮等處理后的圖片

內(nèi)存緩存:防止應(yīng)用 重復(fù)將圖片數(shù)據(jù) 讀取到內(nèi)存當(dāng)中
  • 只緩存轉(zhuǎn)換過后的圖片
// 默認(rèn)開啟內(nèi)存緩存,用戶不需要作任何設(shè)置
Glide.with(this)
     .load(url)
     .into(imageView);

// 可通過 API 禁用 內(nèi)存緩存功能
Glide.with(this)
     .load(url)
     .skipMemoryCache(true) // 禁用 內(nèi)存緩存
     .into(imageView);

Glide的內(nèi)存緩存實(shí)現(xiàn)是基于:LruCache 算法(Least Recently Used) & 弱引用機(jī)制
LruCache算法原理:將 最近使用的對(duì)象 用強(qiáng)引用的方式 存儲(chǔ)在LinkedHashMap中 ;當(dāng)緩存滿時(shí) ,將最近最少使用的對(duì)象從內(nèi)存中移除
弱引用:弱引用的對(duì)象具備更短生命周期,因?yàn)?**當(dāng)JVM進(jìn)行垃圾回收時(shí),一旦發(fā)現(xiàn)弱引用對(duì)象,都會(huì)進(jìn)行回收(無論內(nèi)存充足否)

硬盤緩存:防止應(yīng)用 重復(fù)從網(wǎng)絡(luò)或其他地方重復(fù)下載和讀取數(shù)據(jù)
  • 可緩存原始圖片 & 緩存轉(zhuǎn)換過后的圖片,用戶自行設(shè)置


    image.png

    image.png

    image.png

    image.png
with()

得到一個(gè)RequestManager對(duì)象
根據(jù)傳入with()方法的參數(shù) 將Glide圖片加載的生命周期與Activity/Fragment的生命周期進(jìn)行綁定,從而實(shí)現(xiàn)自動(dòng)執(zhí)行請(qǐng)求,暫停操作

load()

預(yù)先創(chuàng)建好對(duì)圖片進(jìn)行一系列操作(加載、編解碼、轉(zhuǎn)碼)的對(duì)象,并全部封裝到 DrawableTypeRequest `對(duì)象中。

into()

即獲取圖片資源 & 加載圖片并顯示

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,115評(píng)論 25 709
  • 一、簡介 在泰國舉行的谷歌開發(fā)者論壇上,谷歌為我們介紹了一個(gè)名叫Glide的圖片加載庫,作者是bumptech。這...
    天天大保建閱讀 7,763評(píng)論 2 28
  • 7.1 壓縮圖片 一、基礎(chǔ)知識(shí) 1、圖片的格式 jpg:最常見的圖片格式。色彩還原度比較好,可以支持適當(dāng)壓縮后保持...
    AndroidMaster閱讀 2,705評(píng)論 0 13
  • Android緩存機(jī)制:如果沒有緩存,在大量的網(wǎng)絡(luò)請(qǐng)求從遠(yuǎn)程獲取圖片時(shí)會(huì)造成網(wǎng)絡(luò)流量的浪費(fèi),加載速度較慢,用戶體驗(yàn)...
    芒果味的你呀閱讀 4,713評(píng)論 13 22
  • 有一類人是怕秋后的 因?yàn)槌鰜砘?遲早是要還的 畢竟有人喜歡 秋后算總賬
    慕星讀者OR獨(dú)者閱讀 306評(píng)論 0 0

友情鏈接更多精彩內(nèi)容