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

/**
 *
 * <异步加载图片 缓存的实现>
 * <功能详细描述>
 *
 * @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,listview异步加载图片类)