zhu的工作日记:图片三级缓存的工具类(android)

工作点滴,汇聚成雨
(图片三级缓存的工具类)

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

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.support.v4.util.LruCache;
import android.widget.ImageView;

/**
 * 
 * @创建描述:图片三级缓存的工具类
 * 
 */
public class ImageUtils
{

    private static LruCache<String, Bitmap> mCaches;
    private static Handler                  mHandler;
    private static ExecutorService          mPool;

    private Context                         mContext;

    private Map<ImageView, String>          mTags   = new LinkedHashMap<ImageView, String>();

    public ImageUtils(Context context) {
        this.mContext = context;
        if (mCaches == null)
        {
            // 申请的内存空间
            int maxSize = (int) (Runtime.getRuntime().freeMemory() / 4);
            mCaches = new LruCache<String, Bitmap>(maxSize) {
                @Override
                protected int sizeOf(String key, Bitmap value)
                {
                    // 判断添加进入的value的占用内存的大小
                    return value.getRowBytes() * value.getHeight();
                }
            };
        }

        if (mHandler == null)
        {
            mHandler = new Handler();
        }

        if (mPool == null)
        {
            mPool = Executors.newFixedThreadPool(3);
        }
    }

    /**
     * 给imageView加载url对应的图片
     * 
     * @param iv
     * @param url
     */
    public void display(ImageView iv, String url)
    {
        // 1. 从内存中获取
        Bitmap bitmap = mCaches.get(url);
        if (bitmap != null)
        {
            // 内存中有,显示
            iv.setImageBitmap(bitmap);
            return;
        }

        // 2. 从本地去获取
        bitmap = loadFromLocal(url);
        if (bitmap != null)
        {
            // 本地中有,显示
            iv.setImageBitmap(bitmap);
            return;
        }

        // 3. 从网络中获取
        loadFromNet(iv, url);
    }

    private void loadFromNet(ImageView iv, String url)
    {

        mTags.put(iv, url);// url是imageView最新的地址

        // 耗时操作

        // 线程池管理
        mPool.execute(new LoadImageTask(iv, url));
    }

    private class LoadImageTask implements Runnable
    {
        private String      url;
        private ImageView   iv;

        public LoadImageTask(ImageView iv, String url) {
            this.iv = iv;
            this.url = url;
        }

        @Override
        public void run()
        {
            try
            {
                HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();

                conn.setConnectTimeout(5000);// 连接服务器超时时间
                conn.setReadTimeout(5000);// 读取超时时间

                conn.connect();// 连接服务器

                // 获取流
                InputStream is = conn.getInputStream();

                // 将流变为bitmap
                Bitmap bitmap = BitmapFactory.decodeStream(is);

                // 存储到本地
                save2Local(bitmap, url);

                // 存储到内存
                mCaches.put(url, bitmap);

                String recentlyUrl = mTags.get(iv);
                if (url.equals(recentlyUrl))
                {
                    // 显示到UI
                    mHandler.post(new Runnable() {

                        @Override
                        public void run()
                        {
                            display(iv, url);
                        }
                    });
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    private Bitmap loadFromLocal(String url)
    {
        // 本地需要有存储的路径
        File file = getCacheFile(url);

        if (file.exists())
        {
            // 本地有
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());

            // 存储到内存
            mCaches.put(url, bitmap);

            return bitmap;
        }

        return null;
    }

    public void save2Local(Bitmap bitmap, String url) throws FileNotFoundException
    {
        File file = getCacheFile(url);
        FileOutputStream stream = new FileOutputStream(file);
        bitmap.compress(CompressFormat.JPEG, 100, stream);
    }

    private File getCacheFile(String url)
    {
        String name = MD5Utils.encode(url);

        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state))
        {
            // sd存在的
            File dir = new File(Environment.getExternalStorageDirectory(), "/Android/data/" + mContext.getPackageName() + "/icon");
            if (!dir.exists())
            {
                dir.mkdirs();
            }

            return new File(dir, name);
        }
        else
        {
            File dir = new File(mContext.getCacheDir(), "/icon");
            if (!dir.exists())
            {
                dir.mkdirs();
            }

            return new File(dir, name);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值