Omooo
2017-12-19 13:41
没效果的意思是图片没有加载进去,一片空白。
代码:
SimpleImageLoader.java:
package top.omooo.cachedemo.utils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.util.LruCache;
import android.widget.ImageView;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* Created by SSC on 2017/12/6.
* 加载网络图片,并缓存图片到本地和内存
*/
public class SimpleImageLoader {
private static SimpleImageLoader mLoader;
private LruCache<String, Bitmap> mLruCache;
private static final String TAG = "SimpleImageLoader";
public static SimpleImageLoader getInstance() {
if (mLoader == null) {
synchronized (SimpleImageLoader.class) {
if (mLoader == null) {
mLoader = new SimpleImageLoader();
}
}
}
return mLoader;
}
/**
* 用来初始化缓存对象
*/
private SimpleImageLoader() {
int maxSize = (int) (Runtime.getRuntime().maxMemory() / 8);
mLruCache = new LruCache<String, Bitmap>(maxSize){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
};
}
/**
* 用来加载网络图片
* @param view
* @param url
*/
public void displayImage(ImageView view, String url) {
Bitmap bitmap = getBitmapFromCache(url);
if (bitmap != null) {
Log.i(TAG, "displayImage bitmap!=null");
view.setImageBitmap(bitmap);
} else {
Log.i(TAG, "displayImage bitmap==null");
downloadImage(view,url);
view.setImageBitmap(getBitmapFromCache(url));
}
}
/**
* 从缓存中读取图片
* @param url
* @return
*/
private Bitmap getBitmapFromCache(String url) {
Log.i(TAG, "getBitmapFromCache");
return mLruCache.get(url);
}
/**
* 将下载下来的图片保存到缓存中
* @param bitmap
* @param url
*/
private void putBitmapToCache(Bitmap bitmap, String url) {
if (bitmap != null) {
Log.i(TAG, "putBitmapToCache");
mLruCache.put(url, bitmap);
}
}
/**
* 下载图片,并添加到缓存中
* @param imageView
* @param url
*/
private void downloadImage(final ImageView imageView, final String url) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG, "onFailure");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(TAG, "onResponse");
Bitmap bitmap = BitmapFactory.decodeStream(response.body().byteStream());
if (bitmap != null) {
putBitmapToCache(bitmap, url);
Log.i(TAG, "bitmap不为空");
} else {
Log.i(TAG, "bitmap为空");
}
}
});
}
}
然后在MainActivity里面调用:
SimpleImageLoader.getInstance().displayImage(mImageView, url);
运行没效果,呜呜呜
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(TAG, "onResponse");
Bitmap bitmap = BitmapFactory.decodeStream(response.body().byteStream());
if (bitmap != null) {
putBitmapToCache(bitmap, url);
Log.i(TAG, "bitmap不为空");
} else {
Log.i(TAG, "bitmap为空");
}
}
});
上面这个方法的执行时异步的
然而在首次加载图片的时候bitmap == null 会调用系统的OKHTTP去下载图片(这里需要你断点一下是不是真的下载好了),假设下载成功了。但是在下载成功之前代码已经执行到了 view.setImageBitmap(getBitmapFromCache(url)); 这时候图片还没有下载好
/**
* 用来加载网络图片
* @param view
* @param url
*/
public void displayImage(ImageView view, String url) {
Bitmap bitmap = getBitmapFromCache(url);
if (bitmap != null) {
Log.i(TAG, "displayImage bitmap!=null");
view.setImageBitmap(bitmap);
} else {
Log.i(TAG, "displayImage bitmap==null");
downloadImage(view,url);
view.setImageBitmap(getBitmapFromCache(url));
}
}
正确的解决是当图片下载完成了,直接加载给view
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(TAG, "onResponse");
Bitmap bitmap = BitmapFactory.decodeStream(response.body().byteStream());
if (bitmap != null) {
putBitmapToCache(bitmap, url);
displayImage(ImageView view, String url);
Log.i(TAG, "bitmap不为空");
} else {
Log.i(TAG, "bitmap为空");
}
}
});
这样就可以了
视频里面有遗漏,下载完成还需要在set一下,下载过程是异步的,所以在download后面直接set是不行的。还有一点,okhttp的onResponse是在非UI线程回调,不要直接操作ui
Bitmap高效缓存
6824 学习 · 6 问题
相似问题
回答 2
回答 1