Android OOM For Bitmap с захватом изображений - PullRequest
0 голосов
/ 19 февраля 2011

Последние три дня я безостановочно боролся с этой «утечкой памяти», и хотя я упростил другие части своего приложения, эта проблема осталась.

Первое, что я пытаюсь сделать. Я запускаю Намерение для IMAGE_CAPTURE с EXTRA_OUTPUT, чтобы сохранить изображение в файл. Затем я отображаю возвращенное изображение, уменьшенное до порядка 2, для пользователя, позволяя ему выбрать квадратную часть изображения. Как только он выберет его, он переместится в другое действие, которое позволит ему пометить изображение каким-нибудь текстом и тому подобным, и в конечном итоге загрузить все, используя HTTPPost, на сервер.

Прямо сейчас все отлично работает ровно один раз! Я могу пройти через это, и все работает, без каких-либо проблем. Однако, если я пытаюсь сделать еще один снимок, я всегда получаю исключение нехватки памяти. Вот Logcat в последний раз, когда это произошло

02-18 19:07:19.498: ERROR/dalvikvm-heap(6385): 1040400-byte external allocation too large for this process.
02-18 19:07:19.498: ERROR/GraphicsJNI(6385): VM won't let us allocate 1040400 bytes
02-18 19:07:19.498: DEBUG/AndroidRuntime(6385): Shutting down VM
02-18 19:07:19.498: WARN/dalvikvm(6385): threadid=1: thread exiting with uncaught exception (group=0x4001d7f0)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385): FATAL EXCEPTION: main
02-18 19:07:19.518: ERROR/AndroidRuntime(6385): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hitpost/com.hitpost.SharePicture}: android.view.InflateException: Binary XML file line #29: Error inflating class <unknown>
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.os.Looper.loop(Looper.java:123)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.app.ActivityThread.main(ActivityThread.java:4627)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at java.lang.reflect.Method.invokeNative(Native Method)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at java.lang.reflect.Method.invoke(Method.java:521)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at dalvik.system.NativeStart.main(Native Method)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385): Caused by: android.view.InflateException: Binary XML file line #29: Error inflating class <unknown>
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.view.LayoutInflater.createView(LayoutInflater.java:513)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:621)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.app.Activity.setContentView(Activity.java:1647)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at com.hitpost.SharePicture.onCreate(SharePicture.java:90)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     ... 11 more
02-18 19:07:19.518: ERROR/AndroidRuntime(6385): Caused by: java.lang.reflect.InvocationTargetException
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.widget.ImageView.<init>(ImageView.java:108)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at java.lang.reflect.Constructor.constructNative(Native Method)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.view.LayoutInflater.createView(LayoutInflater.java:500)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     ... 23 more
02-18 19:07:19.518: ERROR/AndroidRuntime(6385): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.graphics.Bitmap.nativeCreate(Native Method)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.graphics.Bitmap.createBitmap(Bitmap.java:468)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.graphics.Bitmap.createBitmap(Bitmap.java:435)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:488)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:462)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.content.res.Resources.loadDrawable(Resources.java:1709)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     at android.widget.ImageView.<init>(ImageView.java:118)
02-18 19:07:19.518: ERROR/AndroidRuntime(6385):     ... 27 more

Это ошибка на setContentView последней операции, так как в нем один раз отображается изображение для пользователя, но он почему-то не может отобразить его снова.

Буду очень признателен за помощь!

Обновлено Я тестировал эту проблему на нескольких телефонах, и единственная, где, кажется, это делает, это Nexus One с Froyo. Работает на Samsung Captivate 2.1, не вылетает в связи с этой проблемой на Moto Milestone 2.1.

Кроме того, в конце мне нужно изображение размером 500 x 500, чтобы я не мог уменьшить его в 2 раза.

Ответы [ 2 ]

2 голосов
/ 31 марта 2011

Смотрите мой ответ на BitmapFactory OOM сводит меня с ума .

Ваши растровые данные находятся в собственной куче, а не в куче виртуальной машины. Так что явная сборка мусора ВМ не будет иметь никакого эффекта.

Собственная куча собирается мусором, но реже / агрессивно. Единственный наш подход к работе -

  • контролировать собственную кучу (по ссылке выше), чтобы убедиться, что вы не включили исключение OOM
  • освобождайте растровые изображения, когда они вам не нужны (что освободит место в куче Native), выполнив (как вы делаете)

    mBitmap.recycle (); mBitmap = null;

0 голосов
/ 22 февраля 2011

Вы должны попытаться обернуть объекты Bitmap в объект SoftReference, чтобы ОС возвращала его обратно при нехватке памяти и когда ваше приложение не использует изображение в текущем действии. Также вам следует подумать об освобождении памяти, занимаемой изображением, когда ваша активность изменится, и вам следует перезагрузить изображение снова из файла, когда ваша деятельность с этим конкретным изображением возобновится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...