java.lang.OutOfMemoryError – BitmapFactory.decode(strPath)

我得到java.lang.OutOfMemoryError ,每当我调用UploadActivity.java

行号176是:

Bitmap bm = BitmapFactory.decodeFile(strPath); 

查看我的日志:

 12-07 17:57:10.585: E/AndroidRuntime(16708): FATAL EXCEPTION: main 12-07 17:57:10.585: E/AndroidRuntime(16708): java.lang.OutOfMemoryError 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:650) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:389) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:449) 12-07 17:57:10.585: E/AndroidRuntime(16708): at com.example.camera.UploadActivity$ImageAdapter.getView(UploadActivity.java:176) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.AbsListView.obtainView(AbsListView.java:2465) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.ListView.makeAndAddView(ListView.java:1775) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.ListView.fillDown(ListView.java:678) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.ListView.fillFromTop(ListView.java:739) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.ListView.layoutChildren(ListView.java:1628) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.AbsListView.onLayout(AbsListView.java:2300) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.View.layout(View.java:14063) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewGroup.layout(ViewGroup.java:4607) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.RelativeLayout.onLayout(RelativeLayout.java:948) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.View.layout(View.java:14063) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewGroup.layout(ViewGroup.java:4607) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.View.layout(View.java:14063) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewGroup.layout(ViewGroup.java:4607) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1655) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1513) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.LinearLayout.onLayout(LinearLayout.java:1426) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.View.layout(View.java:14063) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewGroup.layout(ViewGroup.java:4607) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.View.layout(View.java:14063) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewGroup.layout(ViewGroup.java:4607) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1996) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1817) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1114) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4520) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.Choreographer.doCallbacks(Choreographer.java:555) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.Choreographer.doFrame(Choreographer.java:525) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.os.Handler.handleCallback(Handler.java:615) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.os.Handler.dispatchMessage(Handler.java:92) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.os.Looper.loop(Looper.java:137) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.app.ActivityThread.main(ActivityThread.java:4921) 12-07 17:57:10.585: E/AndroidRuntime(16708): at java.lang.reflect.Method.invokeNative(Native Method) 12-07 17:57:10.585: E/AndroidRuntime(16708): at java.lang.reflect.Method.invoke(Method.java:511) 12-07 17:57:10.585: E/AndroidRuntime(16708): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1036) 12-07 17:57:10.585: E/AndroidRuntime(16708): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:803) 12-07 17:57:10.585: E/AndroidRuntime(16708): at dalvik.system.NativeStart.main(Native Method) 

UploadActivity.java:-

 public class ImageAdapter extends BaseAdapter { private Context context; public ImageAdapter(Context c) { // TODO Auto-generated method stub context = c; } public int getCount() { // TODO Auto-generated method stub return ImageList.size(); } public Object getItem(int position) { // TODO Auto-generated method stub return position; } public long getItemId(int position) { // TODO Auto-generated method stub return position; } public View getView(final int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (convertView == null) { convertView = inflater.inflate(R.layout.list_upload, null); } // ColImgName TextView txtName = (TextView) convertView.findViewById(R.id.ColImgName); strPath = ImageList.get(position).toString(); // Get File Name fileName = strPath.substring( strPath.lastIndexOf('/')+1, strPath.length() ); File file = new File(strPath); @SuppressWarnings("unused") long length = file.length(); txtName.setText(fileName); // Image Resource ImageView imageView = (ImageView) convertView.findViewById(R.id.ColImgPath); Bitmap bm = BitmapFactory.decodeFile(strPath); imageView.setImageBitmap(bm); // ColStatus final ImageView txtStatus = (ImageView) convertView.findViewById(R.id.ColStatus); txtStatus.setImageResource(R.drawable.bullet_button); // progressBar final ProgressBar progress = (ProgressBar) convertView.findViewById(R.id.progressBar); progress.setVisibility(View.GONE); //btnUpload final ImageButton btnUpload = (ImageButton) convertView.findViewById(R.id.btnUpload); btnUpload.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Upload btnUpload.setEnabled(false); startUpload(position); } }); return convertView; } } 

Solutions Collecting From Web of "java.lang.OutOfMemoryError – BitmapFactory.decode(strPath)"

您需要回收Bitmap对象。

  Bitmap bm = BitmapFactory.decodeFile(strPath); imageView.setImageBitmap(bm); 

在你的get view中的上面几行代码只是添加下面写的代码///现在回收你的位图,这将在每次迭代时释放你的内存

  if(bm!=null) { bm.recycle(); bm=null; } 

在此之后,如果你得到相同的错误

replace下面的代码

  Bitmap bm = BitmapFactory.decodeFile(strPath); imageView.setImageBitmap(bm); 

  final BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 8; Bitmap bm = BitmapFactory.decodeFile(strPath,options); imageView.setImageBitmap(bm); 

使用inSampleSize将位图加载到内存。 对inSampleSize值使用2的幂值对于解码器来说更快且更高效。 但是,如果您计划在内存或磁盘上caching已resize的版本,通常仍然值得解码到最合适的图像尺寸以节省空间。

有关更多信息,请参阅高效加载大型位图

在调用位图之前bm = BitmapFactory.decodeFile(strPath);

调用这个..位图bm = decodeSampledBitmapFromResource(strPath,reqWidth,reqHeight);

如果你再次得到java.lang.OutOfMemoryError,那么让我知道

 public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and // keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; } public static Bitmap decodeSampledBitmapFromResource(String strPath,int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(strPath, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options,reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(strPath, options);; } 

在应用程序标签中的清单文件中使用这个

 android:largeHeap="true" 

这是您的应用程序的优化问题。 你得到OutOfMemoryError是因为当你在做BitmapFactory.decodeFile(strPath)的时候,android正在尝试为那个位图分配内存。 在你的情况下系统找不到足够的可用空间来分配,这就是为什么你得到这个错误。

现在,我可以从您的代码中看到,您正试图使用​​ImageAdapter显示图像列表。 在这种情况下,您的imageview必须比实际图像的宽度和高度更小。

为了给你一个更普遍的想法,这里发生了什么事情:

  • ImageView宽度*高度= 100dp * 100dp
  • 图片宽度*高度= 800px * 800px。

在这种情况下,尽pipe我们的imageview width-height是100 * 100,但是我们试图设置800 * 800的图像作为背景。 而这绝对不是一个有效的方式,因为系统将分配800×800像素的内存,而100 * 100会做。

这就是为什么在对位图进行任何解码之前,应该对位图进行采样,以便只分配100 * 100的内存。

你会在这里find这个解释的更详细的版本

我有同样的问题。 我收集了所有上述build议,但我仍然有java.lang.outOfMemoryError的问题。 经过很多的调整,最终的工作是缩小图像尺寸(和大小)。 最初,我有800×1000种尺寸的图像。 我将它们重新调整到大约60 x 80(因为这就是我所需要的),而且它起作用了!

所以,除了遵循关于这个问题的所有关于计算器和其他网站的build议之外,还要对您的图像大小和尺寸进行基层检查。 会节省你很多头痛。