關(guān)于安卓glide加載顯示進(jìn)度

關(guān)于glide加載圖片時(shí)涝婉,如何顯示進(jìn)度岩瘦?
首先,glide是沒有接口可以進(jìn)行進(jìn)度監(jiān)聽的扫尺,所以要進(jìn)行進(jìn)一步的代碼編寫。

相關(guān)文章 glide加載https報(bào)錯(cuò)

代碼地址在文末

環(huán)境

win10
glide4+
androidstudio4.2.2

思考:

(1)如何獲取glide請(qǐng)求時(shí)的數(shù)據(jù)
(2)請(qǐng)求數(shù)據(jù)如何計(jì)算

帶著這些問題炊汤,開始發(fā)車:

生成GlideApp對(duì)象

首先正驻,需要通過配置,生成GlideApp對(duì)象婿崭。
(一)gradle配置:

    implementation "com.github.bumptech.glide:okhttp3-integration:4.9.0"
    implementation 'com.github.bumptech.glide:glide:4.9.0'
    kapt 'com.github.bumptech.glide:compiler:4.9.0'

(二)GlideModule文件的編寫

@GlideModule
public final class GlideCache extends AppGlideModule {
    
}

(三)manifest文件的配置
在application標(biāo)簽內(nèi),配置以下代碼肴颊,注意包名路徑與實(shí)際項(xiàng)目中對(duì)應(yīng)氓栈。

        <meta-data
            android:name="com.example.ktdemo.glide.GlideCache"
            android:value="AppGlideModule" />

然后點(diǎn)擊編譯按鈕,即可生成GlideApp對(duì)象了婿着。后續(xù)操作都是在GlideApp對(duì)象中執(zhí)行授瘦。

進(jìn)度回調(diào)實(shí)現(xiàn)

要進(jìn)行進(jìn)度回調(diào)醋界,首先明確一個(gè),就是替換原來glide請(qǐng)求過程中的請(qǐng)求對(duì)象提完,glide請(qǐng)求底層是基于okhttp實(shí)現(xiàn)的形纺,可以直接從這方面入手。

(一)替換網(wǎng)絡(luò)返回時(shí)的對(duì)象

從攔截器入手徒欣,添加一個(gè)攔截器逐样,并且捕獲到ResponseBody 對(duì)象后進(jìn)行處理。
重寫GlideModule中的registerComponents方法打肝,替換請(qǐng)求對(duì)象脂新。

public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        OkHttpClient.Builder builder = GlideUnsafeOkHttpClient.getUnsafeOkHttpClient();
        builder.addInterceptor(new GlideProgressInterceptor());
        OkHttpClient okHttpClient = builder.build();
        registry.replace(GlideUrl.class, InputStream.class, new GlideOkHttpGlideUrlLoader.Factory(okHttpClient));
    }
public class GlideProgressInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();
        Response response = chain.proceed(request);
        String url = request.url().toString();
        ResponseBody responseBody = response.body();

        Response newResponse = response.newBuilder().body(
                new GlideProgressResponseBody(url, responseBody)).build();

        return newResponse;
    }
}

最核心的代碼

public class GlideProgressResponseBody extends ResponseBody {

    private static final String TAG = "ProgressResponseBody";

    private BufferedSource mBufferedSource;
    private ResponseBody mResponseBody;
    //    private GlideProgressListener mGlideProgressListener;
    private String mUrl;

    public GlideProgressResponseBody(String url, ResponseBody responseBody) {
        mUrl = url;
        mResponseBody = responseBody;
//        mGlideProgressListener = GlideProgressInterceptor.getListenerMap().get(url);
    }

    @Nullable
    @Override
    public MediaType contentType() {
        return mResponseBody.contentType();
    }

    @Override
    public long contentLength() {
        return mResponseBody.contentLength();
    }

    @Override
    public BufferedSource source() {

        if (mBufferedSource == null) {
            mBufferedSource = Okio.buffer(new ProgressSource(mResponseBody.source()));
        }

        return mBufferedSource;
    }

    private class ProgressSource extends ForwardingSource {

        private long mTotalBytesRead;
        private int mCurrentProgress;

        public ProgressSource(Source delegate) {
            super(delegate);
        }

