2011-12-16 2 views
0

.하는 SoftReference/WeakReference를 Nullpointer

private WeakHashMap<String, SoftReference<Bitmap>> mCache; 

public Bitmap get(String key, BmpWrap image, BitmapFactory.Options options){ 

      File root = mContext.getFilesDir(); 
      String name = Activity.fullScreenActive ? image.name + ".png" : image.name 
        + ".stat.png"; 
      File img = new File(root, name); 

      if(key == null){ 
       return null; 
      } 
      if(mCache.containsKey(key)){ 
       SoftReference<Bitmap> reference = mCache.get(key); 
       image.bmp = reference.get(); 
       if(image.bmp != null){ 
        return image.bmp; 
       } 
       image.bmp = BitmapFactory.decodeFile(img.getAbsolutePath(), options); 
       mCache.put(key, new SoftReference<Bitmap>(image.bmp)); 
       return image.bmp; 
      } 

      if(img.exists()){ 
       image.bmp = BitmapFactory.decodeFile(img.getAbsolutePath(), options); 
       mCache.put(key, new SoftReference<Bitmap>(image.bmp)); 
       return image.bmp; 
      } else{ 
       throw new RuntimeException("Boooom!"); 
      } 
     } 

     private void scaleImage(BmpWrap image, BitmapFactory.Options options) 

     { 
      options.inTempStorage = new byte[16 * IMG_BUFFER_LEN]; 
      options.inPreferredConfig = Bitmap.Config.RGB_565; 
      options.inDither = false; 


      try { 
       Field f = options.getClass().getField("inPurgeable"); 
       f.set(options, Boolean.TRUE); 

       Field f2 = options.getClass().getField("inInputShareable"); 
       f2.set(options, Boolean.TRUE); 
      } catch (Exception ignore) { 
      } 

      File root = mContext.getFilesDir(); 
      String name = Activity.fullScreenActive ? image.name + ".png" : image.name 
        + ".stat.png"; 
      File img = new File(root, name); 

      // maybe it's jpeg 
      if (!img.exists()) { 
       img = new File(root, name.replace(".png", ".jpg")); 
      } 

      if (img.exists()) { 

       if (image.bmp == null || Activity.fullScreenSwitch) { 
        if (image.bmp != null) 
        image.bmp.recycle(); 
        image.bmp = null; 
        **get(name, image, options);** 
        //image.bmp = BitmapFactory.decodeFile(img.getAbsolutePath(), options); 
       } else if (image.bmp == null) { 
        image.bmp = BitmapFactory.decodeResource(getResources(), 
          getResourceByString(image.name), options); 
       } 
      } else { 
       image.bmp = BitmapFactory.decodeResource(getResources(), 
         getResourceByString(image.name), options); 
      } 
     } 

스택

나는이 생각
12-16 18:30:42.724: E/AndroidRuntime(9955): FATAL EXCEPTION: main 
12-16 18:30:42.724: E/AndroidRuntime(9955): java.lang.RuntimeException: Boooom! 
12-16 18:30:42.724: E/AndroidRuntime(9955):  at com.apk.View$Thread.get(View.java:259) 
12-16 18:30:42.724: E/AndroidRuntime(9955):  at com.apk.View$Thread.scaleImage(View.java:296) 
12-16 18:30:42.724: E/AndroidRuntime(9955):  at com.apk.View$Thread.resizeImages(View.java:326) 
12-16 18:30:42.724: E/AndroidRuntime(9955):  at com.apk.View$Thread.setSurfaceSize(View.java:515) 
12-16 18:30:42.724: E/AndroidRuntime(9955):  at com.apk.View.surfaceChanged(View.java:889) 
+0

잠깐, SoftReference에 WeakReference를 비트 맵으로 보내시겠습니까? – kabuko

+0

어떤 경우에는 get 메소드 호출에서 주석 처리 된 행에 OOM을 수신합니다. 그래서 충돌을 막기 위해 이것을 구현하기를 원합니다. – user1097075

+0

물론, 정상적인 WeakHashMap 의 문제점은 무엇입니까? – kabuko

답변

0

,

private WeakHashMap<String, SoftReference<Bitmap>> mCache; 

뭔가 같은 (이 NPE입니다 ),

private WeakHashMap<String, SoftReference<Bitmap>> mCache = new WeakHashMap<String, SoftReference<Bitmap>>(); 

이 시도하고 보자 내게 무슨 일이 일어날 지 알지 ..

+0

NPE가 중지되었지만 이제는 RunTimeException을 던집니다. 새 RuntimeException을 throw합니다 ("Boooom!"); scaleImage에서 비트 맵을 null로 만들고 재활용하는 루틴에 대해서는 확실하지 않아 루틴에 약간의 수정을 가할 수 있습니다. 이제 소프트 참조를 사용하고 있습니다. – user1097075

+0

이미지가 존재하지 않는다고 생각합니다. – user1097075

+0

예 이미지가 img.getAbsolutePath()에 있습니다. – user1097075

0

NullPointerException은 액세스하려는 경우 mCache이 null임을 의미합니다. 그리고 주어진 이름을 가진 메모리에 파일이 존재하지 않기 때문에 RuntimeException이 발생합니다.

또한 질문에서이 질문을하지 않았지만 말할 적절한 말이 있습니다. WeakHashMap을 사용해야하는 이유는 무엇입니까? 이는 GC가 이 더 이상 참조되지 않는 항목을 수집하도록 허용하는 데 사용됩니다. 문자열을 키로 사용하므로 도달 할 수 있는지 여부에 의존하려는 이유는 무엇입니까? 이 메커니즘은 비트 맵을 가비지 수집하도록되어 있으므로 SoftReferences에 대한 일반적인 HashMap이 실제로 필요한 것입니다.

+0

예를 들면? map의 예는 명백하게'private Map > mCache'입니다. – Malcolm

+0

위의 코드 예제에서이를 어떻게 통합 할 수 있습니까? – user1097075

+0

'WeakHashMap > mCache;'줄을 지우고 내 줄을 입력하십시오. – Malcolm