이미 저장된 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
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);