图像出现内存不足错误

我在listview中显示图像并出现内存错误任何人都指导我这个问题的解决方案是我的代码

logcat的

ERROR/AndroidRuntime(1010): java.lang.OutOfMemoryError: bitmap size exceeds VM budget ERROR/AndroidRuntime(1010): at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method) ERROR/AndroidRuntime(1010): at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:405) ERROR/AndroidRuntime(1010): at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:418) ERROR/AndroidRuntime(1010): at com.Adapters.AdapterTours.getView(AdapterTours.java:73) ERROR/AndroidRuntime(1010): at android.widget.AbsListView.obtainView(AbsListView.java:1409) ERROR/AndroidRuntime(1010): at android.widget.ListView.makeAndAddView(ListView.java:1745) ERROR/AndroidRuntime(1010): at android.widget.ListView.fillUp(ListView.java:700) ERROR/AndroidRuntime(1010): at android.widget.ListView.fillGap(ListView.java:646) ERROR/AndroidRuntime(1010): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:3399) ERROR/AndroidRuntime(1010): at android.widget.AbsListView.onTouchEvent(AbsListView.java:2233) ERROR/AndroidRuntime(1010): at android.widget.ListView.onTouchEvent(ListView.java:3446) ERROR/AndroidRuntime(1010): at android.view.View.dispatchTouchEvent(View.java:3885) ERROR/AndroidRuntime(1010): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903) ERROR/AndroidRuntime(1010): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942) ERROR/AndroidRuntime(1010): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942) ERROR/AndroidRuntime(1010): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942) ERROR/AndroidRuntime(1010): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942) ERROR/AndroidRuntime(1010): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1691) ERROR/AndroidRuntime(1010): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1125) ERROR/AndroidRuntime(1010): at android.app.Activity.dispatchTouchEvent(Activity.java:2096) ERROR/AndroidRuntime(1010): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675) ERROR/AndroidRuntime(1010): at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2194) ERROR/AndroidRuntime(1010): at android.view.ViewRoot.handleMessage(ViewRoot.java:1878) ERROR/AndroidRuntime(1010): at android.os.Handler.dispatchMessage(Handler.java:99) ERROR/AndroidRuntime(1010): at android.os.Looper.loop(Looper.java:130) ERROR/AndroidRuntime(1010): at android.app.ActivityThread.main(ActivityThread.java:3683) ERROR/AndroidRuntime(1010): at java.lang.reflect.Method.invokeNative(Native Method) ERROR/AndroidRuntime(1010): at java.lang.reflect.Method.invoke(Method.java:507) ERROR/AndroidRuntime(1010): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) ERROR/AndroidRuntime(1010): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) ERROR/AndroidRuntime(1010): at dalvik.system.NativeStart.main(Native Method) 

GetView方法

 public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.list_tours, null); holder = new ViewHolder(); holder.tourTitle = (TextView) convertView.findViewById(R.id.tourTitle); holder.tourIcon = (ImageView) convertView.findViewById(R.id.tourIcon); holder.tourDetail = (TextView) convertView.findViewById(R.id.tourDetail); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } DalTours tour = getItem(position); String tempTag = String.valueOf(tour.getId()); holder.tourIcon.setTag(tempTag); if(tour.getImageByteArray() != null) { Bitmap image = BitmapFactory.decodeByteArray(tour.getImageByteArray(), 0, tour.getImageByteArray().length); holder.tourIcon.setImageDrawable(getScaledImage(image)); image = null; }else { holder.tourIcon.setTag(tour); Bitmap cachedImage = ImageLoader.loadBitmap(tour,new ImageLoader.ImageCallback() { @Override public void imageLoaded(Bitmap imageBitmap, DalTours tour) { ImageView image = (ImageView)listview.findViewWithTag(tour); if(image != null) { try { ByteArrayOutputStream stream = new ByteArrayOutputStream(); if(imageBitmap != null) { image.setImageDrawable(getScaledImage(imageBitmap)); imageBitmap.compress(CompressFormat.PNG, 0 ,stream); byte[] bitmapdata = stream.toByteArray(); tours.get(position).setImageByteArray(bitmapdata); } stream = null; }finally { } } } }); holder.tourIcon.setImageDrawable(getScaledImage(cachedImage)); } holder.tourTitle.setText(tours.get(position).getTitle()); holder.tourDetail.setText(tours.get(position).getDetail()); return convertView; } 

