Ошибка памяти при загрузке растровых изображений

У меня есть приложение для Android с 3 ацитивами:

A1 - старты → A2 - старты → A3 - после завершения его процесса: начинается → A1

(поэтому я не "заканчиваю" (); "приложение запускает следующие действия с" startActivity (..); "все время после пользовательского взаимодействия)

поэтому в этих трех действиях есть цикл. В каждой операции я показываю 3-9 изображений, расположенных на SD-карте, которую я загружаю с помощью следующей функции:

try
{
 Uri selectedImageURI = Uri.parse(strImagePath);
 File imgFile = new File(getRealPathFromURI(selectedImageURI, c));
 Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
 ivTmp.setImageBitmap(myBitmap);
}catch (Exception e)
{
 return null;
}

Все это работает. Но иногда (после нескольких циклов по моей активности) мое приложение вылетает.

Logcat сообщает мне:

01-16 13:42:15.863: DEBUG/dalvikvm(23161): GC_BEFORE_OOM freed 10K, 9% free 59019K/64400K, paused 29ms, total 30ms
01-16 13:42:15.863: ERROR/dalvikvm-heap(23161): Out of memory on a 8018704-byte allocation.
01-16 13:42:15.863: ERROR/AndroidRuntime(23161): FATAL EXCEPTION: main
 java.lang.OutOfMemoryError
 at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
 at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:502)
 at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:355)
 at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:785)
 at android.content.res.Resources.loadDrawable(Resources.java:1965)
 at android.content.res.Resources.getDrawable(Resources.java:660)
 at android.widget.ImageView.resolveUri(ImageView.java:616)
 at android.widget.ImageView.setImageResource(ImageView.java:349)
 at <myapp>.MyActivity$6.run(MyActivity.java:143)
 at android.os.Handler.handleCallback(Handler.java:725)
 at android.os.Handler.dispatchMessage(Handler.java:92)
 at android.os.Looper.loop(Looper.java:137)
 at android.app.ActivityThread.main(ActivityThread.java:5039)
 at java.lang.reflect.Method.invokeNative(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:511)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
 at dalvik.system.NativeStart.main(Native Method)
</myapp>

Кто-то может дать мне несколько советов, как справляться с авариями? Может быть, потому, что мои действия настроены на состояние "приостановлено", а не закрывать их правильно?

4 ответа

для быстрого исправления вы можете добавить

android:largeHeap="true" в вашем теге приложения манифеста

ссылка здесь:

Я столкнулся с проблемой OOM для моей таблицы в разжечь и закоулки

Heap size (large)
android:largeHeap="true"

указанная спецификация упоминается для использования более крупной кучи здесь:

изменить: использовать метод кэширования битмапов ссылка здесь


У меня была аналогичная проблема при отображении изображений с высоким разрешением. Я искал и применял все растровые решения андроида, приведенные в http://developer.android.com/training/displaying-bitmaps/index.html, а также следующие метаданные кешей в ссылке. но никто из них не работает. не любое правильное решение в любом месте. Затем я понял, что проблема в том, что я не мог правильно использовать структуру выпадающих папок. Я сохранял изображения с высоким разрешением в папках mdpi и hdpi. эта причина андроида увеличивает изображения до ультра размеров. Изображение размером 100 кб вызывало увеличение памяти на 20 мб благодаря блоку/монитору памяти. поэтому я добавил эти изображения с ультраразрешением в папку xxhdpi, затем он был FIXED неожиданно. то слайдер изображения работает безупречно


Да, андроид не сразу уничтожает действия, когда они не видны пользователю, но существует ряд методов жизненного цикла, которые вызываются в зависимости от текущего состояния. Проверьте http://developer.android.com/guide/components/activities.html#Lifecycle

Вы можете попробовать завершить операции в onStop() или onDestroy(), поскольку они будут вызываться, когда активность не будет видна и когда система будет работать с низкой памятью соответственно.: -)


Это связано с высоким разрешением изображения, которое вы должны масштабировать растровым изображением, используя следующий код

Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
 int h = 100; // height in pixels
 int w = 100; // width in pixels
Bitmap photoBitMap = Bitmap.createScaledBitmap(myBitmap,h, w, true);
ivTmp.setImageBitmap(photoBitMap);

licensed under cc by-sa 3.0 with attribution.