Как понять профиль Android SDK traceview ...? - PullRequest
2 голосов
/ 20 января 2012

У меня есть код, который использует Jsoup для получения и анализа некоторых html-страниц, а затем я манипулирую html-деревом, прежде чем передать его в WebView, который его рисует.Если я игнорирую свои манипуляции, код запускается в приемлемое время (2-3 секунды) на симуляторе Android SDK, но когда я выполняю свои манипуляции, время переходит на недопустимое (~ 60 секунд, чтобы просто загрузить одну страницу!).

Использование Eclipse и Android SDK у меня был профилированный прогон, и теперь я пытаюсь интерпретировать результаты.отсюда http://android -developers.blogspot.com / 2010/10 / traceview-war-story.html взял подсказку для сортировки профиля по «эксклюзивному времени ЦП%».К моему удивлению, мой собственный код даже не показывал 1%.Самый большой потребитель времени - android.view.ViewGroup.drawChild () в 11.9%.Первая не-андроидная функция в списке (отсортированная по эксклюзивному процессору%) - это java.lang.ref.Reference.get (), и она имеет 0,4%.

Но я думаю, что самая странная вещь - это моясобственный код, я могу только найти doInBackground () моего AsyncTask в списке;функции, которые он вызывает в свою очередь, даже не представлены, хотя по выводу отладки я вижу, что они вызываются.Почему их нет в списке?

Я не понимаю, что с этим делать.Любые намеки очень ценятся.

1 Ответ

2 голосов
/ 08 января 2013

Хотя у меня нет ссылки под рукой, я думаю, можно с уверенностью предположить, что Android выполняет AsyncTask.doInBackground () в потоке с приоритетом android.os.Process.THREAD_PRIORITY_BACKGROUND

Это означает, что этоПоток запланирован в контексте Linux cgroup (класс планирования), для которого - всегда или при частых обстоятельствах, я не уверен и прочитал различные утверждения - верхняя граница общего времени ЦП 5% или 10% -- опять же, разные источники предъявляют разные требования - применяется.

Другими словами, все фоновые потоки должны делить 5% или 10% доступного процессорного времени.Опять же, я прочитал утверждения о том, что это динамически корректируется, если задачи переднего плана и реального времени бездействуют, но я был бы рад указать на надежный источник сам.Кроме того, я бы не стал рассчитывать на это, поскольку пользователь может прослушивать аудиопоток в реальном времени при использовании моего приложения.

Если вы отрегулируете приоритет фонового потока, например, так:

private static final int bgThreadPrio = Process.THREAD_PRIORITY_BACKGROUND +
                                        Process.THREAD_PRIORITY_MORE_FAVORABLE;
protected YourReturnType doInBackground() {
    Process.setThreadPriority(bgThreadPrio);
    ....
}

тогда вы достигнете двух вещей.

  • Вы поднимаете поток из фоновой группы, чтобы ему не приходилось делить 10% процессорного времени с другими фоновыми потоками (по крайней мере, в настоящее время, пока Android)изменяет свою политику в этом отношении.)
  • Вы назначаете приоритет Потоку, который обычно не будет иметь крайне плохого влияния на пользовательский интерфейс и потоки реального времени, поскольку THREAD_PRIORITY_DEFAULT равен 0, а THREAD_PRIORITY_BACKGROUND равен 10. Итак, ваш потокбудет работать с приоритетом 9, что намного хуже 0, но это позволит избежать искусственного ограничения фоновых задач.

Однако вы, вероятно, также измените приоритет потока, который обеспечивает базовый исполнитель AsyncTaskваш AsyncTask.Этот поток будет переработан, и он может быть одним потоком или выбранным из пула.Поэтому было бы неплохо установить приоритет во всех методах doInBackground () во всех AsyncTasks в вашем приложении.

...