您的位置:首页 > 理论基础 > 计算机网络

扣丁学堂——双缓存实例(处理较大网络图片)

2016-01-23 20:24 681 查看
一丶代码见本文

二丶演示(略)就是点击显示网络图片,并将其加载进入缓存和内存中

java没学好,这节还怎么懂,就直接复制粘贴源码,下次慢慢看,用到直接用

MainActivity

public class MainActivity extends AppCompatActivity {

    private ImageView iv,iv2;
    private LruCache<String,Bitmap> lruCache;

    private LruCacheUtils lruCacheUtils;
    private static final String DISK_CACHE_SUBDIR = "temp";
    private static final int DISK_CACHE_SIZE = 1024*1024*10;  //10MB
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) findViewById(R.id.imageView);
        iv2 = (ImageView) findViewById(R.id.imageView2);

        //获取当前activity内存大小
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        int memoryClass = am.getMemoryClass();
        final int cacheSize = memoryClass/8 * 1024 * 1024;  //字节  8/1的内存作为缓存大小(通常)

        lruCache = new LruCache<>(cacheSize);

    }

    //添加缓存
    public void addBitmapToCache(String key,Bitmap bitmap){
        if(getBitmapFromCahce(key)==null){
            lruCache.put(key,bitmap);
        }
    }

    //从缓存中读取方法
    public Bitmap getBitmapFromCahce(String key){
       return lruCache.get(key);
    }

    public void showClick(View view){
        String key = String.valueOf(R.mipmap.a);
        Bitmap bitmap = getBitmapFromCahce(key);
        if(bitmap==null) {
            bitmap = decodeSampledBitmapFromResource(getResources(), R.mipmap.a, 100, 100);
            addBitmapToCache(key,bitmap);
        }else{
            System.out.println("lruCache中有位图");
        }

        iv.setImageBitmap(bitmap);
    }

    public void show2Click(View view){
        String url = "http://i2.sinaimg.cn/photo/2/2013-06-17/U10152P1505T2D2F66DT20150328095931.jpg";
        loadBitmap(url,iv2);
    }

    @Override
    protected void onResume() {
        super.onResume();
        lruCacheUtils = LruCacheUtils.getInstance();
        lruCacheUtils.open(this, DISK_CACHE_SUBDIR, DISK_CACHE_SIZE);
    }

    @Override
    protected void onPause() {
        super.onPause();
        lruCacheUtils.flush();
    }

    @Override
    protected void onStop() {
        super.onStop();
        lruCacheUtils.close();
    }

    /**
     * 加载图片
     * @param url
     * @param imageView
     */
    public void loadBitmap(String url, final ImageView imageView){
        //从内存缓存中取图片
        Bitmap bitmap = lruCacheUtils.getBitmapFromCahce(url);
        if (bitmap==null){
            //再从磁盘缓存中取图片
            InputStream in = lruCacheUtils.getDiskCache(url);
            if (in==null){
                lruCacheUtils.putCache(url, new LruCacheUtils.CallBack<Bitmap>() {
                    @Override
                    public void response(Bitmap entity) {
                        System.out.println("http load");
                        imageView.setImageBitmap(entity);
                    }
                });
            }else{
                System.out.println("disk cache");
                bitmap = BitmapFactory.decodeStream(in);
                lruCacheUtils.addBitmapToCache(url,bitmap);
                imageView.setImageBitmap(bitmap);
            }
        }else{
            System.out.println("memory cache");
            imageView.setImageBitmap(bitmap);
        }
    }

    /**
     * 位图重新采样
     * @param res
     * @param resid
     * @param reqWidth
     * @param reqHeight
     * @return
*/
    public Bitmap decodeSampledBitmapFromResource(Resources res,int resid,int reqWidth,int reqHeight){
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res,resid,options);
        options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resid,options);
    }
    /**
     * 计算位图的采样比例
     * @param options
     * @param reqWidth
     * @param reqHeight
     * @return
*/
    public int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){
        //获取位图的原宽高
        int w = options.outWidth;
        int h = options.outHeight;
        System.out.println("w="+w);
        System.out.println("h="+h);
        int inSampleSize = 1;
        if(w>reqWidth || h>reqHeight){
            if(w>h){
                // Math.round四舍五入
                inSampleSize = Math.round((float)h / (float)reqHeight);
            }else{
                inSampleSize = Math.round((float)w / (float)reqWidth);
            }
        }
        System.out.println("inSampleSize="+inSampleSize);
        return inSampleSize;
    }

}

LruCacheUtils(磁盘缓存第三方解决方案,这里重新律顺一下)

public class LruCacheUtils {
    private static LruCacheUtils lruCacheUtils;
    private DiskLruCache diskLruCache;  //LRU磁盘缓存
    private LruCache<String,Bitmap> lruCache; //LRU内存缓存
    private Context context;

    private LruCacheUtils(){}

