關(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后可用此虑。
that's all-----------------------------------------------------