读Android照片墙结合DiskLruCache有感

存储详情

读Android照片墙结合DiskLruCache有感_第1张图片
Paste_Image.png
读Android照片墙结合DiskLruCache有感_第2张图片
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照片墙完整版,完美结合LruCache和DiskLruCache

你可能感兴趣的:(读Android照片墙结合DiskLruCache有感)