    public static LruCacheUtils getInstance(){
        if (lruCacheUtils ==null){
            lruCacheUtils = new LruCacheUtils();
        }
        return lruCacheUtils;
    }
    //打开磁盘缓存
    public void open(Context context,String disk_cache_subdir,int disk_cache_size){
        try {
            this.context = context;
            //获取当前activity内存大小
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            int memoryClass = am.getMemoryClass();
            lruCache = new LruCache<>(memoryClass/8 * 1024 * 1024);//字节  8/1的内存作为缓存大小(通常)
            //open()方法接收四个参数,第一个参数指定的是数据的缓存地址,
            // 第二个参数指定当前应用程序的版本号,
            // 第三个参数指定同一个key可以对应多少个缓存文件,基本都是传1,
            // 第四个参数指定最多可以缓存多少字节的数据。通常10MB
            diskLruCache = DiskLruCache.open(getCacheDir(disk_cache_subdir), getAppVersion(), 1, disk_cache_size);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //添加缓存
    public void addBitmapToCache(String url,Bitmap bitmap){
        String key = hashKeyForDisk(url);
        if(getBitmapFromCahce(key)==null){
            System.out.println("key===="+key);
            System.out.println("bitmap===="+bitmap);
            lruCache.put(key,bitmap);
        }
    }

    //从缓存中读取方法
    public Bitmap getBitmapFromCahce(String url){
        String key = hashKeyForDisk(url);
        return lruCache.get(key);
    }

    //关闭磁盘缓存
    public void close(){
        if (diskLruCache!=null && !diskLruCache.isClosed()){
            try {
                diskLruCache.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //刷新磁盘缓存
    public void flush(){
        if (diskLruCache!=null){
            try {
                diskLruCache.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取磁盘缓存
     * @param url
     * @return
*/
    public InputStream getDiskCache(String url) {
        String key = hashKeyForDisk(url);
        System.out.println("getDiskCache="+key);
        try {
            DiskLruCache.Snapshot snapshot = diskLruCache.get(key);
            System.out.println(snapshot);
            if (snapshot!=null){
                return snapshot.getInputStream(0);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 下载图片并缓存到内存和磁盘
     * @param url
     * @param callBack
     */
    public void putCache(final String url, final CallBack callBack){
        new AsyncTask<String,Void,Bitmap>(){
            @Override
            protected Bitmap doInBackground(String... params) {
                String key = hashKeyForDisk(params[0]);
                System.out.println("key="+key);
                DiskLruCache.Editor editor = null;
                Bitmap bitmap = null;
                try {
                    URL url = new URL(params[0]);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setReadTimeout(1000 * 30);
                    conn.setConnectTimeout(1000 * 30);
                    ByteArrayOutputStream baos = null;
                    if(conn.getResponseCode()==HttpURLConnection.HTTP_OK){
                        BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
                        baos = new ByteArrayOutputStream();
                        byte[] bytes = new byte[1024];
                        int len = -1;
                        while((len=bis.read(bytes))!=-1){
                            baos.write(bytes,0,len);
                        }
                        bis.close();
                        baos.close();
                        conn.disconnect();
                    }
                    if (baos!=null){
                        bitmap = decodeSampledBitmapFromStream(baos.toByteArray(),100,100);
                        addBitmapToCache(params[0],bitmap);
                        editor = diskLruCache.edit(key);
                        System.out.println(url.getFile());
                        //位图压缩后输出(参数:压缩格式,质量(100表示不压缩,30表示压缩70%),输出流)
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, editor.newOutputStream(0));
                        editor.commit();//提交
                    }
                } catch (IOException e) {
                    try {
                        editor.abort();//放弃写入
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
                return bitmap;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                super.onPostExecute(bitmap);
                callBack.response(bitmap);
            }
        }.execute(url);
    }

    //回调接口
    public interface CallBack<T>{
        public void response(T entity);
    }

    /**
     * 计算采样比例
     * @param options
     * @param reqWidth
     * @param reqHeight
     * @return
*/
    public int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){
        //获取位图的原宽高
        int w = options.outWidth;
        int h = options.outHeight;
        int inSampleSize = 1;
        if(w>reqWidth || h>reqHeight){
            if(w>h){
                inSampleSize = Math.round((float)h / (float)reqHeight);
            }else{
                inSampleSize = Math.round((float)w / (float)reqWidth);
            }
        }
        return inSampleSize;
    }

    /**
     *
     * @param bytes
     * @param reqWidth
     * @param reqHeight
     * @return
*/
    public Bitmap decodeSampledBitmapFromStream(byte[] bytes,int reqWidth,int reqHeight){
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
        options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
    }

    /**
     * MD5计算摘要
     * @param key
     * @return
*/
    public String hashKeyForDisk(String key) {
        String cacheKey;
        try {
            final MessageDigest mDigest = MessageDigest.getInstance("MD5");
            mDigest.update(key.getBytes());
            cacheKey = bytesToHexString(mDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            cacheKey = String.valueOf(key.hashCode());
        }
        return cacheKey;
    }

    private String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(0xFF & bytes[i]);
            if (hex.length() == 1) {
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    /**
     * 获取版本号
     * @return
*/
    private int getAppVersion() {
        try {
            return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 1;
    }

    //获取缓存目录
    private File getCacheDir(String name) {
        String cachePath = Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED || !Environment.isExternalStorageRemovable() ?
                context.getExternalCacheDir().getPath() : context.getCacheDir().getPath();
        name = cachePath + File.separator + name;
        System.out.println(name);
        return new File(name);
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: