博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ImageLoader的优化写法
阅读量:7231 次
发布时间:2019-06-29

本文共 5380 字,大约阅读时间需要 17 分钟。

ImageLoader是android开发中常用到的图片缓存技术。本文通过阅读《Android源码设计模式解析与实战》后,了解到一个程序的健壮性,可拓展性是十分重要的。源码设计均来自于《Android源码设计模式解析与实战》: 1.首先定义ImageCache接口,实现图片的缓存和提取两种方法。

public interface ImageCache {    void put(String url,Bitmap bitmap);    Bitmap get(String url);}复制代码

2.分别实现内存缓存(MemoryCache),sd卡缓存(DiskCache)和双缓存(DoubleCache)策略,其均实现ImageCache接口。

public class MemoryCache implements ImageCache {    LruCache
mMemoryCache; public MemoryCache(){ initMemoryCache(); } private void initMemoryCache() { //计算可使用的最大内存 final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); //取四分之一的可用内存作为缓存 final int CacheSize = maxMemory / 4; mMemoryCache = new LruCache
(CacheSize) { @Override protected int sizeOf(String key, Bitmap value) { //图片的宽高之积/1024(存储的应该是图片的大小) return value.getRowBytes() * value.getHeight() / 1024; } }; } @Override public void put(String url, Bitmap bitmap) { mMemoryCache.put(url,bitmap); } @Override public Bitmap get(String url) { return mMemoryCache.get(url); }}复制代码
public class DiskCache implements ImageCache{    static String cacheDir = "sdcard/cache/";    @Override    public void put(String url, Bitmap bitmap) {        FileOutputStream fileOutputStream = null;        try {            fileOutputStream = new FileOutputStream(cacheDir + 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 get(String url) {        return BitmapFactory.decodeFile(cacheDir + url);    }}复制代码
public class DoubleCache implements ImageCache{    ImageCache mMemmoryCache = new MemoryCache();    ImageCache mDiskCache = new DiskCache();    @Override    public void put(String url, Bitmap bitmap) {        mMemmoryCache.put(url,bitmap);        mDiskCache.put(url,bitmap);    }    @Override    public Bitmap get(String url) {        Bitmap bitmap = mMemmoryCache.get(url);        if(bitmap == null){            bitmap = mDiskCache.get(url);        }        return bitmap;    }}复制代码

3.创建ImageLoader类

public class ImageLoader {    //内存缓存    ImageCache mImageCache = new MemoryCache();    //线程池,线程数量为CPU的数量    ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());    public void setImageCache(ImageCache cache){        mImageCache = cache;    }    public void displayImage(final String url, final ImageView imageView) {        //判断该url的图片是否在缓存中存在,存在则直接显示在imageview上        Bitmap bitmap = mImageCache.get(url);        if(bitmap != null){            imageView.setImageBitmap(bitmap);            return;        }        //图片没缓存,在线程池中下载        submitLoadRequest(url,imageView);    }    private void submitLoadRequest(final String url, final ImageView imageView) {        imageView.setTag(url);        mExecutorService.submit(new Runnable() {            @Override            public void run() {                Bitmap bitmap = downloadImage(url);                if (bitmap == null) {                    return;                }                if (imageView.getTag().equals(url)) {                    imageView.setImageBitmap(bitmap);                }                mImageCache.put(url, bitmap);            }        });    }    private Bitmap downloadImage(String imageurl) {        Bitmap bitmap = null;        try {            URL url = new URL(imageurl);            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            bitmap = BitmapFactory.decodeStream(conn.getInputStream());            conn.disconnect();        } catch (IOException e) {            e.printStackTrace();        }        return bitmap;    }复制代码

在ImageLoader类中添加setImageCache()方法,用户可以通过此方法决定缓存的方式为以上3种的哪一种。

4.在Activity上进行声明,使用。

public class MainActivity extends AppCompatActivity {    private ImageView imageView;    private ImageLoader imageLoader;    private String url = "http://bmob-cdn-11151.b0.upaiyun.com/2017/06/04/3cdfbcc8400de13c8027b5513d469637.jpg";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView() {        imageView = (ImageView)findViewById(R.id.imageView);        imageLoader = new ImageLoader();        //使用内存缓存        imageLoader.setImageCache(new MemoryCache());        //使用sd卡缓存        imageLoader.setImageCache(new DiskCache());        //使用doubleCache缓存        imageLoader.setImageCache(new DoubleCache());        //使用自定义的方法缓存        imageLoader.setImageCache(new ImageCache() {            @Override            public void put(String url, Bitmap bitmap) {            }            @Override            public Bitmap get(String url) {                return null;            }        });        imageLoader.displayImage(url,imageView);    }}复制代码

本方法高度内聚,低耦合,在使用过程中,分别使用3中不同的缓存策略,使复杂的代码进行分离,在出现问题时,便于方便的修改,不会影响到其他的代码功能,实现抽象接口的方法还允许开发者使用自定义的缓存策略,可拓展性高。

理解这种程序设计时十分必要的,在以后的开发中要时刻考虑自己程序的健壮性,可拓展性,高内聚低耦合。

转载地址:http://kzcfm.baihongyu.com/

你可能感兴趣的文章
一 flask介绍 三
查看>>
C++拓展笔记1-3:浅析C++关键字const的几个作用
查看>>
Django 分页组件替换自定义分页
查看>>
Pdf Convert Image 的解决方案
查看>>
[笔记]使用clearfix清除浮动
查看>>
数据强转
查看>>
Latest crack software ftp download
查看>>
OpenStack 的防火墙规则流程
查看>>
Overloading Django Form Fields
查看>>
03.MyBatis的核心配置文件SqlMapConfig.xml
查看>>
python学习笔记(9)-python编程风格
查看>>
Apache HTTP Server搭建虚拟主机
查看>>
(译).NET4.X 并行任务中Task.Start()的FAQ
查看>>
git log显示
查看>>
java中相同名字不同返回类型的方法
查看>>
Rails NameError uninitialized constant class solution
查看>>
Android 获取SDCard中某个目录下图片
查看>>
设置cookies第二天0点过期
查看>>
【转载】NIO客户端序列图
查看>>
poj_2709 贪心算法
查看>>