我想显示的位图图像在ImageView从sd卡已经存储。运行后,我的应用程序是崩溃和得到OutOfMemoryError错误:

(. lang。OutOfMemoryError:未能分配23970828字节分配,2097152空闲字节和2MB直到OOM)

我不知道为什么它没有记忆。我觉得我的图片太大了,所以我试着改变它。

Iterator<String> it = imageArray.iterator();
while (it.hasNext()) {
  Object element = it.next();
  String objElement = element.toString();
  Log.e("objElement ", " = " + objElement);
  final ImageView imageView = new ImageView (getContext());
  final ProgressBar pBar = new ProgressBar(getContext(), null, 
                                           android.R.attr.progressBarStyleSmall);
  imageView.setTag(it);
  pBar.setTag(it);

  imageView.setImageResource(R.drawable.img_placeholder);
  pBar.setVisibility(View.VISIBLE);

  if (objElement.endsWith(mp3_Pattern)) {
     Log.e("Mp3 ", " ends with ");
     pBar.setVisibility(View.GONE);
     imageView.setImageResource(R.drawable.audio_control);
  }
  if (objElement.endsWith(png_Pattern)) {
     Bitmap bitmap = BitmapFactory.decodeFile(objElement);
     int size = Math.min(bitmap.getWidth(), bitmap.getHeight());
     int x = (bitmap.getWidth() - size) / 2;
     int y = (bitmap.getHeight() - size) / 2;
     Bitmap bitmap_Resul = Bitmap.createBitmap(bitmap, x, y, size, size);
     Log.e("bitmap_Resul "," = "+ bitmap_Resul);

     if (bitmap_Resul != bitmap) {
        bitmap.recycle();
     }
     imageView.setImageBitmap(bitmap_Resul);
     Log.e("png_Pattern ", " ends with ");
     Log.e(" bitmap "," = " + bitmap);
  }

  holder.linearLayout.addView(imageView);
  holder.linearLayout.addView(pBar);

日志猫信息:

08-27 14:11:15.307    1857-1857/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.tazeen.classnkk, PID: 1857
    java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM
            at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
            at android.graphics.Bitmap.nativeCreate(Native Method)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:812)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:789)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:709)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:634)
            at com.example.tazeen.classnkk.AllPosts_Page$MyListAdapter.getView(AllPosts_Page.java:357)
            at android.widget.AbsListView.obtainView(AbsListView.java:2347)
            at android.widget.ListView.makeAndAddView(ListView.java:1864)
            at android.widget.ListView.fillDown(ListView.java:698)
            at android.widget.ListView.fillFromTop(ListView.java:759)
            at android.widget.ListView.layoutChildren(ListView.java:1659)
            at android.widget.AbsListView.onLayout(AbsListView.java:2151)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2086)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1843)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
            at android.view.Choreographer.doCallbacks(Choreographer.java:580)
            at android.view.Choreographer.doFrame(Choreographer.java:550)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

当前回答

使用滑动库和覆盖大小,以减少大小;

Glide.with(mContext).load(imgID).asBitmap().override(1080, 600).into(mImageView);

其他回答

试试最简单的。也许你的应用程序崩溃是因为你的图像大小(以MB为单位)太大了,所以它没有为它分配空间。所以在粘贴你的图像在drawable之前,只要减少大小的任何查看器软件,或者如果你是从图库在运行时比保存它压缩你的位图。 这对我很管用。你一定会的。

我遇到了这个问题,当我移动到一个新的活动时,我没有杀死我的旧活动。我用finish()修复了它;

    Intent goToMain = new Intent(this,MainActivity.class);
    startActivity(goToMain);
    finish();

I have found that images in the 'drawable' folder will get converted to a much larger image on high def phones. For example, a 200k image will be resampled to a higher res, like 800k or 32000k. I had to discover this on my own and to date have not seen documentation for this heap memory trap. To prevent this I put everything in a drawable-nodpi folder (in addition to using 'options' in BitmapFactory based on the particular device heap). I can't afford to have the size of my app bloated with multiple drawable folders, particularly as the range of screen defs is so vast now. The tricky thing is studio now doesn't specifically indicate the 'drawable-nodpi' folder as such in the project view, it just shows a 'drawable' folder. If you're not careful, when you drop an image to this folder in studio, it won't actually get dropped into the drawable-nodpi:

Careful here 'backgroundtest' did not actually go to drawable-nodpi and will 
be resampled higher, such as 4x or 16x of the original dimensions for high def screens.

一定要单击对话框中的nodpi文件夹,因为项目视图不会像以前那样分别显示所有可绘制的文件夹,所以不会立即显示到错误的文件夹。在我很久以前删除了它之后,Studio在某个时候为我重新创建了香草“可绘制”:

我真的不建议像这样编辑清单

android:hardwareAccelerated=“错误”,android:largeHeap=“真实”

这些选项会导致应用程序的动画效果不流畅。此外,“liveData”或更改本地DB(Sqlite, Room)激活缓慢。这不利于用户体验。

所以我推荐RESIZE位图

下面是示例代码

fun resizeBitmap(source: Bitmap): Bitmap {
      val maxResolution = 1000    //edit 'maxResolution' to fit your need
      val width = source.width
      val height = source.height
      var newWidth = width
      var newHeight = height
      val rate: Float

            if (width > height) {
                if (maxResolution < width) {
                    rate = maxResolution / width.toFloat()
                    newHeight = (height * rate).toInt()
                    newWidth = maxResolution
                }
            } else {
                if (maxResolution < height) {
                    rate = maxResolution / height.toFloat()
                    newWidth = (width * rate).toInt()
                    newHeight = maxResolution
                }
            }
            return Bitmap.createScaledBitmap(source, newWidth, newHeight, true)
 }

如果上传图片,请尝试降低图片质量,这是位图的第二个参数。这就是我案例中的解。以前是90,然后我尝试了60(正如下面的代码所示)。

Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
finalBitmap.compress(Bitmap.CompressFormat.JPEG,60,baos);
byte[] b = baos.toByteArray();