图片缓存

首先用sp将json数据保存起来,然后将网络数据分别存储在内存、本地。

PhotosMenuDetailPager.java

PhotosMenuDetailPager extends MenuDetailBasePager {

    @ViewInject(R.id.lv_photos)
    private ListView mListView;

    @ViewInject(R.id.gv_photos)
    private GridView mGridView;

    private List<PhotoItemBean> photoItemList;

    private BitmapUtils bitmapUtils;

    private boolean isSingleColumns = true; // 当前是否是单列数据, 默认是单列

    private BitmapCacheUtils mBitmapCacheUtils; // 图片缓存工具类

    private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case NetCacheUtils.SUCCESS: // 网络缓存请求成功.
                Bitmap bm = (Bitmap) msg.obj;
                int position = msg.arg1;

                ImageView mImageView = (ImageView) mListView.findViewWithTag(position);
                if(mImageView != null) {
                    // System.out.println("当前是第" + position + "张, 图片请求成功");
                    mImageView.setImageBitmap(bm);
                }
                break;
            case NetCacheUtils.FAILED:
                Toast.makeText(mActivity, "第" + msg.arg1 + "张图片请求失败", 0).show();
                break;
            default:
                break;
            }

        }
    };

    public PhotosMenuDetailPager(Activity activity) {
        super(activity);

// bitmapUtils = new BitmapUtils(mActivity);
// bitmapUtils.configDefaultBitmapConfig(Config.ARGB_4444);


        mBitmapCacheUtils = new BitmapCacheUtils(handler);
    }

    @Override
    public View initView() {
        View view = View.inflate(mActivity, R.layout.photos, null);
        ViewUtils.inject(this, view);
        return view;
    }

    @Override
    public void initData() {
        // 先显示缓存起来的数据
        String json = CacheUtils.getString(mActivity, ConstantUtils.PHOTOS_URL, null);
        if(!TextUtils.isEmpty(json)) {
            processData(json);
        }

        // 去网络中取图片数据
        getDataFromNet();
    }

    private void getDataFromNet() {
        HttpUtils httpUtils = new HttpUtils();
        httpUtils.send(HttpMethod.GET, ConstantUtils.PHOTOS_URL, new RequestCallBack<String>() {

            @Override
            public void onSuccess(ResponseInfo<String> responseInfo) {
                // System.out.println("组图数据请求成功: " + responseInfo.result);

                CacheUtils.putString(mActivity, ConstantUtils.PHOTOS_URL, responseInfo.result);

                processData(responseInfo.result);
            }

            @Override
            public void onFailure(HttpException error, String msg) {
                System.out.println("组图数据请求失败: " + msg);
            }
        });

    }

    /** * 处理和显示数据 * @param result */
    protected void processData(String json) {
        PhotosBean bean = parseJson(json);

        photoItemList = bean.data.news;
        PhotosAdapter mAdapter = new PhotosAdapter();
        mListView.setAdapter(mAdapter);
    }

    /** * 解析json数据 * @param json * @return */
    private PhotosBean parseJson(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, PhotosBean.class);
    }

    class PhotosAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return photoItemList.size();
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            PhotosViewHolder mHolder = null;
            if(convertView == null) {
                convertView = View.inflate(mActivity, R.layout.photos_item, null);
                mHolder = new PhotosViewHolder();
                mHolder.ivImage = (ImageView) convertView.findViewById(R.id.iv_photos_item_iamge);
                mHolder.tvDescription = (TextView) convertView.findViewById(R.id.tv_photos_item_description);
                convertView.setTag(mHolder);
            } else {
                mHolder = (PhotosViewHolder) convertView.getTag();
            }

            PhotoItemBean bean = photoItemList.get(position);

            // 根据mholder的两个对象进行赋值
            mHolder.tvDescription.setText(bean.title);

            // 设置默认图片
            mHolder.ivImage.setTag(position);
            mHolder.ivImage.setImageResource(R.drawable.pic_item_list_default);

            // 设置最新图片,之前设置的是默认图片,这里从网络请求图片后设置背景
            // bitmapUtils.display(mHolder.ivImage, bean.listimage);

            Bitmap bm = mBitmapCacheUtils.getBitmapFromUrl(bean.listimage, position);

            if(bm != null) {
                // 当前图片不等于null, 是从内存或者本地中取到的, 立刻显示.
                mHolder.ivImage.setImageBitmap(bm);
            }
            return convertView;
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return 0;
        }
    }

    public class PhotosViewHolder {

        public ImageView ivImage;
        public TextView tvDescription;
    }

    /** * 切换当前的页面显示. */
    public void switchListOrGrid(ImageButton ib) {
        if(isSingleColumns) {
            isSingleColumns = false;
            // 当前是单列, 切换成两列
            mListView.setVisibility(View.GONE);
            mGridView.setVisibility(View.VISIBLE);

            mGridView.setAdapter(new PhotosAdapter());

            // 切换图片
            ib.setImageResource(R.drawable.icon_pic_list_type);
        } else {
            isSingleColumns = true;
            // 当前是两列, 切换成单列
            mGridView.setVisibility(View.GONE);
            mListView.setVisibility(View.VISIBLE);

            mListView.setAdapter(new PhotosAdapter());

            // 切换图片
            ib.setImageResource(R.drawable.icon_pic_grid_type);
        }
    }
}

