我正在使用DiskLruCache
来缓存图片网址。我使用AsyncTask
下载图像,如下所示:
new AsyncTask<String, String, String>() {
String path = null;
@Override
protected String doInBackground(String... params) {
// Get the assets from DiskLruCache
try {
if (url != null)
path = assetManager.getAssetFilePath(url);
} catch (IOException e) {
callback.downloadFailed();
}
return path;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (path != null)
callback.assetDownloaded(path);
else
callback.downloadFailed();
}
}.execute();
AssetManager
是一个调用方法getAssetFilePath(...)
的自定义助手类。这段代码中出现了异常:
DiskLruCache.Snapshot snapshot = mDiskCache.get(key);
if (snapshot == null) {
DiskLruCache.Editor editor = mDiskCache.edit(key);
InputStream is = downloadFile(url);
if (is == null) return null;
// EXCEPTION OCCURS HERE
OutputStream os = editor.newOutputStream(0);
byte[] buffer = new byte[1024 * 10];
int len;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
is.close();
os.close();
editor.commit();
}
具体来说,这一行导致异常:
OutputStream os = editor.newOutputStream(0);
我似乎无法在我的任何测试设备上复制此问题,但它正在为其他用户发生。
这个问题的原因是什么?我该如何处理它?</ p>
logcat告诉我:
由java.lang.NullPointerException引起:尝试调用虚方法&#39; java.io.OutputStream com.jakewharton.disklrucache.DiskLruCache $ Editor.newOutputStream(int)&#39;在空对象引用上
有更好的方法吗?
这也是初始化DiskLruCache
的好方法吗?如果没有,那么什么是良好的可扩展初始化?寻找最佳实践和实施。
public CacheManager() {
BASE_PATH = Environment.getExternalStorageDirectory().getPath() + "/exampleapp";
try {
mDiskCache = DiskLruCache.open(new File(BASE_PATH), VERSION, 1, CACHE_SIZE);
} catch (IOException e) {
Log.i(TAG, "Asset Manager IOException");
e.printStackTrace();
}
}
答案 0 :(得分:0)
可能
DiskLruCache.Editor editor = mDiskCache.edit(key);
已经为空 - 但您没有检查。由于mDiskCache.get(key)
已经返回null,因此在检查之前是否合理?
答案 1 :(得分:0)
edit(String key): Returns an editor for the entry named key, or null if another edit is in progress.
您应检查它是否未返回null
,如果是,请在将来没有其他修改正在进行时再次尝试。 (也许将编辑排在另一个线程上)。
答案 2 :(得分:0)
在不同的线程中使用相同的编辑器会出现此错误。只需确保同步使用编辑器的方法。
public synchronized writeMyDataToCache(String key, String data){
DiskLruCache.Editor editor = diskLruCache.edit(key);
writeSomethingToCache(editor, data);
}