我是 SO 新手,也是 Android 编程新手!如果这个问题是微不足道的,请原谅我。
无论如何,我正在尝试创建一个画廊应用程序,它将显示文件夹中所有媒体文件(视频和图片)的缩略图。我的应用程序运行良好,除了处理图像以获取其采样位图的漫长等待时间。
我已经使用内存缓存(LruCache)解决了这个问题,但它只在用户留在应用程序中并四处导航时解决了这个问题。每次用户关闭应用程序并重新打开它时,它都会再次重新生成缓存。
在网上做了一些阅读后,我决定在内存缓存之上添加磁盘缓存,希望它能解决问题。但即使在我实施之后,问题仍然存在。不确定我是否做错了。
下面是我初始化内存缓存和磁盘缓存的代码。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
if (savedInstanceState != null) {
displayManager.cancelAsyncTask();
path = savedInstanceState.getString(ARG_POSITION);
}else{
// Get memory class of this device, exceeding this amount will throw an
// OutOfMemory exception.
final int memClass = ((ActivityManager)getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = 1024 * 1024 * memClass / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in bytes rather than number of items.
return bitmap.getByteCount();
}
};
Log.d("DEBUG_CACHE","context is "+this);
File cacheDir = getDiskCacheDir(this, DISK_CACHE_SUBDIR);
Log.d("DEBUG_CACHE", "cache dir is "+cacheDir.getAbsolutePath());
new InitDiskCacheTask().execute(cacheDir);
}
ArrayList<File> folderList = dataManager.getFolderListWithPhotoOrVideo(path);
ArrayList<File> thumbList = dataManager.getAllPhotosAndVideos(path);
displayManager.setCurrentPath(path);
displayManager.setParent(this);
displayManager.setMemCache(mMemoryCache);
displayManager.setFolderList(folderList);
displayManager.setThumbnails(thumbList);
}
下面是我如何从缓存中获取缩略图(如果存在)以及如何将位图添加到缓存中。
@Override
protected Void doInBackground(Void... params) {
int noOfThumbnails = thumbnails.size();
for(int j=0;j<noOfThumbnails;j++){
String filePath = thumbnails.get(j).getName();
if(isPhoto(filePath)){
//if file is an image file
Uri uri = Uri.fromFile(new File(thumbnails.get(j).getAbsolutePath()));
Bitmap thumb = getBitmapFromMemCache(filePath);
if(thumb==null){
thumb = getBitmapFromDiskCache(filePath);
if(thumb==null){
thumb = getPreview(uri);
addBitmapToCache(filePath,thumb);
}
}
bitmaps.add(thumb);
}else{
Bitmap thumb = getBitmapFromMemCache(filePath);
if(thumb==null){
thumb = getBitmapFromDiskCache(filePath);
if(thumb==null){
thumb = ThumbnailUtils.createVideoThumbnail(thumbnails.get(j).getAbsolutePath(),MediaStore.Images.Thumbnails.MICRO_KIND);
addBitmapToCache(filePath,thumb);
}
}
bitmaps.add(thumb);
}
double progress = ((double)(j+1)/(double)noOfThumbnails)*100;
publishProgress(new Double(progress).intValue());
if(isCancelled()){
Log.d("DEBUG", "doInBackGround. Task cancelled");
return null;
}
}
return null;
}
public void addBitmapToCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
// Also add to disk cache
synchronized (parent.mDiskCacheLock) {
try {
if (parent.mDiskLruCache != null && parent.mDiskLruCache.get(key) == null) {
parent.mDiskLruCache.put(key, bitmap);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public Bitmap getBitmapFromMemCache(String key) {
return (Bitmap) mMemoryCache.get(key);
}
public Bitmap getBitmapFromDiskCache( String key ) {
Bitmap bitmap = null;
Snapshot snapshot = null;
try {
snapshot = parent.mDiskLruCache.get( key );
if ( snapshot == null ) {
return null;
}
final InputStream in = snapshot.getInputStream( 0 );
if ( in != null ) {
final BufferedInputStream buffIn =
new BufferedInputStream( in, Utils.IO_BUFFER_SIZE );
bitmap = BitmapFactory.decodeStream( buffIn );
}
} catch ( IOException e ) {
e.printStackTrace();
} finally {
if ( snapshot != null ) {
snapshot.close();
}
}
return bitmap;
}
对于 DiskLruCache.java,我使用了 google 源文件(可以在这里找到)。