Простой TextView.setText вызывает 40% использования ЦП
Запуск моего приложения вызывает использование 40% CPU на моем телефоне:
final String position = String.format("%02d:%02d:%02d", time.getHours(), time.getMinutes(),
time.getSeconds());
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
c.mTxtPosition.setText(position);
...
Комментируя метод setText, использование CPU падает до ожидаемого уровня ~ 4%. Метод вызывается каждую секунду и обновляет ImageViews, CustomViews... без возникновения одного и того же избытка нагрузки.
Помимо использования ЦП dalvik постоянно сообщает сборку мусора около 10-1000 объектов, просто вызвав setText().
Создание такого трассировочного файла:
Debug.startMethodTracing("setText");
c.mTxtPosition.setText(position);
Debug.stopMethodTracing();
traceview перечисляет следующие методы как Top 5 своим соответствующим эксклюзивным CPU%:
- ViewParent.invalidateChildInParent(16%)
- View.requestLayout(11%)
- ViewGroup.invalidateChild(9%)
- TextView.setText(7%)
- верхнего уровня (6%)
Кто-нибудь объясняет это?
Ответы
Ответ 1
Я заметил это себе некоторое время назад, я думаю, проблема заключается в том, что каждый раз, когда вы вызываете setText, размер текстового поля может меняться, поэтому требуется, чтобы весь экран проходил через ретранслятор (дорого).
Я еще не пробовал это сам, но если ваш текстовый файл прост и может быть сделан относительно фиксированным размером, возможно, попробуйте подкласс TextView и создайте представление, которое не изменяет размер на setText, а просто рисует что бы это ни было в существующей области? Это сэкономит много времени.
Возможно, theres уже является флагом setText, который может заставить это сделать это, но я не знаю об этом, хотя я не искал внимательно.
Ответ 2
В моем случае я обновляю TextView от события касания, что вызывает много обновлений. Решение заключалось в том, чтобы изменить layout_width и layout_height TextView на фиксированный.
Ответ 3
некоторые возможные улучшения:
- попробуйте использовать обработчик, который обновляет текстовое окно каждые 0,5 секунды вместо потока, который это делает.
- сделать runnable конечным постоянным объектом вместо того, чтобы трещать новый каждый раз.
- рассмотрите возможность проверки того, что время изменилось (newTimeInMs-LastPublishedTimeInMs >= 1000), прежде чем сообщать текстовому редактору обновить себя.
- вместо String.format, попробуйте использовать StringBuilder. однако вам не понравится решение локали, которое предоставляет String.format(например, для арабских цифр).
Ответ 4
В моем случае это было свойство TextView:
android:ellipsize="marquee"
Удаление ускоренного ввода текста.