android实现异步加载图片类

其中牵涉到的关键知识点

1,回调机制,不过回调接口的实现方式有多种多样,可以是一个类继承该接口,也可以是作为一个方法参数;

可以参照自己的这篇博客:

http://www.cnblogs.com/bobodeboke/archive/2013/04/24/3040662.html

2,hashmap联通softReference实现缓存机制。

3,注意这种回调的处理,首先图片是用的默认图片(这里是应用图标进行占位),当回调接口调用时候,替换为网络获得的图片。

详见代码:

package com.bobo.myimageloader.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.HashMap;

import android.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;

//异步加载工具类
public class AsycImageLoader {

    private Context mContext;
    // 用来缓存图片信息

    private HashMap<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();
    private Bitmap defbitmap;
    private String LOG_TAG = "AsycImageLoader";

    // 异步加载图片工具类,如果异步加载不成功就返回图标文件
    public AsycImageLoader(Context context) {
        this.mContext = context;
        // 默认的图片
        this.defbitmap = BitmapFactory.decodeResource(mContext.getResources(),
                com.bobo.myimageloader.R.drawable.ic_launcher);

    }

    /**
     * 从sd卡中异步加载图片
     * 
     * @param uri图片所在的文件路径
     * @param imageView显示图片的imageview
     * @param imageCallBack图片的回调接口
     * @return
     */
    private Bitmap loadBitmapFormSD(final String uri,
            final ImageView imageView, final ImageCallBack imageCallBack,
            final int optsize) {
        if (this.imageCache.containsKey(uri)) {
            SoftReference<Bitmap> softReference = this.imageCache.get(uri);
            Bitmap bitmap = softReference.get();
            if (bitmap != null) {
                return bitmap;
            }
        }
        final Handler handler = new Handler() {
            public void handleMessage(Message msg) {
                // 调用回调接口
                imageCallBack.imageLoaded((Bitmap) msg.obj, imageView);
            }
        };
        // 从文件路径总加载相对费时,因此开启线程进行操作
        new Thread() {
            public void run() {
                Bitmap bitmap = null;
                if ((new File(uri)).isFile()) {
                    // 说明对应路径有错
                    bitmap = BitmapFactory.decodeResource(
                            mContext.getResources(),
                            com.bobo.myimageloader.R.drawable.ic_launcher);
                }
                bitmap = getBitmapFromFile(uri, optsize);
                imageCache.put(uri, new SoftReference<Bitmap>(bitmap));
                /*
                 * Message msg=new Message(); msg.obj=bitmap;
                 */
                Message msg = handler.obtainMessage(0, bitmap);
                handler.sendMessage(msg);

            }
        }.start();
        return defbitmap;
    }

    /**
     * 从文件路径中获取文件可以设定opt参数
     * 
     * @param uri
     * @return
     */

    private Bitmap getBitmapFromFile(String uri, int opsize) {
        System.out.println("取出文件的路径是:"+uri);
        BitmapFactory.Options opt = new BitmapFactory.Options();
        // 设置缩放比例,如果设置为2,则图像会是原来的1/2
        opt.inSampleSize = opsize;
        opt.inPurgeable = true;
        Bitmap bitmap = BitmapFactory.decodeFile(uri, opt);
        if (bitmap != null) {
            return bitmap;
        }
        return this.defbitmap;
    }

    private Bitmap loadBitmapFromNet(final String uri,
            final ImageView imageView, final ImageCallBack imageCallBack,
            final int optsize) {
        if (imageCache.containsKey(uri)) {
            SoftReference<Bitmap> soft = imageCache.get(uri);
            Bitmap bitmap = soft.get();
            return bitmap;
        }

        // 如果没有需要开启线程进行下载
        final Handler handler = new Handler() {
            public void handleMessage(Message msg) {
                imageCallBack.imageLoaded((Bitmap) msg.obj, imageView);
            }
        };
        new Thread() {
            public void run() {
                Bitmap bitmap = null;

                try {
                    String savePath = getFileSavePath();
                    downLoadImageFormNet(uri, savePath);

                    bitmap = getBitmapFromFile(savePath, optsize);
                    imageCache.put(uri, new SoftReference<Bitmap>(bitmap));
                    Message msg=handler.obtainMessage(0, bitmap);
                    handler.sendMessage(msg);
                } catch (Exception e) {
                    Log.d(LOG_TAG, "从网络下载保存bitmap失败");
                    bitmap = BitmapFactory.decodeResource(
                            mContext.getResources(),
                            com.bobo.myimageloader.R.drawable.ic_launcher);

                }

            }
        }.start();

        return defbitmap;
    }

    // 从网络下载并且保存图片资源
    protected void downLoadImageFormNet(String uri, String savePath) {
        // 如果下载的就是不做处理的原始文件
        Bitmap bitmap = null;
        try {

            bitmap = BitmapFactory.decodeStream((new URL(uri)).openStream());
            FileOutputStream fos = new FileOutputStream(savePath);
            bitmap.compress(CompressFormat.JPEG, 100, fos);
        } catch (Exception e) {
            Log.d(LOG_TAG, "网络下载或保存文件失败");
            e.printStackTrace();
        }

    }

    protected String getFileSavePath() {
        String fileName = new SimpleDateFormat("yyyyMMdd hhmmss")
                .format(new Date());
        String path = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
                + File.separator
                + "myAsycImage"
                + File.separator
                + "IMG_"
                + fileName + ".jpg";
        File file = new File(path);
        if (!file.getParentFile().exists()) {
            if (!file.getParentFile().mkdirs()) {
                return null;
            }
        }
        try {
            file.createNewFile();
            Log.d(LOG_TAG, file.getAbsolutePath());
            return file.getAbsolutePath();
        } catch (IOException e) {

            e.printStackTrace();
            return null;
        }

    }

    // 定义一个回调接口
    private interface ImageCallBack {
        void imageLoaded(Bitmap bitmap, ImageView imageView);
    }

    /**
     * 外部调用接口
     * 
     * @param uri
     *            网路上的图片地址
     * @param imageView
     *            需要显示图片的image控件
     * @param callback
     */
    public void setAsycImageFromNet(String uri, ImageView imageView) {
        if (uri == null) {
            return;
        }

        imageView.setImageBitmap(loadBitmapFromNet(uri, imageView,
                new ImageCallBack() {

                    @Override
                    public void imageLoaded(Bitmap bitmap, ImageView imageView) {
                        imageView.setImageBitmap(bitmap);
                    }

                }, 2));
    }

    public void setAsycImageFromSD(String path, ImageView imageView) {
        if (path == null) {
            return;
        }
        // 感觉是先用默认图片进行占位,等获取到图片再使用网路上的图片
        imageView.setImageBitmap(loadBitmapFormSD(path, imageView,
                new ImageCallBack() {

                    @Override
                    public void imageLoaded(Bitmap bitmap, ImageView imageView) {
                        imageView.setImageBitmap(bitmap);
                    }

                }, 2));

    }

    // 因为本地加载图片的时间开销小,因此可以不进行异步加载
    public void setImageFromSD(String path, ImageView imageView) {
        imageView.setImageBitmap(BitmapFactory.decodeFile(path));

    }
}

 

 

 

posted @ 2013-06-24 16:58  bobo的学习笔记  阅读(346)  评论(0编辑  收藏  举报