        @Override
        public long read(Buffer sink, long byteCount) throws IOException {

            long bytesRead = super.read(sink, byteCount);
            long fullLength = mResponseBody.contentLength();

            if (bytesRead == -1) {
                mTotalBytesRead = fullLength;
            } else {
                mTotalBytesRead += bytesRead;
            }

            int progress = (int) (100f * mTotalBytesRead / fullLength);

            Log.e(TAG, "download url is: " + mUrl + " progress is " + progress);

            GlideProgressManager.getInstance().notifyProgress(mUrl, progress, (mTotalBytesRead == fullLength));

//            if ((mGlideProgressListener != null) && (progress != mCurrentProgress)) {
//                mGlideProgressListener.onProgress(progress);
//
//            }
//
//            if ((mGlideProgressListener != null) && (mTotalBytesRead == fullLength)) {
//                mGlideProgressListener = null;
//            }

            mCurrentProgress = progress;

            return bytesRead;
        }
    }
}

上面代碼中,可以看到粗梭,我們對(duì)進(jìn)度的數(shù)據(jù)處理争便,都是基于一個(gè)繼承ResponseBody的自定義返回對(duì)象進(jìn)行的。而對(duì)外断医,僅僅是添加了一個(gè)攔截器而已滞乙。

至此,核心代碼都已經(jīng)講完了鉴嗤。

調(diào)用

下面代碼只是實(shí)例斩启,實(shí)際使用中,需要注意監(jiān)聽對(duì)象的及時(shí)釋放躬窜,避免造成內(nèi)存泄漏浇垦。

val imgUrl = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"

        GlideProgressManager.getInstance().setGlideProgressListener(object :GlideProgressListener{
            override fun onProgress(url: String?, progress: Int, isFinish: Boolean) {
                Log.d("glide", "glide url:$url progress:$progress isFinish:$isFinish")
            }
        })

        GlideApp.with(this).asBitmap().load(imgUrl).into(object : SimpleTarget<Bitmap>() {
            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                Log.d("glide", "glide onResourceReady")
            }
        })

可能遇到的坑

kapt編譯時(shí)報(bào)錯(cuò),這個(gè)時(shí)候荣挨,需要檢查gradle的版本號(hào)男韧。實(shí)測目前compileSdkVersion為31的情況下,kapt會(huì)報(bào)錯(cuò)默垄。修改為了30后可用此虑。

代碼相關(guān)文件

that's all-----------------------------------------------------

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市口锭,隨后出現(xiàn)的幾起案子朦前,更是在濱河造成了極大的恐慌,老刑警劉巖鹃操,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件韭寸,死亡現(xiàn)場離奇詭異,居然都是意外死亡荆隘,警方通過查閱死者的電腦和手機(jī)恩伺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椰拒,“玉大人晶渠,你說我怎么就攤上這事凰荚“” “怎么了番川?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵养盗,是天一觀的道長。 經(jīng)常有香客問我聂儒,道長衩婚,這世上最難降的妖魔是什么非春? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任奇昙,我火速辦了婚禮,結(jié)果婚禮上什湘,老公的妹妹穿的比我還像新娘闽撤。我一直安慰自己,他們只是感情好热幔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布蠕啄。 她就那樣靜靜地躺著歼跟,像睡著了一般哈街。 火紅的嫁衣襯著肌膚如雪她倘。 梳的紋絲不亂的頭發(fā)上硬梁,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音跃巡,去河邊找鬼个扰。 笑死递宅,一個(gè)胖子當(dāng)著我的面吹牛办龄,可吹牛的內(nèi)容都是我干的俐填。 我是一名探鬼主播盏檐,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旨别?” 一聲冷哼從身側(cè)響起汗茄,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤秸弛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后洪碳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胆屿,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年偶宫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了非迹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纯趋,死狀恐怖憎兽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吵冒,我是刑警寧澤纯命,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站痹栖,受9級(jí)特大地震影響亿汞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜揪阿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一疗我、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧南捂,春花似錦吴裤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春剖膳,著一層夾襖步出監(jiān)牢的瞬間魏颓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工吱晒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留琼开,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓枕荞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親搞动。 傳聞我的和親對(duì)象是個(gè)殘疾皇子躏精,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355