android listview异步加载图片类 (优化)

原创 2013年12月06日 10:40:14
/**
 *
 * <异步加载图片 缓存的实现>
 * <功能详细描述>
 *
 * @author  cyf
 * @version  [版本号, 2013-11-18]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class AsyncImageLoader
{
    /**
     * 图片缓存
     */
    private HashMap<String, SoftReference<Bitmap>> imageCache;
   
    /**
     * 正在执行下载的url
     */
    private List<String> isDowningUrl;
   
    private Context context;
   
    public AsyncImageLoader(Context context)
    {
        this.context = context;
        imageCache = new HashMap<String, SoftReference<Bitmap>>();
        isDowningUrl = new ArrayList<String>();
    }
   
   /**
    *
    * <先读取缓存中的图片,没有在从本地读,本地没有再去网络下载>
    * <功能详细描述>
    * @param imageUrl
    * @param imageCallback
    * @param zoomForBitmap
    * @return
    * @see [类、类#方法、类#成员]
    */
    public Bitmap loadDrawable(final String imageUrl, final ImageCallback imageCallback, final BitmapSize bitmapSize)
    {
        if (imageUrl != null && imageUrl.length() > 0)
        {
            //先在缓存中查找图片
            if (imageCache.containsKey(imageUrl))
            {
                SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
                Bitmap drawable = softReference.get();
                if (drawable != null)
                {
                    return drawable;
                }
            }
            final Handler handler = new Handler()
            {
                public void handleMessage(Message message)
                {
                    imageCallback.imageLoaded((Bitmap)message.obj, imageUrl);
                }
            };
            //listview上下滑动会重复加载item,重复开线程影响效率
            if (!isDowningUrl.contains(imageUrl))
            {
                new Thread()
                {
                    @Override
                    public void run()
                    {
                        isDowningUrl.add(imageUrl);
                        Bitmap drawable = getBitmap(imageUrl, context);
                        Bitmap nowBitmap = null;
                        if (drawable != null)
                        {
                            //压缩
                            nowBitmap = GeneralUtils.zoomPhoto(drawable, bitmapSize);
                        }
                        if (nowBitmap != null)
                            imageCache.put(imageUrl, new SoftReference<Bitmap>(nowBitmap));
                        isDowningUrl.remove(imageUrl);
                        Message message = handler.obtainMessage(0, nowBitmap);
                        handler.sendMessage(message);
                    }
                }.start();
            }
        }
        return null;
    }
   
    /**
     * 根据网址获得图片,优先从本地获取,本地没有则从网络下载
     *
     * @param url  图片网址
     * @param context 上下文
     * @return 图片
     */
    public static Bitmap getBitmap(String url, Context context)
    {
        String imageName = url.substring(url.lastIndexOf("/") + 1, url.length());
        File file = new File(getPath(context), imageName);
        if (file.exists())
        {
            return BitmapFactory.decodeFile(file.getPath());
        }
        return loadImageFromUrl(url, file, context);
    }
   
    /**
     * 获取图片的存储目录,在有sd卡的情况下为 “/sdcard/本应用包名”
     * 没有sd的情况下为“/data/data/本应用包名/cach/images/”
     *
     * @param context 上下文
     * @return 本地图片存储目录
     */
    private static String getPath(Context context)
    {
        String path = null;
        boolean hasSDCard = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        String packageName = context.getPackageName() + "/CT/";
        if (hasSDCard)
        {
            path = Environment.getExternalStorageDirectory().getPath() + "/CT/";
        }
        else
        {
            path = "/data/data/" + packageName;
        }
        File file = new File(path);
        if (!file.exists())
        {
            file.mkdirs();
        }
        return file.getPath();
    }
   
    /**
     *
     * <根据URL下载图片,并保存到本地>
     * <功能详细描述>
     * @param imageURL
     * @param context
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static Bitmap loadImageFromUrl(String imageURL, File file, Context context)
    {
        Bitmap bitmap = null;
        try
        {
            URL url = new URL(imageURL);
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            con.setDoInput(true);
            con.connect();
            if (con.getResponseCode() == 200)
            {
                InputStream inputStream = con.getInputStream();
                ByteArrayOutputStream OutputStream = new ByteArrayOutputStream();
                FileOutputStream out = new FileOutputStream(file.getPath());
                byte buf[] = new byte[1024 * 20];
                int len = 0;
                while ((len = inputStream.read(buf)) != -1)
                {
                    OutputStream.write(buf, 0, len);
                }
                OutputStream.flush();
                OutputStream.close();
                inputStream.close();
                out.write(OutputStream.toByteArray());
                out.close();
                bitmap = BitmapFactory.decodeFile(file.getPath());
            }
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return bitmap;
    }
   
    // 回调接口
    public interface ImageCallback
    {
        public void imageLoaded(Bitmap bitmap, String imagePath);
    }
   
    /**
     *
     * <释放缓存>
     * <功能详细描述>
     * @see [类、类#方法、类#成员]
     */
    public void recycleMemory()
    {
        Iterator iter = imageCache.keySet().iterator();
        while (iter.hasNext())
        {
            Object key = iter.next();
            SoftReference<Bitmap> softReference = (SoftReference<Bitmap>)imageCache.get(key);
            Bitmap bitmap = softReference.get();
            if (bitmap != null && !bitmap.isRecycled())
            {
                bitmap.recycle();
            }
        }
        imageCache.clear();
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

android bitmap图片压缩,打时间水印。

public class BitmapUtil {     /**      * 图片大于300k则压缩。      */     private static final int imageMaxS...

RecyclerView详细介绍----基础使用(一)

1. 前言RecyclerView 是Android L版本中新增加的,相信很多人都听说他可以完美代替Listview,Gridview。那他到底比Listview,Gridview强大在哪里呢,今天...

Android ListView优化 异步加载图片

  • 2015年07月20日 09:59
  • 5.19MB
  • 下载

又优化了一下Android ListView 异步加载图片(续)

之前发表过一篇文章: 又优化了一下 Android ListView 异步加载图片  大家反应还行,不过普遍爆出new Thread太多会导致性能和资源浪费的问题,我想了一下的确如此,有人说用A...

Android listview异步加载图片(线程池,内存缓存,SD卡缓存)优化显示

listview异步加载图片,主要运用了异步加载图片,内存缓存图片,线程池控制下载图片技术   public class AsyncBitmapLoader { /** * 内存图片软引用缓...

又优化了一下 Android ListView 异步加载图片

写这篇文章并不是教大家怎么样用listview异步加载图片,因为这样的文章在网上已经有很多了,比如这位仁兄写的就很好: http://www.iteye.com/topic/685986 ...

Android进阶:ListView性能优化异步加载图片 使滑动效果流畅

ListView 是一种可以显示一系列项目并能进行滚动显示的 View,每一行的Item可能包含复杂的结构,可能会从网络上获取icon等的一些图标信息,就现在的网络速度要想保持ListView运行的很...

[Android实例]Listview异步加载图片之优化篇(有图有码有解释)

(国内最大Android开发论坛推荐:http://www.eoeandroid.com/) 在APP应用中,listview的异步加载图片方式能够带来很好的用户体验,同时也是考量程序性能的一个重要指...

Android ListView性能优化,异步加载图片

ListView性能优化+异步加载图片 一、绪论 相信大家在Android开发中肯定会经常用到ListView吧,那么怎么优化ListView呢?尤其是每个item里面中还有图片需要加载,数据源比较多...
  • lyhhj
  • lyhhj
  • 2015年09月02日 23:32
  • 2675
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android listview异步加载图片类 (优化)
举报原因:
原因补充:

(最多只允许输入30个字)