BitmapCacheUtils.java

/** * @author andong * 图片缓存工具类 */
public class BitmapCacheUtils {

    private NetCacheUtils mNetCacheUtils; // 网络缓存对象
    private LocalCacheUtils mLocalCacheUtils; // 本地缓存对象
    private MemoryCacheUtils mMemoryCacheUtils; // 内存缓存对象

    public BitmapCacheUtils(Handler handler) {

        mMemoryCacheUtils = new MemoryCacheUtils();
        mLocalCacheUtils = new LocalCacheUtils();
        mNetCacheUtils = new NetCacheUtils(handler, mLocalCacheUtils, mMemoryCacheUtils);
    }

    /** * 根据Url取图片 * * 1. 先根据Url去内存中取, 如果取到直接返回. * 2. 再根据Url去本地中取, 如果取到直接返回. * 3. 最后去网络中取, 取到之后发送给主线程显示. * 3.1 根据Url, 向内存中存一份. * 3.2 根据Url, 向本地中存一份. * * @param imageUrl * @return */
    public Bitmap getBitmapFromUrl(String imageUrl, int position) {
        // 1. 先根据Url去内存中取, 如果取到直接返回.
        Bitmap bm = mMemoryCacheUtils.getBitmapFromMemory(imageUrl);
        if(bm != null) {
            System.out.println("从内存中取到的");
            return bm;
        }

        // 2. 再根据Url去本地中取, 如果取到直接返回.
        bm = mLocalCacheUtils.getBitmapFromLocal(imageUrl);
        if(bm != null) {
            System.out.println("从本地中取到的");
            return bm;
        }

        // 3. 最后去网络中取, 取到之后发送给主线程显示.
        System.out.println("从网络中取到的");
        mNetCacheUtils.getBitmapFromNet(imageUrl, position);
        return null;
    }

}

MemoryCacheUtils.java

public class MemoryCacheUtils {

    private LruCache<String, Bitmap> mMemoryCache;

    public MemoryCacheUtils() {
        // 虚拟机内存的8分之一来缓存图片
        int maxMemorySize = (int) (Runtime.getRuntime().maxMemory() / 8);

        mMemoryCache = new LruCache<String, Bitmap>(maxMemorySize) {

            /** * 把图片的大小返回 */
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes() * value.getHeight();
            }
        };
    }

    /** * 向内存中存一张图片 * @param imageUrl * @param bm */
    public void putBitmap2Memory(String imageUrl, Bitmap bm) {
        mMemoryCache.put(imageUrl, bm);
    }

    /** * 从内存中取一张图片 * @param imageUrl * @return */
    public Bitmap getBitmapFromMemory(String imageUrl) {
        return mMemoryCache.get(imageUrl);
    }
}

