РЕДАКТИРОВАТЬ : я разместил свое решение ниже (в основном, ListViews очень медленный по некоторым причинам), и постараюсь обновить его, если я смогу объяснить, почему именно ListView так ужасен в эта ситуация.
Цель:
Получить 7 объектов ListView, показывающих 7 независимо установленных часов / таймеров, которые обновляются / отмечаются каждую секунду. Эти часы являются просто строками с показанным рассчитанным прошедшим временем (SystemClock.ElapsedRealTime () - хранится ElapsedRealTime (), когда был создан объект.)
Проблема:
По существу, 8 минут из этих 7 часов тикают - моя программа по сути бесполезна ... представленная информация является неточной, пользовательский интерфейс в значительной степени не отвечает и т. Д. Вот некоторые результаты тестирования с эталоном физического секундомера:
- В 04:00 часы смещаются на 1 секунду и обновляются каждые 4 секунды.
- В 06:00 часы проскальзывают на 3 секунды и обновляются каждые 5 секунд.
- В 08:00 часы проскальзывают на 6-7 секунд и обновляются каждые 6 секунд.
- В 16:00 часы проскальзывают на 7 секунд и обновляются каждые 10 секунд.
Что у меня пока есть:
У меня есть собственный класс ActivityTimer, с сохраненным long, представляющим SystemClock.ElapsedRealTime () того времени, когда каждый экземпляр ActivityTimer был впервые создан. Нажав на кнопку 7 раз, я создаю 7 экземпляров, каждый из которых добавляется в ArrayList
У меня есть составное представление ActivityTimerControl, которому передают экземпляр ActivityTimer при создании экземпляра, а затем представляют элементы данных моего ActivityTimer в элементах пользовательского интерфейса (например, тикающие часы). Мой ArrayAdapter обрабатывает это создание и работает нормально. Согласно этому прекрасному учебнику у меня есть _Handler в этом ActivityControl, который при создании ActvityControl публикует это:
private Runnable _timerUpdateTask = new Runnable()
{
public void run()
{
final long start = _ActivityTimer.getStartTime();
long millis = SystemClock.elapsedRealtime() - start;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
if (seconds < 10)
{
_tglActivityPauseButton.setTextOn(""+minutes+":0"+seconds);
}
else
{
_tglActivityPauseButton.setTextOn("" + minutes + ":" + seconds);
}
_tglActivityPauseButton.setChecked(true);
_timerUpdateHandler.postDelayed(this, 1000);
}
};
Кроме того, что я описал, мой проект на самом деле ничего не делает, так как я до сих пор застрял в этой фундаментальной проблеме. Так что я не опубликовал никакого другого кода, потому что я не думаю, что он уместен за пределами приведенных выше резюме, но если кто-то считает, что какая-то другая часть проекта актуальна, просто дайте мне знать, и я опубликую подробный код для этого. Я представляю свою последнюю строку в SetTextOn () ToggleButton, но тестирование показало, что это не является существенным фактором - не имеет значения, устанавливаю ли я текст обычного TextView, или что, нет Независимо от того, что я пробовал, мои результаты всегда примерно одинаковы, с заметной задержкой на каждом такте и, в конечном итоге, пользовательский интерфейс полностью не отвечает.
Насколько я понимаю, предполагается, что обработчик является наиболее эффективным способом обновления элемента пользовательского интерфейса на постоянной и частой основе, заменяя java.util.Timer, но, несмотря на это, мой код запускается медленно и становится хуже, чем дольше Я позволил ему бежать.
Даже после увеличения postDelay до 5000 мс, те же проблемы все еще возникали, и приложение по-прежнему принудительно закрывалось через 49 минут. Так как я бы подумал, что этот тест увеличил бы время до принудительного закрытия на 5, если бы он не был исправлен полностью (в ущерб нужной мне функциональности), я подозреваю, что что-то неправильно обрабатывается с помощью обработчика или какой-то другой компонент.
Мои вопросы:
- Я подозреваю, что моя проблема в том, что у меня есть 7 объектов (ActivityControls), каждый из которых имеет свой собственный обработчик , постоянно повторяющий обновление соответствующего времени, которое отображается. У кого-нибудь есть опыт, чтобы сказать, будет ли это так?
- Есть ли способ, которым я могу иметь один обработчик, который вызывает каждый ActivityControl в моем ListView для обновления своего времени?
- Оставляет ли сообщение в обработчике какую-то трассировку памяти, которая не удаляется автоматически, или может принести пользу от вынужденной утилизации?
- У кого-нибудь еще есть идеи относительно наиболее эффективного способа запуска постоянных обновлений пользовательского интерфейса для нескольких объектов?