使用rxjava实现图片三级缓存。
我们都知道现在有好多的实现图片加载的框架,包括谷歌,Facebook出的一些很好的开源框架,使得我们的使用很方便而不去关心他的实现。但是这样会有一个问题,我们只是知道怎么用,但是,不知道他怎么实现遇到问题也很难解决,所以,自己实现一个简易的图片加载小的工具。

首先看他的使用

imagerLoader = new ImagerLoader();
可以设置缓存,可以实现缓存,可以删除缓存,
imagerLoader.setCatch(new LruCacth());//设置内存缓存默认没有缓存
imagerLoader.setCatch(new DirCatch());//设置sd卡缓存
imagerLoader.setHttpClient(true);//使用httpurlconnection做网络访问
imagerLoader.setCatch(new ImagerCatch() {//自定义缓存
@Override
public void PutImagerBitmap(String url, Bitmap bitmap) {
}
@Override
public Bitmap GetImagerBitmap(String url) {
return null;
}
@Override
public void ReMoveCatch() { }
});

完成配置后使用

imagerLoader.DisPlayBitmap(“http://pic41.nipic.com/20140509/4746986_145156378323_2.jpg“,mImageView);

下来看一下代码

首先是imager loader的实现

public class ImagerLoader {
private Bitmap bitmap;
private ImagerCatch mCatch;
private boolean flagHttp = true;

public void setCatch(ImagerCatch mCatch){
this.mCatch = mCatch;
}

public ImagerCatch getCatch(){
return mCatch;
}

/**
* 设置使用什么做图片加载
* 默认为原声
* @param falg
*/
public void setHttpClient(boolean falg){
flagHttp = falg;
}

public void DisPlayBitmap(final String imagerUrl , final ImageView imageView){
if (mCatch != null)
bitmap = mCatch.GetImagerBitmap(imagerUrl);
if (bitmap != null)
imageView.setImageBitmap(bitmap);
else {
Observable observable = Observable.create(new Observable.OnSubscribe() {
Bitmap bitMap;
@Override
public void call(Subscriber ? super Bitmap> subscriber) {
if (flagHttp)
bitMap = downLoadBitmap(imagerUrl);
else
bitMap = downLoadOkHttpBitmap(imagerUrl);
subscriber.onNext(bitMap);
subscriber.onCompleted();
}
});
observable.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e){
}
@Override
public void onNext(Bitmap bitmaps) {
bitmap = bitmaps;
if (bitmap != null)
imageView.setImageBitmap(bitmap);
if (mCatch != null)
mCatch.PutImagerBitmap(imagerUrl, bitmap);
}
});
}
}
private Bitmap downLoadBitmap(String imagerUrl) {
Bitmap bitmap = null;
try {
URL url = new URL(imagerUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
bitmap = BitmapFactory.decodeStream(connection.getInputStream());
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
Bitmap Mbitmap = null;
OkHttpClient mOkHttpClient;

private Bitmap downLoadOkHttpBitmap(String url) {

mOkHttpClient = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Mbitmap = BitmapFactory.decodeStream(response.body().byteStream());
}
});
return Mbitmap;
}

public void ReMoveCache() {
if (mCatch != null)
mCatch.ReMoveCatch();
}
}

缓存的定义和实现

缓存是通过基类来传递实现
public interface ImagerCatch {
void PutImagerBitmap(String url , Bitmap bitmap);
Bitmap GetImagerBitmap(String url);
void ReMoveCatch();
}

缓存实现类

内存缓存

public class LruCacth implements ImagerCatch{
LruCache String,Bitmap> mImageCacth;
LruCacth(){
initImagerCache();
}
private void initImagerCache() {
//计算可用的最大内存
long l = Runtime.getRuntime().maxMemory() / 1024;
//取八分之一作为内存缓存
mImageCacth = new LruCache String, Bitmap>((int) (l/8)){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight()/1024;
}
};
}
@Override
public void PutImagerBitmap(String url, Bitmap bitmap) {
mImageCacth.put(url,bitmap);
}
@Override
public Bitmap GetImagerBitmap(String url) {
return mImageCacth.get(url);
}
@Override
public void ReMoveCatch() {
mImageCacth.evictAll();
}
}

磁盘缓存

public class DirCatch implements ImagerCatch {
private String dir;
File sdDir = null;
DirCatch(){
initDirCatch();
}

private void initDirCatch() {
boolean sdCardExist = Environment.getExternalStorageState()
.equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在
if (sdCardExist)
{
sdDir = Environment.getExternalStorageDirectory();//获取跟目录
dir = sdDir.toString();
}
}
@Override
public void PutImagerBitmap(String url, Bitmap bitmap) {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(dir + “/”+ url);
bitmap.compress(Bitmap.CompressFormat.PNG ,100 ,fileOutputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fileOutputStream!=null){
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public Bitmap GetImagerBitmap(String url) {
return BitmapFactory.decodeFile(dir + “/”+ url);
}
@Override
public void ReMoveCatch() {
sdDir.delete();
}
}

使用双缓存

public class DubleCatch implements ImagerCatch {

private final DirCatch dirCatch;
private final LruCacth lruCacth;

DubleCatch (){
dirCatch = new DirCatch();
lruCacth = new LruCacth();
}
@Override
public void PutImagerBitmap(String url, Bitmap bitmap) {
dirCatch.PutImagerBitmap(url, bitmap);
lruCacth.PutImagerBitmap(url ,bitmap);
}

@Override
public Bitmap GetImagerBitmap(String url) {
Bitmap bitmap = null;
bitmap = lruCacth.GetImagerBitmap(url);
if (bitmap== null){
bitmap = dirCatch.GetImagerBitmap(url);
}
return bitmap;
}

@Override
public void ReMoveCatch() {
dirCatch.ReMoveCatch();
lruCacth.ReMoveCatch();
}
}

总的来说,只是提供一个思路给大家,大家可以根据自己的需求去自定义使用什么网络去加载图片访问,个人觉得就访问个图片系统的httpURLconnection就可以了,而且不用倒入第三方库,关于缓存的实现可以自己实现。

欢迎大家批评指正一起来完善。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