Android-自定义图片加载框架

框架结构


ImageCache类(图片缓存)
流程介绍:设置了两级缓存,将最近使用的图片保存到内存中,将网络加载过来的图片保存到本地。其中保存到内存中图片,为经过压缩的图片,而保存到本地的为网络加载的原图。

保存到内存中,用到了最近最少使用算法的缓存,构造如下:
int maxMemory  = ( intRuntime .getRuntime() .maxMemory();
int cacheMemory  = maxMemory  /  8;
mLruCache  =  new  LruCache<String, Bitmap>(cacheMemory) {
    @Override
    protected  int  sizeOf( String  keyBitmap  value) {
        //获取位图大小
        return value .getByteCount();
    }
};

ImageNetworkUtil类(网络加载类)
只包含简单的网络获取,输入输出流操作,直接跳过。下载源代码,直接查看。

ImageCenter类(图片加载中心)
流程介绍:将加载图片任务包装到一个Runnable对象中,然后将对象添加到任务队列中,等待线程池处理任务队列中的任务。其中加载图片任务,将压缩图片方法,加载图片成功回调方法,加载图片失败回调方法都委托给了IImageHandler接口(图片处理策略)处理。

线程池构造如下:
private  static  final  int  CPU_COUNT  =  Runtime .getRuntime() .availableProcessors();
private  static  final  int  DEFAULT_THREAD_COUNT  =  CPU_COUNT  +  1;
mThreadPool  =  Executors .newFixedThreadPool( DEFAULT_THREAD_COUNT);

任务创建如下:
private  Runnable createTask( final  IImageHandle imageHandle) {
    return  new  Runnable() {
        @Override
        public  void  run() {
            final  Bitmap bitmap;
            final  String url  = imageHandle .getImageUrl();
            final  String uid  = imageHandle .getUniqueId(); //压缩后图片保存在内存中的唯一Id
            String name  =  EncryptionUtil .getMd5(url);

            //保存在内存
            if (mImageCache .isExistsCache(uid)){
                bitmap  = mImageCache .getBitmapCache(uid);
            }
            //保存在本地
            else  if (mImageCache .isExistsDisk(name)){
                byte[] bytes  = mImageCache .getBitmapDisk(name);
                bitmap  = imageHandle .onPreHandle(bytes);
                mImageCache .saveBitmapCache(uid, bitmap);
            }
            //网络加载
            else{
                byte[] bytes  =  ImageNetworkUtil .loadByteArrayByUrl(url);
                mImageCache .saveBitmapDisk(name, bytes);
                bitmap  = imageHandle .onPreHandle(bytes);
                mImageCache .saveBitmapCache(uid, bitmap);
            }

            mUIHandler .post( new  Runnable() {
                @Override
                public  void  run() {
                    if (bitmap  ==  null){
                        imageHandle .onImageLoadFailed(url);
                    } else {
                        imageHandle .onImageLoadSuccess(bitmap, url);
                    }
                }
            });
        }
    };
}

添加和获取任务:
//任务栈
private  LinkedList<Runnable> mTaskQueue  =  new  LinkedList();

private  void addTask( Runnable task) {
    if (mQueueType  ==  QueueType .LIFO){
        mTaskQueue .push(task);
    } else {
        mTaskQueue .add(task);
    }

    mPoolThreadHandler .sendEmptyMessage( 0);
}

private  Runnable getTask() {
    if (mQueueType  ==  QueueType .LIFO){
        return mTaskQueue .pop();
    } else {
        return mTaskQueue .poll();
    }
}

IImageHandle接口(图片处理策略类)
单单罗列出了几个简单的接口,通过实现这些接口,来生成不同的图片处理策略。接下来,会展示一个我自己实现的图片处理策略,读者感兴趣的话,也可以写几个自己看着说的实现类。

接口结构及其功能描述如下:
public  interface  IImageHandle {

    /**
     * 获取处理后得到的图片的唯一id
     * (建议:将与图片处理有关的所有因素都结合组成一个MD5码)
     *
     * @return 唯一id
     */

    String  getUniqueId();

    /**
     * 获取图片地址
     * @return 图片地址
     */

    String  getImageUrl();

    /**
     * 处理图片
     * @param bytes 原始图片字节码
     * @return 处理后图片
     */

    Bitmap  onPreHandle( byte[]  bytes);

    /**
     * 图片加载成功回调
     * @param bitmap 最终图片
     * @param url 图片地址
     */

    void  onImageLoadSuccess( Bitmap  bitmapString  url);

    /**
     * 图片加载成功回调
     * @param url 图片地址
     */

    void  onImageLoadFailed( String  url);
}


BitmapHandle类(位图处理策略)
实现图片处理策略的所有接口,在onPreHandle方法中,通过byte[](图片字节数组)对图片进行压缩处理。在getUniqueId方法中,返回一个唯一Id。由于位图处理策略中,图片压缩处理只与ImageUrl有关,所以通过EncryptionUtil.getMd5("BitmapHandle" + mUrl)获取唯一Id。注意,此唯一Id将用在LruChache内存缓存中,因此必须唯一。
public  class  BitmapHandle  implements  IImageHandle {

    public  interface  BitmapHandleListener {
        void  onHandle( Bitmap  bitmap);
    }

    private  BitmapHandleListener mListener;
    private  String mUrl;

    public  BitmapHandle( String  urlBitmapHandleListener  listener){
        mListener  = listener;
        mUrl  = url;
    }

    @Override
    public  String  getUniqueId(){
        return  EncryptionUtil .getMd5( "BitmapHandle"  + mUrl);
    }

    @Override
    public  String  getImageUrl(){
        return mUrl;
    }

    @Override
    public  Bitmap  onPreHandle( byte[]  bytes){
        BitmapFactory . Options options  =  new  BitmapFactory. Options();

        options .inJustDecodeBounds  =  true;
        BitmapFactory .decodeByteArray(bytes,  0, bytes .length, options);

        //根据不同的图片格式,选择不同的像素格式,减小内存占用。
        if (options .outMimeType  !=  null  && options .outMimeType .equals( "image/jpeg")){
            options .inPreferredConfig  =  Bitmap . Config .RGB_565;
        } else  if (options .outMimeType  !=  null  && options .outMimeType .equals( "image/png")){
            options .inPreferredConfig  =  Bitmap . Config .ARGB_8888;
        }

        options .inJustDecodeBounds  =  false;
        Bitmap bitmap  =  BitmapFactory .decodeByteArray(bytes,  0, bytes .length, options);
        return bitmap;
    }

    @Override
    public  void  onImageLoadSuccess( Bitmap  bitmapString  url){
        if (mListener  !=  null){
            mListener .onHandle(bitmap);
        }
    }

    @Override
    public  void  onImageLoadFailed( String  url){
        if (mListener  !=  null){
            mListener .onHandle( ResourceUtil .getBitmap( R .drawable .ic_no_picture));
        }
    }
}


ImageLoader类(图片加载外观类)
在ImageLoader中,封装了以上的内部实现。以BitmapHandler为例,其封装如下:
/***********************  位图处理策略  ***********************/
public  void getBitmap( String url,  BitmapHandle . BitmapHandleListener listener) {
    mLoadCenter .submitTask( new  BitmapHandle(url, listener));
}

代码地址
项目地址: https://github.com/AbeDai/Android_Framework (绝对不会让你失望哦)

/**************************  项目介绍 *****************************/
此项目为本人知识库,里面保存了许多自己实现的控件和功能,其中包括Volley使用介绍,视图注入框架,EventBus框架,还有图片加载框架等...
查看ImageLoader使用效果方法:运行项目,点击顶部搜索框,键入“imageloader”,即可快速搜索到ImageLoader使用知识点。

如果觉得好,不要忘记动动手指,点点star!







  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值