2015-12-22 52 views
1

我正在使用DiskLruCache來緩存圖像的URL。我下載使用AsyncTask的圖像,像這樣:從DiskLruCache訪問OutputStream時出現NullPointerException

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

我似乎無法複製任何我的測試設備,但它的這個問題正在爲其他用戶發生。

這個問題的原因是什麼?我該如何解決這個問題?

的logcat的告訴我:

通過顯示java.lang.NullPointerException產生的原因:試圖調用虛擬方法的java.io.OutputStream com.jakewharton.disklrucache.DiskLruCache $ Editor.newOutputStream(INT)'在零對象上引用

有沒有更好的方法來做到這一點?

也是這是初始化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

大概

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

已經是空 - 但是你不檢查這一點。由於mDiskCache.get(key)已經返回null之前,這似乎是合理的檢查?

+0

我該如何預防?這是正常的行爲嗎? – AndyRoid

+0

有沒有更好的方法來處理這個問題?更好的建築? – AndyRoid

+0

首先檢查null並且什麼都不做 - null可能會激活另一個編輯處於活動狀態(在另一個線程中下載)。如果同一圖像被多個線程讀取,您有時會看到此錯誤,但並非總是如此。 – Jan

0

documentation

edit(String key): Returns an editor for the entry named key, or null if another edit is in progress. 

你應該檢查它沒有返回null,如果是,在將來某個時間重試時沒有其他的編輯都在進步。 (也許在另一個線程上排隊編輯)。

+0

我在哪裏可以找到一個很好的實現?我似乎無法找到好的例子。我明白,可能使用優先隊列在這裏是理想的,但我之前並沒有像緩存那樣工作。 – AndyRoid

相關問題