2012-01-23 2 views

답변

1

공개 열거 형 BitmapLoading { INSTANCE;

private final Map<String, SoftReference<Bitmap>> cache; 
private final ExecutorService pool; 
private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>()); 
private Bitmap placeholder; 

BitmapLoading() { 
    cache = new HashMap<String, SoftReference<Bitmap>>(); 
    pool = Executors.newFixedThreadPool(5); 
} 

public void setPlaceholder(Bitmap bmp) { 
    try { 
     placeholder = bmp; 
    } catch (OutOfMemoryError e) { 
     placeholder.recycle(); 
     bmp.recycle(); 
     placeholder = null; 
     bmp = null; 
    } 
} 

public Bitmap getBitmapFromCache(String url) { 
    if (cache.containsKey(url)) { 
     return cache.get(url).get(); 
    } 
    return null; 
} 

public void queueJob(final String url, final ImageView imageView,final int width, final int height) { 
    /* Create handler in UI thread. */ 
    final Handler handler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      String tag = imageViews.get(imageView); 
      if (tag != null && tag.equals(url)) { 
       if (msg.obj != null) { 
        imageView.setImageBitmap((Bitmap) msg.obj); 
       } else { 
        imageView.setImageBitmap(placeholder); 
        Log.d(null, "fail " + url); 
       } 
      } 
     } 
    }; 
    pool.submit(new Runnable() { 
     @Override 
     public void run() { 
      Bitmap bmp = null; 
      try{ 
       bmp = downloadBitmap(url, width, height); 
       Message message = Message.obtain(); 
       message.obj = bmp; 
       handler.sendMessage(message); 
      }catch (OutOfMemoryError e) { 
       bmp.recycle(); 
       bmp = null; 
      } 
     } 
    }); 
} 

public void loadBitmap(final String url, final ImageView imageView,final int width, final int height) { 
    imageViews.put(imageView, url); 
    Bitmap bitmap = null ; 
    try { 
     bitmap = getBitmapFromCache(url); 
     if (bitmap != null) { 
      imageView.setImageBitmap(bitmap); 
     } else { 
      imageView.setImageBitmap(placeholder); 
      queueJob(url, imageView, width, height); 
     } 
    } catch (OutOfMemoryError e) { 
     bitmap.recycle(); 
     bitmap = null; 
     System.gc(); 
    } 
} 

private Bitmap downloadBitmap(String url, int width, int height) { 
    Bitmap bitmap =null; 
    try { 
     bitmap = BitmapFactory.decodeStream((InputStream) new URL(url).getContent()); 
     bitmap = Bitmap.createScaledBitmap(bitmap, width, height, true); 
     cache.put(url, new SoftReference<Bitmap>(bitmap)); 
     return bitmap; 
    }catch (OutOfMemoryError e) { 
     bitmap.recycle(); 
     bitmap = null; 
     System.gc(); 
    } 
    catch (MalformedURLException e) { 
    } catch (IOException e) { 
    } 
    return null; 
} 

}

+0

이 코드가 도움이 될 것 같아요. –

0

이 문제를 해결하기 위해 지연로드 개념을 사용해야하거나 비트 맵에서 소프트 참조 개념을 사용해야합니다.

+0

좋습니다. 시도해 보겠습니다. 고마워요. – Srinivas

2

이러한 링크가 유용 할 수 있습니다.
http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html
또한이 링크는 이미지로드와 관련된 목록/그리드 구현시 간단하지만 과격한 실수를 어떻게 저 지르는지 보여줍니다.
How to solve the vm budget memory heap error in lazy loading bitmaps?

또한 활동을 반복적으로 호출 할 때 dis 문제가 나타나는 것처럼 어댑터의 getView 메소드에서 초기화중인 스레드에 이미지를로드하고있는 것으로 생각됩니다.
이것은 내가 꿰매고, 사람들이 구현 한 다음 유사한 문제에 부딪히는 공통점이 있습니다.
코드에서 이런 일이 발생하면 getView가 호출 된 모든 목록 행에 대한 스레드 생성으로 이어 지므로 다시 확인해야합니다.

0

사실이 프로젝트에 목록보기에 게으른로드 작업을 수행하는 방법의 아주 좋은 예가 : Android Lazy Loading ListView.

관련 문제