Как сделать секундомер в android studio

Обновлено: 07.07.2024

Подключаться к сервису мы теперь умеем. В этом уроке попробуем обменяться с ним данными.

В сервисе метод onBind возвращает объект, наследующий интерфейс IBinder. Проще всего использовать для этого объект Binder и расширить его необходимыми нам методами. Т.е. создаем свой класс MyBinder с предком Binder и рисуем в нем свои методы.

При биндинге, в методе onServiceConnected мы получаем объект Binder. Мы можем привести его к типу MyBinder (из сервиса) и вызывать его методы, а реализация будет срабатывать в сервисе, где мы описывали этот класс.

Как вы понимаете, это сработает только, если сервис и приложение выполняются в одном процессе. Поэтому такой биндинг называется локальным.

Нарисуем пример. У нас будет сервис, который с определенным интервалом будет что-то выводить в лог. Мы к нему подключимся, и будем повышать или понижать интервал и получать новое значение интервала обратно.

Project name: P0981_ServiceBindingLocal
Build Target: Android 2.3.3
Application name: ServiceBindingLocal
Package name: ru.startandroid.develop.p0981servicebindinglocal
Create Activity: MainActivity

Добавим в strings.xml строки:

Экран main.xml:

Кнопки для запуска сервиса, повышения интервала и понижения интервала.

Создаем сервис MyService.java:

Здесь мы используем таймер – Timer. Он позволяет повторять какое-либо действие через заданный промежуток времени. Кратко распишу принцип действия. TimerTask – это задача, которую Timer будет периодически выполнять. В методе run – кодим действия этой задачи. И далее для объекта Timer вызываем метод schedule, в который передаем задачу TimerTask, время через которое начнется выполнение, и период повтора. Чтобы отменить выполнение задачи, необходимо вызвать метод cancel для TimerTask. Отмененную задачу нельзя больше запланировать, и если снова надо ее включить – необходимо создать новый экземпляр TimerTask и скормить его таймеру.

Итак, в методе onCreate мы создаем таймер и выполняем метод schedule, в котором стартует задача.

Метод schedule проверяет, что задача уже создана и отменяет ее. Далее планирует новую, с отложенным на 1000 мс запуском и периодом = interval. Т.е. можно сказать, что этот метод перезапускает задачу с использованием текущего интервала повтора (interval), а если задача еще не создана, то создает ее. Сама задача просто выводит в лог текст run. Если interval = 0, то ничего не делаем.

Метод upInterval получает на вход значение, увеличивает interval на это значение и перезапускает задачу. Соответственно задача после этого будет повторяться реже.

Метод downInterval получает на вход значение, уменьшает interval на это значение (но так, чтоб не меньше 0) и перезапускает задачу. Соответственно задача после этого будет повторяться чаще.

onBind возвращает binder. Это объект класса MyBinder.

MyBinder расширяет стандартный Binder, мы добавляем в него один метод getService. Этот метод возвращает наш сервис MyService.

Т.е. в подключаемом Activity, в методе onServiceConnected мы получим объект, который идет на выход метода onBind. Далее преобразуем его к типу MyBinder, вызовем getService и вуаля - у нас в Activity будет ссылка на объект-сервис MyService.

Кодим MainActivity.java:

Жмем Start – запускаем сервис. В логах:

MyService onCreate
MyService onBind
MainActivity onServiceConnected

Создается сервис, и мы к нему подключаемся. Биндинг был ранее вызван в onStart и, когда сервис стартанул, мы автоматически подключились. В прошлом уроке мы разбирали такую ситуацию, когда биндинг идет к незапущенному пока сервису.

Далее с интервалом в одну секунду в лог падает текст run.

Попробуем увеличить интервал. Жмем Up.


На экране появилось текущее значение интервала. И по времени записей в логах видим, что именно с этим интервалом срабатывает задача (вывод текста run в лог) .

Далее можно нажимать Up и Down и наблюдать, как меняется интервал выполнения задачи. Таким образом, мы из Activity подключились к сервису и управляем его работой.

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

На следующем уроке:

- шлем уведомление из сервиса

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

- новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Я не знаю, что случилось. TextView не меняет, он сохраняет печать 00. Я ожидаю, что выберете простой таймер, такой как 0,1,2. Я хочу использовать потоки не такие классы, как таймер или timetask. Спасибо за ваше время. здесь код:

Вам действительно не нужно создавать нити для достижения своей цели. Это относительно просто использовать объект Java Timer(), чтобы настроить повторный обратный вызов на ваш код, где вы можете обновить текстовое поле.

Именно то, что вы пытаетесь сделать здесь, на 100% не понятно мне, я предполагаю, что вы, когда вы нажимаете inizio, хотите, чтобы текст в текстовом поле начинал увеличиваться, например, 1,2,3 и т.д. Когда вы нажимаете кнопку сброса, вы хотите, чтобы он снова перезапустился с 1. (Примечание: чтобы сделать это действие, как обычный секундомер, вы бы изменили текст кнопки inizio на слово "stop" после запуска таймера и т.д.)

