[android] Android : java.lang.OutOfMemoryError : 2097152 여유 바이트와 OOM까지 2MB로 23970828 바이트 할당을 할당하지 못했습니다.

이미 저장된 SD 카드의 ImageView에 비트 맵 이미지 를 표시하고 싶습니다 . 실행 후 내 응용 프로그램이 중단되고 다음의 OutOfMemoryError 오류가 발생합니다.

(java.lang.OutOfMemoryError : 사용 가능한 바이트가 2097152이고 OOM까지 2MB 인 23970828 바이트 할당에 실패했습니다)

나는 왜 메모리가 부족한지 전혀 모른다. 이미지 크기가 매우 커서 이미지를 변경하려고했습니다.

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)



답변

OutOfMemoryError 는 특히 비트 맵을 처리하는 동안 안드로이드에서 발생하는 가장 일반적인 문제입니다. 이 오류는 메모리 공간 부족으로 인해 오브젝트를 할당 할 수없고 가비지 콜렉터가 일부 공간을 확보 할 수없는 경우 JVM (Java Virtual Machine)에서 발생합니다.

알렉세이에서 언급 한 바와 같이, 당신은 당신의 매니페스트 파일에서 개체 아래에 추가 할 수 있습니다 android:hardwareAccelerated="false", android:largeHeap="true"그것은 어떤 환경에서의 작동합니다.

<application
    android:allowBackup="true"
    android:hardwareAccelerated="false"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

비트 맵을 효율적으로 표시 하려면 여기에서 Android 개발자 개념 중 일부를 명확하게 읽어야합니다.

5 가지 주제를 모두 읽고 코드를 다시 작성하십시오. 그래도 문제가 해결되지 않으면 튜토리얼 자료에서 잘못된 점을 확인하게되어 기쁩니다.

SOF에서 이러한 유형의 오류에 대한 가능한 답변은 다음과 같습니다.

Android : 사용 가능한 힙이 2MB 인 400KB 파일의 메모리 부족 BitmapFactory.decodeStream ()

안드로이드에서 java.lang.OutOfMemoryError 문제를 해결하는 방법

안드로이드 : java.lang.OutOfMemoryError

java.lang.OutOfMemoryError

OutOfMemoryError에 대한 솔루션 : 비트 맵 크기가 VM 예산을 초과합니다

편집 : @cjnash의 의견에서

이 줄을 추가 한 후에도 여전히 충돌이 발생한 사람은 이미지를 res / drawable / 대신 res / drawable-xhdpi / 폴더에 붙여 넣으면 문제가 해결 될 수 있습니다.


답변

응용 프로그램에서 매니페스트에 이것을 추가하려고 했습니까? android:largeHeap="true"?

이처럼

  <application
      android:name=".ParaseApplication"
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme"
      android:largeHeap="true" >


답변

나에게 문제는 이미지의 크기가 매우 크기 때문에 (파일 크기는 작지만) 내 .png 파일이 메모리에서 매우 큰 비트 맵으로 압축 해제되었다는 것입니다.

그래서 수정은 단순히 이미지 크기를 조정하는 것이 었습니다. 🙂


답변

사실 당신은 당신의 매니페스트이 라인에 추가 할 수 있습니다 android:hardwareAccelerated="false", android:largeHeap="true"그것은 어떤 상황에서 근무하지만, 코드의 다른 부분이 함께 주장 할 수 있음을 유의하십시오.

<application
    android:allowBackup="true"
    android:hardwareAccelerated="false"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">


답변

이 작동합니다

 BitmapFactory.Options options = new BitmapFactory.Options();
 options.inSampleSize = 8;

 mBitmapSampled = BitmapFactory.decodeFile(mCurrentPhotoPath,options);


답변

다음과 같이 ImageView로 설정하기 전에 이미지 크기를 조정 하십시오.

Bitmap.createScaledBitmap(_yourImageBitmap, _size, _size, false);

여기서 size는 ImageView의 실제 크기입니다. 다음을 측정하여 크기에 도달 할 수 있습니다.

imageView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

다음 크기 imageView.getMeasuredWidth()imageView.getMeasuredHeight()를 사용하십시오 scaling.


답변

글라이드 라이브러리 및 크기 무시를 사용 하여 크기를 줄입니다.

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