如何解决延迟加载的位图的VM预算内存堆错误? [英] How to solve the vm budget memory heap error in lazy loading bitmaps?
问题描述
我一直在使用图像加载器类延迟加载列表视图中。它工作正常,但我一直在处理大量位图将被从Web服务下载。所以现在我得到的位图的大小超过VM预算。增加bitmapfactory尺寸为32 * 1024,但如果它再次达到32MB就会抛出一个错误。它被打破我的头在过去的一个星期。所以有人请帮我出这个问题。我在这里通过张贴我的图像加载类以及请让我知道,我应该怎么解决这个问题。
公共类ImageLoader的{
私人的HashMap<字符串,位图>缓存=新的HashMap<字符串,位图>();
点阵位图= NULL;
私人活动的活动;
PhotosLoader photoLoaderThread =新PhotosLoader();
公共ImageLoader的(活动活动){
this.activity =活动;
photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);
清除缓存();
}
公共无效DisplayImage(字符串URL,活动活动,ImageView的ImageView的,的String [] IMAGEURL){
this.activity =活动;
如果(cache.containsKey(URL)){
imageView.setImageBitmap(cache.get(URL));
}
其他{
imageView.setImageResource(R.drawable.icon);
queuePhoto(URL,活动,ImageView的);
}
}
私人无效queuePhoto(字符串URL,活动活动,ImageView的ImageView的){
this.activity =活动;
photosQueue.Clean(ImageView的);
PhotoToLoad P =新PhotoToLoad(URL,ImageView的);
同步(photosQueue.photosToLoad){
photosQueue.photosToLoad.push(对);
photosQueue.photosToLoad.notifyAll();
}
如果(photoLoaderThread.getState()== Thread.State.NEW)
photoLoaderThread.start();
}
公共位图getBitmap(字符串URL,诠释的采样大小)抛出异常{
位图BM = NULL;
尝试 {
URL请求=新的网址(URL);
InputStream的是=(的InputStream)request.getContent();
BitmapFactory.Options选项=新BitmapFactory.Options();
options.inDither = TRUE;
options.inPurgeable = TRUE;
options.inInputShareable = TRUE;
options.inSampleSize =采样大小;
options.inTempStorage =新的字节[32 * 1024];
BM = BitmapFactory.de codeStream(是,空,期权);
如果(BM!= NULL)
BM = Bitmap.createScaledBitmap(BM,115 100,真正的);
is.close();
是=无效;
}赶上(IOException异常E){
抛出新的异常();
}赶上(OutOfMemoryError异常E){
bm.recycle();
BM = NULL;
System.gc()的;
抛出新的异常();
}
返回BM;
}
私有类PhotoToLoad {
公共字符串URL;
公众的ImageView ImageView的;
公共PhotoToLoad(字符串U,ImageView的我){
URL = U;
ImageView的=我;
}
}
PhotosQueue photosQueue =新PhotosQueue();
公共无效stopThread(){
photoLoaderThread.interrupt();
}
静态类PhotosQueue {
私人堆叠式和LT; PhotoToLoad> photosToLoad =新的堆栈< PhotoToLoad>();
公共无效清洁(ImageView的图像){
对于(INT J = 0; J< photosToLoad.size()){
尝试{
如果(photosToLoad.get(J).imageView ==图片)
photosToLoad.remove(J);
其他
+ D];
}赶上(例外五){
}
}
}
}
类PhotosLoader继承Thread {
公共无效的run(){
尝试 {
而(真){
如果(photosQueue.photosToLoad.size()== 0)
同步(photosQueue.photosToLoad){
photosQueue.photosToLoad.wait();
}
如果(photosQueue.photosToLoad.size()!= 0){
PhotoToLoad photoToLoad;
同步(photosQueue.photosToLoad){
photoToLoad = photosQueue.photosToLoad.pop();
}
BMP位= NULL;
BMP = getBitmap(photoToLoad.url,1);
cache.put(photoToLoad.url,BMP);
如果(((字符串)photoToLoad.imageView.getTag())。等于(photoToLoad.url)){
BitmapDisplayer BD =新BitmapDisplayer(BMP,photoToLoad.imageView);
活动一=(活动)photoToLoad.imageView.getContext();
a.runOnUiThread(BD);
}
}
如果(Thread.interrupted())
打破;
}
}赶上(InterruptedException异常E){
e.printStackTrace();
}赶上(例外五){
e.printStackTrace();
}
}
}
类BitmapDisplayer实现Runnable {
ImageView的ImageView的;
公共BitmapDisplayer(位图B,ImageView的我){
位= NULL;
位= B;
ImageView的=我;
}
公共无效的run(){
如果(位图!= NULL){
imageView.setImageBitmap(位);
imageView.setScaleType(ScaleType.FIT_XY);
}
其他{
imageView.setImageResource(R.drawable.icon);
}
}
}
公共无效clearCache(){
尝试{
cache.clear();
缓存=新的HashMap<字符串,位图>();
bitmap.recycle();
System.gc()的;
}赶上(例外五){
}
}
下面links..u验证可以得到的想法有关...
的http://negativeprobability.blogspot.com/2011/08/lazy-loading-of-images-in-listview.html http://stackoverflow.com/questions/5082703/android-out-of-memory-error-with-lazy-load-images HTTP://blog.jteam。 NL / 2009/09/17 /探索最世界的,Android的部分-2 / http://groups.google.com/group/android-developers/browse_thread/thread/bb3c57cab27e0d91?fwc=1
I have been using Image loader class for lazy loading in list view. It works fine but I have been dealing with lots of bitmap that will be downloaded from web service. so now I get bitmap size exceeds VM budget. Increased bitmapfactory size to be 32*1024 but if it reaches 32mb again it will throw a the error. It being breaking my head for the past one week. so some one please help me out of this problem. I here by post my image loader class as well please let me know where and how should I solve this problem.
public class ImageLoader {
private HashMap<String, Bitmap> cache=new HashMap<String, Bitmap>();
Bitmap bitmap = null;
private Activity activity;
PhotosLoader photoLoaderThread=new PhotosLoader();
public ImageLoader(Activity activity){
this.activity = activity;
photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);
clearCache();
}
public void DisplayImage(String url, Activity activity, ImageView imageView, String[] imageUrl){
this.activity = activity;
if(cache.containsKey(url)){
imageView.setImageBitmap(cache.get(url));
}
else{
imageView.setImageResource(R.drawable.icon);
queuePhoto(url, activity, imageView);
}
}
private void queuePhoto(String url, Activity activity, ImageView imageView){
this.activity = activity;
photosQueue.Clean(imageView);
PhotoToLoad p=new PhotoToLoad(url, imageView);
synchronized(photosQueue.photosToLoad){
photosQueue.photosToLoad.push(p);
photosQueue.photosToLoad.notifyAll();
}
if(photoLoaderThread.getState()==Thread.State.NEW)
photoLoaderThread.start();
}
public Bitmap getBitmap(String url, int sampleSize) throws Exception{
Bitmap bm = null;
try {
URL request = new URL(url);
InputStream is = (InputStream) request.getContent();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = true;
options.inPurgeable = true;
options.inInputShareable = true;
options.inSampleSize = sampleSize;
options.inTempStorage = new byte[32 * 1024];
bm = BitmapFactory.decodeStream(is, null, options);
if (bm!=null)
bm = Bitmap.createScaledBitmap(bm, 115,100, true);
is.close();
is = null;
} catch (IOException e) {
throw new Exception();
} catch (OutOfMemoryError e) {
bm.recycle();
bm = null;
System.gc();
throw new Exception();
}
return bm;
}
private class PhotoToLoad{
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i){
url=u;
imageView=i;
}
}
PhotosQueue photosQueue=new PhotosQueue();
public void stopThread(){
photoLoaderThread.interrupt();
}
static class PhotosQueue{
private Stack<PhotoToLoad> photosToLoad=new Stack<PhotoToLoad>();
public void Clean(ImageView image){
for(int j=0 ;j<photosToLoad.size();){
try{
if(photosToLoad.get(j).imageView==image)
photosToLoad.remove(j);
else
++j;
}catch (Exception e) {
}
}
}
}
class PhotosLoader extends Thread {
public void run() {
try {
while(true){
if(photosQueue.photosToLoad.size()==0)
synchronized(photosQueue.photosToLoad){
photosQueue.photosToLoad.wait();
}
if(photosQueue.photosToLoad.size()!=0){
PhotoToLoad photoToLoad;
synchronized(photosQueue.photosToLoad){
photoToLoad=photosQueue.photosToLoad.pop();
}
Bitmap bmp = null;
bmp = getBitmap(photoToLoad.url, 1);
cache.put(photoToLoad.url, bmp);
if(((String)photoToLoad.imageView.getTag()).equals(photoToLoad.url)){
BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView);
Activity a=(Activity)photoToLoad.imageView.getContext();
a.runOnUiThread(bd);
}
}
if(Thread.interrupted())
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class BitmapDisplayer implements Runnable{
ImageView imageView;
public BitmapDisplayer(Bitmap b, ImageView i){
bitmap = null;
bitmap=b;
imageView=i;
}
public void run(){
if(bitmap!=null){
imageView.setImageBitmap(bitmap);
imageView.setScaleType(ScaleType.FIT_XY);
}
else{
imageView.setImageResource(R.drawable.icon);
}
}
}
public void clearCache() {
try{
cache.clear();
cache = new HashMap<String, Bitmap>();
bitmap.recycle();
System.gc();
}catch (Exception e) {
}
}
verify below links..u can get idea about that...
http://negativeprobability.blogspot.com/2011/08/lazy-loading-of-images-in-listview.html http://stackoverflow.com/questions/5082703/android-out-of-memory-error-with-lazy-load-images http://blog.jteam.nl/2009/09/17/exploring-the-world-of-android-part-2/ http://groups.google.com/group/android-developers/browse_thread/thread/bb3c57cab27e0d91?fwc=1
这篇关于如何解决延迟加载的位图的VM预算内存堆错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!