我是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源文件(可以找到here)。
答案 0 :(得分:0)
好!我终于明白了。 (我自己的愚蠢错误.... grrr)
在此之前我修改了DiskLruCache.java,以便验证任何密钥!默认情况下,它应该只验证带有正则表达式[a-z0-9_-]的任何字符串,即不应该有任何大写字母,空格或甚至换行符。我认为这不是什么大问题所以我把它关掉并接受所有字符串。
但错了!我将其修改为默认值,然后每次添加或获取缓存时都修改了我的密钥,并且完美!
谢谢! :)