LocalCacheUtils.java

/** * @author andong * 本地缓存工具类 */
public class LocalCacheUtils {

    // 缓存的目录
    private final String CACHE_DIR = "/mnt/sdcard/itheima_zhbj";

    /** * 根据Url存储当前图片 * @param imageUrl * @param bm */
    public void putBitmap2Local(String imageUrl, Bitmap bm) {
        try {
            String fileName = MD5Encoder.encode(imageUrl);
            File file = new File(CACHE_DIR, fileName); // /mnt/sdcard/it/aslkjdlhk124312423lkj
            File parentFile = file.getParentFile();
            if(!parentFile.exists()) {
                parentFile.mkdirs();
            }

            FileOutputStream fos = new FileOutputStream(file);
            // 把图片通过流写到本地
            bm.compress(CompressFormat.JPEG, 100, fos);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** * 从本地中根据url取出图片 * @param imageUrl * @return */
    public Bitmap getBitmapFromLocal(String imageUrl) {
        try {
            String fileName = MD5Encoder.encode(imageUrl);
            File file = new File(CACHE_DIR, fileName); // /mnt/sdcard/itheima_zhbj/aslkjdlhk124312423lkj
            if(file.exists()) {
                // 文件存在, 有缓存, 读取出来, 并返回

                FileInputStream is = new FileInputStream(file);
                Bitmap bm = BitmapFactory.decodeStream(is);
                return bm;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

NetCacheUtils.java

/** * @author andong * 网络缓存工具类 */
public class NetCacheUtils {

    public static final int SUCCESS = 0;
    public static final int FAILED = 1;

    private Handler handler;
    private ExecutorService mExecutorService;
    private LocalCacheUtils localCacheUtils; // 本地缓存对象
    private MemoryCacheUtils memoryCacheUtils; // 内存缓存对象

    public NetCacheUtils(Handler handler, LocalCacheUtils localCacheUtils, MemoryCacheUtils memoryCacheUtils) {
        this.handler = handler;
        this.localCacheUtils = localCacheUtils;
        this.memoryCacheUtils = memoryCacheUtils;

        // 创建一个线程池
        mExecutorService = Executors.newFixedThreadPool(10);
    }

    /** * 使用子线程去请求网络, 把图片抓取回来, 再发送给主线程 * @param imageUrl */
    public void getBitmapFromNet(String imageUrl, int position) {
        // new Thread(new InternalRunnable(imageUrl, position)).start();

        // 让线程池执行一个任务.
        mExecutorService.execute(new InternalRunnable(imageUrl, position));
    }

    class InternalRunnable implements Runnable {

        private String imageUrl;
        private int position;

        public InternalRunnable(String imageUrl, int position) {
            this.imageUrl = imageUrl;
            this.position = position;
        }

        @Override
        public void run() {
            HttpURLConnection conn = null;
            try {
                conn = (HttpURLConnection) new URL(imageUrl).openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(5000);
                conn.connect();

                int responseCode = conn.getResponseCode();
                if(responseCode == 200) {
                    InputStream is = conn.getInputStream();
                    Bitmap bm = BitmapFactory.decodeStream(is);

                    // 发送到主线程中显示
                    Message msg = handler.obtainMessage();
                    msg.obj = bm;
                    msg.what = SUCCESS;
                    msg.arg1 = position;
                    handler.sendMessage(msg);

                    // 向内存存一份
                    memoryCacheUtils.putBitmap2Memory(imageUrl, bm);
                    // 向本地存一份
                    localCacheUtils.putBitmap2Local(imageUrl, bm);
                }
            } catch (Exception e) {
                e.printStackTrace();
                Message msg = handler.obtainMessage();
                msg.what = FAILED;
                msg.arg1 = position;
                handler.sendMessage(msg);
            } finally {
                if(conn != null) {
                    conn.disconnect(); // 断开连接
                }
            }
        }
    }
}

你可能感兴趣的:(图片缓存)