Огромные растровые изображения, вызывающие ANR в Android - PullRequest
1 голос
/ 23 марта 2012

Вот эта вещь:

  • Я работаю с огромным растровым изображением [1024 X 1024]
  • Мне нужны данные BitMap в формате (RGB и альфа) для побитовой манипуляции; для этой манипуляции я использую нативные библиотеки
  • Активность хорошо работает с изображениями [512 X 512] ... Но когда я переключаюсь между активностями с похожей задачей, вылетает андроид со следующей трассировкой

Вопрос такой:

  • Что я делаю не так? Что должно вызвать изменение размера JiT?
  • есть ли способ загрузить огромные растровые изображения ..? если я использую кеширование приложения; это даст мне какую-то выгоду в этом случае? Если да, то какая память будет кешировать? В основном я бью по пределам памяти ... поэтому я пытаюсь обойти это ...

След:

03-22 14:21:05.240: I/dalvikvm(105): Jit: resizing JitTable from 8192 to 16384
03-22 14:21:05.730: D/dalvikvm(196): GC_EXPLICIT freed 44K, 50% free 3130K/6151K,external 5368K/6703K, paused 713ms

Обратите внимание:

  • В настоящее время я использую API 10 [нет возможности использовать API 11 или более]
  • Я бы тоже не смог использовать опцию "android: largeHeap"
  • Поскольку я использую собственную библиотеку, я превышаю ограничение в 6 МБ [встроенной памяти], хотя в моем распоряжении 32 МБ памяти ...

ОБНОВЛЕНИЕ: [ANR Trace]

Эта трассировка ANR указывает KeyDispatchingTimedOut ... но я считаю, что это не причина ... Как при нажатии на "Меню" я переключаюсь на другое действие, используя Intent .., когда это действие запускается, необходимо вычислить " Фоновое изображение "на основе" массива цветов "с использованием нативной библиотеки ... Вот что занимает много времени ... Обратите внимание, что когда операция запускается индивидуально, происходит такой же расчет ...

E/ActivityManager(105): ANR in com.uc (com.uc/.UcMain)
E/ActivityManager(105): Reason: keyDispatchingTimedOut
E/ActivityManager(105): Load: 2.31 / 1.58 / 1.48
E/ActivityManager(105): CPU usage from 29434ms to 1ms ago:
E/ActivityManager(105):   97% 1737/com.uc: 97% user + 0.1% kernel / faults: 117 minor
E/ActivityManager(105):   1.4% 73/akmd: 0% user + 1.4% kernel
E/ActivityManager(105):   0.6% 105/system_server: 0.2% user + 0.3% kernel / faults: 9 minor

1 Ответ

3 голосов
/ 23 марта 2012

ANR на самом деле не проблема памяти, это проблема с выполнением чего-либо в потоке пользовательского интерфейса («основной» в отладчике), которое занимает слишком много времени.Любая работа, которую вы выполняете в потоке пользовательского интерфейса, должна быть быстрой или запускать сторожевой таймер ANR.Длительный процесс, который вы выполняете, приводит к тому, что его нужно поместить в другой поток.

Вам нужно перенести работу, которую вы выполняете, чтобы вычислить фоновое изображение, в отдельный поток.Я бы посоветовал вам использовать подход загрузки действия с помощью только счетчика прогресса и запуска фонового потока, тогда у вас есть все, чтобы фактически отобразить пользовательский интерфейс, скрыть счетчик и показать виды, для которых вы хотите установить фоновое изображение.

Обратите внимание, что вы можете вносить изменения только в представления из потока пользовательского интерфейса, например, вызывая API View.setBackgroundDrawable(...), но вы можете создать Drawable в фоновом потоке, а затем установить его из потока пользовательского интерфейса.AsyncTask хорош для такой схемы работы.Если вы не используете AsyncTask, то вы будете использовать API Activity.runOnUiThread(...)

...