Как решить java.ленг.OutOfMemoryError проблемы в Android
Altough у меня очень маленький размер изображения в папке drawable, я получаю эту ошибку от пользователей. И я не использую функцию bitmap в коде. По крайней мере, намеренно :)
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:683)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:513)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:889)
at android.content.res.Resources.loadDrawable(Resources.java:3436)
at android.content.res.Resources.getDrawable(Resources.java:1909)
at android.view.View.setBackgroundResource(View.java:16251)
at com.autkusoytas.bilbakalim.SoruEkrani.cevapSecimi(SoruEkrani.java:666)
at com.autkusoytas.bilbakalim.SoruEkrani.run(SoruEkrani.java:862)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5602)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
в соответствии с этим stackTrace я получаю эту ошибку в этой строке ('tv' - это textView):
tv.setBackgroundResource(R.drawable.yanlis);
в чем проблема? Если вам нужна другая информация о коде, я могу добавить его. Спасибо!
4 ответов
вы не можете увеличить размер кучи динамически, но вы можете запросить использовать больше, используя.
android: largeHeap= "true"
на manifest.xml
, вы можете добавить в свой манифест эти строки, он работает для некоторых ситуаций.
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
следует ли создавать процессы вашего приложения с большой кучей Dalvik. Это относится ко всем процессам, созданным для приложения. Это относится только к первому приложению загружается в процесс; если вы используете общий идентификатор пользователя, чтобы разрешить нескольким приложениям использовать процесс, все они должны использовать этот параметр последовательно, иначе они будут иметь непредсказуемые результаты. Большинство приложений не должны нуждаться в этом и вместо этого должны сосредоточиться на сокращении общего использования памяти для повышения производительности. Включение этого параметра также не гарантирует фиксированного увеличения объема доступной памяти, поскольку некоторые устройства ограничены общим объемом доступной памяти память.
запрос доступный размер памяти во время выполнения, используйте методы getMemoryClass()
или getLargeMemoryClass()
.
если все еще сталкивается с проблемой, то это также должно работать
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
mBitmapInsurance = BitmapFactory.decodeFile(mCurrentPhotoPath,options);
это оптимальное использование BitmapFactory.Опции.inSampleSize относительно скорости отображения изображение. В документации упоминается использование значений, которые имеют мощность 2, поэтому я работаю с 2, 4, 8, 16 и т. д.
позволяет получить более глубокую выборку изображений:
например, не стоит загружать пиксельное изображение 1024x768 в память, если оно в конечном итоге будет отображаться в миниатюре 128x128 пикселей в ImageView
.
чтобы сообщить декодеру о подмножестве изображения, загрузив меньшую версию в память, установите inSampleSize
to true
в своем
вы должны реализовать менеджер кэша LRU при работе с bitmap
http://developer.android.com/reference/android/util/LruCache.html http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html когда я должен сдать рисунок с помощью LRUCache?
или
используйте библиотеку уровней, например Universal Image Loader :
https://github.com/nostra13/Android-Universal-Image-Loader
EDIT:
теперь при работе с изображениями и большую часть времени с растровым изображением я использую Glide, который позволяет настроить модуль Glide и LRUCache
Я вижу только два варианта:
- у вас есть утечки памяти в вашем приложении.
- устройства не хватает памяти при запуске приложения.
несколько подсказок для обработки такой ошибки / исключения для приложений Android:
-
действия и приложения имеют такие методы, как:
- onLowMemory
- onTrimMemory Обработайте эти методы, чтобы наблюдать за использованием памяти.
тег в Манифесте может иметь атрибут 'largeHeap' равным TRUE, который запрашивает больше кучи для песочницы приложений.
-
управление кэшированием и диском в памяти кэширование:
- изображения и другие данные могли быть кэшированы в памяти во время работы приложения (локально в действиях/фрагменте и глобально); должны управляться или удаляться.
использование WeakReference, SoftReference создания экземпляра Java, в частности для файлов.
Если так много изображений, используйте правильную структуру библиотеки / данных, которая может управлять памятью, использовать samling загруженных изображений, обрабатывать кэширование диска.
обрабатывать исключение OutOfMemory
-
следуйте рекомендациям по кодированию
- утечка памяти (не все с сильной ссылкой)
-
минимизировать стек действий, например, количество действий в стеке (не держите все в контексте/activty)
- контекст имеет смысл, те данные / экземпляры, которые не требуются вне области (активность и фрагменты), держите их в соответствующем контексте вместо глобального референс-холдинга.
минимизировать использование статики, многие другие синглеты.
-
позаботьтесь о OS basic memory fundametals
- проблемы фрагментации памяти
Involk GC.Собирать() вручную, иногда, когда вы уверены, что кэширование в памяти больше не нужны.