前言
带有加载进度的Glide,看着是不是很好,这里也是给自己做个笔记,
一:原理
Glide 默认肯定是没有这个功能的,所以小伙办们就放弃吧,首先Glide 默认加载器,是HttpUrlConnection,我们要做的是改成OKHttp,通过okhttp的拦截器,获取到图片的大小,就可以实现监听下载进度
二: 实现
菜鸡一枚,就不献丑了,郭大神也得很好,可以看我上一篇Android - 图片处理之Glide4.0版本
里面放上了 大神对Glide 的全面解析,说真的,小伙伴们还是多敲敲代码,对自己好,
上面的代码就是我对着郭大神的敲得,最后会直接放上,方便COPY。。。
这就说一下如何更换成OKHttp模块,毕竟最新的是 4.4版本
@GlideModule
public class OkHttpLibraryGlideModule extends AppGlideModule {
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
//添加拦截器到Glide
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new ProgressInterceptor());
OkHttpClient okHttpClient = builder.build();
//原来的是 new OkHttpUrlLoader.Factory();
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okHttpClient));
}
//完全禁用清单解析
@Override
public boolean isManifestParsingEnabled() {
return false;
}
}
package com.allens.lib_glide.ResponseBody;
import android.support.annotation.Nullable;
import android.util.Log;
import com.allens.lib_glide.Impl.ProgressListener;
import com.allens.lib_glide.Interceptor.ProgressInterceptor;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;
/**
* 描述:
* <p>
* Created by allens on 2018/1/8.
*/
public class ProgressResponseBody extends ResponseBody {
private static final String TAG = "XGlide";
private BufferedSource bufferedSource;
private ResponseBody responseBody;
private ProgressListener listener;
public ProgressResponseBody(String url, ResponseBody responseBody) {
this.responseBody = responseBody;
listener = ProgressInterceptor.LISTENER_MAP.get(url);
}
@Nullable
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() {
return responseBody.contentLength();
}
@Override
public BufferedSource source() {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(new ProgressSource(responseBody.source()));
}
return bufferedSource;
}
private class ProgressSource extends ForwardingSource {
long totalBytesRead = 0;
int currentProgress;
ProgressSource(Source source) {
super(source);
}
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
long fullLength = responseBody.contentLength();
if (bytesRead == -1) {
totalBytesRead = fullLength;
} else {
totalBytesRead += bytesRead;
}
int progress = (int) (100f * totalBytesRead / fullLength);
Log.d(TAG, "download progress is " + progress);
if (listener != null && progress != currentProgress) {
listener.onProgress(progress);
}
if (listener != null && totalBytesRead == fullLength) {
listener = null;
}
currentProgress = progress;
return bytesRead;
}
}
}
package com.allens.lib_glide.Interceptor;
import com.allens.lib_glide.Impl.ProgressListener;
import com.allens.lib_glide.ResponseBody.ProgressResponseBody;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
/**
* 描述:
* <p>
* 拦截器
* Created by allens on 2018/1/8.
*/
public class ProgressInterceptor implements Interceptor {
public static final Map<String, ProgressListener> LISTENER_MAP = new HashMap<>();
//入注册下载监听
public static void addListener(String url, ProgressListener listener) {
LISTENER_MAP.put(url, listener);
}
//取消注册下载监听
public static void removeListener(String url) {
LISTENER_MAP.remove(url);
}
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
String url = request.url().toString();
ResponseBody body = response.body();
Response newResponse = response.newBuilder().body(new ProgressResponseBody(url, body)).build();
return newResponse;
}
}
package com.allens.lib_glide.Impl;
/**
* 描述:
* <p>
* 进度的的监听
* Created by allens on 2018/1/8.
*/
public interface ProgressListener {
void onProgress(int progress);
}
最后是使用
final ImageView img = findViewById(R.id.img);
final RoundProgressBar bar = findViewById(R.id.roundProgressBar01_id);//自定义View
bar.setVisibility(View.VISIBLE);
ProgressInterceptor.addListener(url, new ProgressListener() {
@Override
public void onProgress(int progress) {
bar.setProgress(progress);
}
});
RequestOptions options = new RequestOptions()
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE);
// .transforms(new CircleTransform(mContext,2, Color.DKGRAY))
// .transforms(new BlackWhiteTransformation());
// .transforms(new BlurTransformation(mContext, 25),new CircleTransform(mContext,2, Color.DKGRAY)) // (0 < r <= 25)
// .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
Glide.with(this)
.load(url)
.apply(options)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
ProgressInterceptor.removeListener(url);
bar.setVisibility(View.GONE);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
ProgressInterceptor.removeListener(url);
bar.setVisibility(View.GONE);
return false;
}
})
.into(img);