美文网首页
读Android照片墙结合DiskLruCache有感

读Android照片墙结合DiskLruCache有感

作者: jacky123 | 来源:发表于2016-07-16 21:08 被阅读143次

    存储详情

    Paste_Image.png Paste_Image.png

    DiskCache 使用详情

    1.声明DiskLruCache,并初始化
    private DiskLruCache mDiskLruCache;
    
    
    // 获取图片缓存路径
    File cacheDir = getDiskCacheDir(context, "thumb");
    if (!cacheDir.exists()) {
        cacheDir.mkdirs();
    }
    // 创建DiskLruCache实例,初始化缓存数据 ,设置了硬盘缓存容量为10M
    mDiskLruCache = DiskLruCache
            .open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024);  
            
    /**
     * 根据传入的uniqueName获取硬盘缓存的路径地址。
     */
    public File getDiskCacheDir(Context context, String uniqueName) {
        String cachePath;
        if (Environment.MEDIA_MOUNTED.equals(Environment
                .getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            cachePath = context.getExternalCacheDir().getPath();
        } else {
            cachePath = context.getCacheDir().getPath();
        }
        return new File(cachePath + File.separator + uniqueName);
    }       
            
    /**
     * 获取当前应用程序的版本号。
     */
    public int getAppVersion(Context context) {
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0);
            return info.versionCode;
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        return 1;
    }
    

    一般我们对于应用安全性不高的数据,能够缓存到sd卡就缓存到sd的context.getExternalCacheDir().getPath()路径,在本示例具体的路径就是:/storage/emulated/0/Android/data/com.example.photoswalldemo/cache


    2.使用DiskLruCache前奏

    在Adapter的getView中,我们通过方法loadBitmaps,尝试读取内存缓存

    /**
     * 加载Bitmap对象。此方法会在LruCache中检查所有屏幕中可见的ImageView的Bitmap对象,
     * 如果发现任何一个ImageView的Bitmap对象不在缓存中,就会开启异步线程去下载图片。
     */
    public void loadBitmaps(ImageView imageView, String imageUrl) {
        try {
            Bitmap bitmap = getBitmapFromMemoryCache(imageUrl);
            if (bitmap == null) {
                BitmapWorkerTask task = new BitmapWorkerTask();
                taskCollection.add(task);
                task.execute(imageUrl);
            } else {
                if (imageView != null && bitmap != null) {
                    imageView.setImageBitmap(bitmap);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    3.DiskLruCache 存取的细节
    //AsyncTask中
    @Override
    protected Bitmap doInBackground(String... params) {
        imageUrl = params[0];
        FileDescriptor fileDescriptor = null;
        FileInputStream fileInputStream = null;
        Snapshot snapShot = null;
        try {
            // 生成图片URL对应的key
            final String key = md5Key(imageUrl);
            // 查找key对应的缓存
            snapShot = mDiskLruCache.get(key);
            if (snapShot == null) {
                // 如果没有找到对应的缓存,则准备从网络上请求数据,并写入缓存
                DiskLruCache.Editor editor = mDiskLruCache.edit(key);
                if (editor != null) {
                    OutputStream outputStream = editor.newOutputStream(0);
                    if (downloadUrlToStream(imageUrl, outputStream)) {
                        editor.commit();
                    } else {
                        editor.abort();
                    }
                }
                // 缓存被写入后,再次查找key对应的缓存
                snapShot = mDiskLruCache.get(key);
            }
            if (snapShot != null) {
                /** 得到缓存文件的输入流 **/
                fileInputStream = (FileInputStream) snapShot
                        .getInputStream(0);
                fileDescriptor = fileInputStream.getFD();
            }
            // 将缓存数据解析成Bitmap对象
            Bitmap bitmap = null;
            if (fileDescriptor != null) {
                bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
            }
            if (bitmap != null) {
                // 将Bitmap对象添加到内存缓存当中
                addBitmapToMemoryCache(params[0], bitmap);
            }
            return bitmap;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileDescriptor == null && fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                }
            }
        }
        return null;
    }
    
    
    /**
     * 建立HTTP请求,并获取Bitmap对象。
     * 
     * @param imageUrl
     *            图片的URL地址
     * @return 解析后的Bitmap对象
     */
    private boolean downloadUrlToStream(String urlString,
            OutputStream outputStream) {
        HttpURLConnection urlConnection = null;
        BufferedOutputStream out = null;
        BufferedInputStream in = null;
        try {
            final URL url = new URL(urlString);
            urlConnection = (HttpURLConnection) url.openConnection();
            in = new BufferedInputStream(urlConnection.getInputStream(),
                    8 * 1024);
            out = new BufferedOutputStream(outputStream, 8 * 1024);
            int b;
            while ((b = in.read()) != -1) {
                out.write(b);
            }
            return true;
        } catch (final IOException e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
    

    4.其他细节
    /**
     * 将缓存记录同步到journal文件中。
     */
    public void fluchCache() {
        if (mDiskLruCache != null) {
            try {
                mDiskLruCache.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    //然后再Activity中调用
    @Override
    protected void onPause() {
        super.onPause();
        mAdapter.fluchCache();
    }
    

    DiskLruCache 的源码地址:
    Android-Universal-Image-Loader-master 里面。

    原文地址

    相关文章

      网友评论

          本文标题:读Android照片墙结合DiskLruCache有感

          本文链接:https://www.haomeiwen.com/subject/ilnyjttx.html