Этот код просто покажет вам, как использовать таймер, чтобы установить повторяющийся интервал, в котором вы можете обновить свой пользовательский интерфейс, чтобы показать состояние переменной:

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

Я хочу отобразить хронометр, который начинает отсчет при запуске службы и никогда не останавливается, пока пользователь не нажмет кнопку. Я хочу разрешить пользователю оставлять активность, отображая хронометр, делать что-то, а затем возвращаться. Но идея состоит в том, что когда пользователь возвращается, я не хочу, чтобы хронометр снова возвращался в 0:00. Insted Я хочу, чтобы он показывал точное время, которое прошло с момента запуска службы.

Я могу рассчитывать прошедшее время каждый раз, когда пользователь возвращается к активности хронометра:

Дело в том, что я не знаю, как сказать хронометру начать отсчет с того времени!

большое спасибо! ПОКА

Вы можете использовать хронометр .

Вы также должны проверить эту тему .

Базовое время – это время, когда Chronometer начал тикать. Вы можете установить его с помощью Chronometer.setBase() . Вы должны получить базовое время, используя SystemClock.getElapsedTime() . Call setBase() с временем начала каждого запуска Chronometer . Если есть потенциал для того, чтобы действие было уничтожено и воссоздано, пока таймер все еще активен, вам нужно будет удерживать базовое время где-то вне Activity которому принадлежит Chronometer .

Чтобы запустить хронометр, вы должны использовать метод setBase() вашего хронометра с помощью SystemClock.elapsedRealTime() . Именно так:

Но если вы хотите начать в другое время, вы должны вычесть время, которое вы хотите в миллисекундах. Например, вы хотите запустить свой хронометр через 10 секунд:

Некоторые странные с SystemClock.getElapsedTime (), я сделал некоторые изменения для нормального использования с датой начала, например

Здесь ребенок хронометра ниже, TimeView

Просто скопируйте и используйте, это работает для меня

Когда вы устанавливаете базовое время с помощью .setBase (SystemClock.elapsedRealTime ()), хронометр начинает отсчет с 00.00, но время, которое он хранит, – это количество milisecs от загрузки. Когда вы используете .stop, внутренний счетчик не останавливается, просто время, которое вы видите на часах. Итак, если вы снова используете .start, счетчик часов переходит к реальному счету. Если вы хотите сохранить время, прошедшее с начала, вам нужно снова получить время, прошедшее через Систему, и внести изменения в .setTime

Это работает для меня:

Или есть лучший способ в android (android handler)?

ОТВЕТЫ

Ответ 1

Стандартный способ Java использовать таймеры через java.util.Timer и java.util.TimerTask отлично работает в Android, но вы должны знать, что этот метод создает новый поток.

Ответ 2

Да может использоваться java-таймер, но поскольку вопрос задает лучший способ (для мобильных устройств). Что объясняется Здесь.

Для StackOverflow:

Поскольку Таймер создает новый поток, он может считаться тяжелым,

если все, что вам нужно, это получить обратный вызов, когда выполняется действие Обработчик, можно использовать в сочетании с

или Message

на боковой ноте этот подход может быть использован, если вы хотите запустить кусок кода в потоке пользовательского интерфейса из другого потока.

если вам нужно получить обратный вызов, даже если ваша активность не выполняется, вы можете использовать AlarmManager

Ответ 3

Как я уже видел, java.util.Timer является наиболее используемым для реализации таймера.

Для повторяющейся задачи:

Для одного запуска задачи:

задача - метод, который нужно выполнить
после время до первоначального выполнения
( интервал время повторения выполнения)

Ответ 4

Я надеюсь, что это полезно и может потребовать меньше усилий для реализации, Класс Android CountDownTimer

Ответ 5

Добавьте новую переменную int named time. Установите значение 0. Добавьте следующий код в функцию onCreate в MainActivity.java.

Перейдите в метод запуска и добавьте следующий код.

Ответ 6

Документация на Android предполагает, что вы должны использовать AlarmManager для регистрации намерения, которое будет срабатывать в указанное время, если ваше приложение может не быть работает.

В противном случае вы должны использовать Handler.

Примечание. Диспетчер аварийных сигналов для случаев, когда вы хотите иметь код приложения выполняется на определенном времени, даже если ваше приложение не в настоящее время работает. Для нормального времени операции (тики, таймауты и т.д.) легче и гораздо эффективнее используйте обработчик.

Ответ 7

Здесь мы идем. Нам понадобятся два класса. Я отправляю код, который изменяет профиль мобильного аудио через каждые 5 секунд (5000 миллисекунд).

Наш 1-й класс

Наш 2-й класс

Ответ 8

Ответ 9

Я использую обработчик и запускаю для создания таймера. Я обертываю это в абстрактном классе. Просто извлеките/реализуйте его, и вы хорошо пойдете:

Обратите внимание, что handler.postDelayed вызывается перед выполнением кода - это сделает таймер более закрытым по времени "ожидаемым". Однако в случаях, когда таймер работает часто, и задача ( onTimer() ) длинна - могут быть перекрытия. Если вы хотите начать подсчет intervalMS после выполнения задачи, переместите onTimer() вызов строки выше.

Ответ 10

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

Читайте также: