从DiskLruCache访问OutputStream时出现NullPointerException

时间:2015-12-22 23:24:01

标签: java android caching

我正在使用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();
    }

}

3 个答案:

答案 0 :(得分:0)

可能

    DiskLruCache.Editor editor = mDiskCache.edit(key);

已经为空 - 但您没有检查。由于mDiskCache.get(key)已经返回null,因此在检查之前是否合理?

答案 1 :(得分:0)

来自documentation

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);
}