图像缩放function

  public Drawable getScaledImage(Bitmap actualBitmap) { BitmapDrawable bmd= null; if(actualBitmap != null) { int width = actualBitmap.getWidth(); int height = actualBitmap.getHeight(); Activity parent = (Activity)context; Display display = parent.getWindowManager().getDefaultDisplay(); int Screenwidth = display.getWidth(); int Screenheight = display.getHeight(); float newWidth = (Screenwidth*35)/100; float temp = newWidth / width; float newHeight = temp * height; float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); Bitmap resizedBitmap = Bitmap.createBitmap(actualBitmap, 0, 0, width, height, matrix, true); bmd = new BitmapDrawable(resizedBitmap); } return bmd; } 

图像加载器类

 public class ImageLoader { private static HashMap<String, SoftReference> imageCache; public ImageLoader() { //imageCache = new HashMap<String, SoftReference>(); } public static Bitmap loadBitmap(final DalTours tour, final ImageCallback imageCallback) { if(imageCache == null) imageCache = new HashMap<String, SoftReference>(); if (imageCache.containsKey(tour.getImageurl())) { SoftReference softReference = imageCache.get(tour.getImageurl()); Bitmap Bitmap = softReference.get(); if (Bitmap != null) { return Bitmap; } } final Handler handler = new Handler() { @Override public void handleMessage(Message message) { imageCallback.imageLoaded((Bitmap) message.obj, tour); } }; new Thread() { @Override public void run() { Bitmap Bitmap = loadImageFromUrl(tour.getImageurl()); imageCache.put(tour.getImageurl(), new SoftReference(Bitmap)); Message message = handler.obtainMessage(0, Bitmap); handler.sendMessage(message); } }.start(); return null; } public static Bitmap loadImageFromUrl(String url) { Bitmap bm; try { URL aURL = new URL(url); URLConnection conn = aURL.openConnection(); conn.connect(); InputStream is = null; try { is= conn.getInputStream(); }catch(IOException e) { return null; } BufferedInputStream bis = new BufferedInputStream(is); bm = BitmapFactory.decodeStream(bis); bis.close(); is.close(); } catch (IOException e) { return null; } return bm; } public interface ImageCallback { public void imageLoaded(Bitmap imageBitmap, DalTours tour); } } 

任何帮助都会受到赞赏

要解决android.graphics.BitmapFactory.nativeDecodeByteArray中的java.lang.OutOfMemoryErrorexception,您应该使用以下代码:

 BitmapFactory.Options options=new BitmapFactory.Options();// Create object of bitmapfactory's option method for further option use options.inPurgeable = true; // inPurgeable is used to free up memory while required Bitmap songImage1 = BitmapFactory.decodeByteArray(thumbnail,0, thumbnail.length,options);//Decode image, "thumbnail" is the object of image file Bitmap songImage = Bitmap.createScaledBitmap(songImage1, 50 , 50 , true);// convert decoded bitmap into well scalled Bitmap format. imageview.SetImageDrawable(songImage); 

最后我解决了这个高分辨率图像问题,使用以下线程大image processing导致内存不足错误

这是我的代码,用于根据您所需的大小下载和缩放图像。

不再需要自定义缩放function!

 public static Bitmap loadImageFromUrl(String url) { Bitmap bm; try { URL aURL = new URL(url); URLConnection conn = aURL.openConnection(); conn.connect(); InputStream is = null; try { is= conn.getInputStream(); }catch(IOException e) { return null; } BufferedInputStream bis = new BufferedInputStream(is); bm = BitmapFactory.decodeStream(bis); bis.close(); is.close(); } catch (IOException e) { return null; } return Bitmap.createScaledBitmap(bm,100,100,true); } 

你必须recycle位图。 位图实现是本机的,因此java对象很小并且是垃圾收集的不良候选者,但仍然分配了内存。 塔卡一看Bitmap.recycle()

绝对是在内存中为大图像提供位图的情况。 如果您反复执行此操作,那么每次都可以回收位图。 但是,只是回收并不能保证内存被释放,它几乎没有标记为垃圾回收。 所以,作为一个额外的步骤,你也应该处理垃圾收集。

使用此代码;

 Bitmap mybitmap = ....; // you are getting the bitmap here mybitmap.recycle(); System.gc(); // the above recycling may not be enough always