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));



    }

}

 

 

 

你可能感兴趣的:(android)