Как установить таймер в android
Каков правильный способ установки таймера в андроиде для запуска задачи (функция, которую я создаю, которая не меняет пользовательский интерфейс)?
Используйте этот способ Java:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html
Или есть лучший способ в android (android handler)?
Ответы
Ответ 1
Стандартный способ Java использовать таймеры через java.util.Timer и java.util.TimerTask отлично работает в Android, но вы должны знать, что этот метод создает новый поток.
Вы можете использовать очень удобный Handler класс (android.os.Handler) и отправлять сообщения обработчику через sendMessageAtTime(android.os.Message, long)
или sendMessageDelayed(android.os.Message, long)
. После того, как вы получите сообщение, вы можете запускать требуемые задачи. Второй вариант - создать объект Runnable и запланировать его с помощью функций Handler postAtTime(java.lang.Runnable, long)
или postDelayed(java.lang.Runnable, long)
.
Ответ 2
Да может использоваться java-таймер, но поскольку вопрос задает лучший способ (для мобильных устройств). Что объясняется Здесь.
Для StackOverflow:
Поскольку Таймер создает новый поток, он может считаться тяжелым,
если все, что вам нужно, это получить обратный вызов, когда выполняется действие Обработчик, можно использовать в сочетании с
Runnable:
private final int interval = 1000; // 1 Second
private Handler handler = new Handler();
private Runnable runnable = new Runnable(){
public void run() {
Toast.makeText(MyActivity.this, "C'Mom no hands!", Toast.LENGTH_SHORT).show();
}
};
...
handler.postAtTime(runnable, System.currentTimeMillis()+interval);
handler.postDelayed(runnable, interval);
или Message
private final int EVENT1 = 1;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Event1:
Toast.makeText(MyActivity.this, "Event 1", Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(MyActivity.this, "Unhandled", Toast.LENGTH_SHORT).show();
break;
}
}
};
...
Message msg = handler.obtainMessage(EVENT1);
handler.sendMessageAtTime(msg, System.currentTimeMillis()+interval);
handler.sendMessageDelayed(msg, interval);
на боковой ноте этот подход может быть использован, если вы хотите запустить кусок кода в потоке пользовательского интерфейса из другого потока.
если вам нужно получить обратный вызов, даже если ваша активность не выполняется, вы можете использовать AlarmManager
Ответ 3
Как я уже видел, java.util.Timer является наиболее используемым для реализации таймера.
Для повторяющейся задачи:
new Timer().scheduleAtFixedRate(task, after, interval);
Для одного запуска задачи:
new Timer().schedule(task, after);
задача - метод, который нужно выполнить
после время до первоначального выполнения
( интервал время повторения выполнения)
Ответ 4
Я надеюсь, что это полезно и может потребовать меньше усилий для реализации,
Класс Android CountDownTimer
например,
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Ответ 5
Вероятно Timerconcept
new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
}
}.start();
или
Способ 2::
Запрограммировать таймер
Добавьте новую переменную int named time. Установите значение 0.
Добавьте следующий код в функцию onCreate в MainActivity.java.
//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);
Перейдите в метод запуска и добавьте следующий код.
//We must use this function in order to change the text view text
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView tv = (TextView) findViewById(R.id.main_timer_text);
tv.setText(String.valueOf(time));
time += 1;
}
});
Ответ 6
Это ситуативный.
Документация на Android предполагает, что вы должны использовать AlarmManager для регистрации намерения, которое будет срабатывать в указанное время, если ваше приложение может не быть работает.
В противном случае вы должны использовать Handler.
Примечание. Диспетчер аварийных сигналов для случаев, когда вы хотите иметь код приложения выполняется на определенном времени, даже если ваше приложение не в настоящее время работает. Для нормального времени операции (тики, таймауты и т.д.) легче и гораздо эффективнее используйте обработчик.
Ответ 7
Здесь мы идем. Нам понадобятся два класса. Я отправляю код, который изменяет профиль мобильного аудио через каждые 5 секунд (5000 миллисекунд)...
Наш 1-й класс
public class ChangeProfileActivityMain extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Timer timer = new Timer();
TimerTask updateProfile = new CustomTimerTask(ChangeProfileActivityMain.this);
timer.scheduleAtFixedRate(updateProfile, 0, 5000);
}
}
Наш 2-й класс
public class CustomTimerTask extends TimerTask {
private AudioManager audioManager;
private Context context;
private Handler mHandler = new Handler();
// Write Custom Constructor to pass Context
public CustomTimerTask(Context con) {
this.context = con;
}
@Override
public void run() {
// TODO Auto-generated method stub
// your code starts here.
// I have used Thread and Handler as we can not show Toast without starting new thread when we are inside a thread.
// As TimePicker has run() thread running., So We must show Toast through Handler.post in a new Thread. Thats how it works in Android..
new Thread(new Runnable() {
@Override
public void run() {
audioManager = (AudioManager) context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
mHandler.post(new Runnable() {
@Override
public void run() {
if(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Toast.makeText(context, "Ringer Mode set to Normal", Toast.LENGTH_SHORT).show();
} else {
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Toast.makeText(context, "Ringer Mode set to Silent", Toast.LENGTH_SHORT).show();
}
}
});
}
}).start();
}
}
Ответ 8
Я новичок в Android, но вот класс таймера, который я создал на основе ответов выше. Он работает для моего приложения, но я приветствую любые предложения.
Пример использования:
...{
public Handler uiHandler = new Handler();
private Runnable runMethod = new Runnable()
{
public void run()
{
// do something
}
};
timer = new UITimer(handler, runMethod, timeoutSeconds*1000);
timer.start();
}...
public class UITimer
{
private Handler handler;
private Runnable runMethod;
private int intervalMs;
private boolean enabled = false;
private boolean oneTime = false;
public UITimer(Handler handler, Runnable runMethod, int intervalMs)
{
this.handler = handler;
this.runMethod = runMethod;
this.intervalMs = intervalMs;
}
public UITimer(Handler handler, Runnable runMethod, int intervalMs, boolean oneTime)
{
this(handler, runMethod, intervalMs);
this.oneTime = oneTime;
}
public void start()
{
if (enabled)
return;
if (intervalMs < 1)
{
Log.e("timer start", "Invalid interval:" + intervalMs);
return;
}
enabled = true;
handler.postDelayed(timer_tick, intervalMs);
}
public void stop()
{
if (!enabled)
return;
enabled = false;
handler.removeCallbacks(runMethod);
handler.removeCallbacks(timer_tick);
}
public boolean isEnabled()
{
return enabled;
}
private Runnable timer_tick = new Runnable()
{
public void run()
{
if (!enabled)
return;
handler.post(runMethod);
if (oneTime)
{
enabled = false;
return;
}
handler.postDelayed(timer_tick, intervalMs);
}
};
}
Ответ 9
Я использую обработчик и запускаю для создания таймера. Я обертываю это в абстрактном классе. Просто извлеките/реализуйте его, и вы хорошо пойдете:
public static abstract class SimpleTimer {
abstract void onTimer();
private Runnable runnableCode = null;
private Handler handler = new Handler();
void startDelayed(final int intervalMS, int delayMS) {
runnableCode = new Runnable() {
@Override
public void run() {
handler.postDelayed(runnableCode, intervalMS);
onTimer();
}
};
handler.postDelayed(runnableCode, delayMS);
}
void start(final int intervalMS) {
startDelayed(intervalMS, 0);
}
void stop() {
handler.removeCallbacks(runnableCode);
}
}
Обратите внимание, что handler.postDelayed
вызывается перед выполнением кода - это сделает таймер более закрытым по времени "ожидаемым". Однако в случаях, когда таймер работает часто, и задача (onTimer()
) длинна - могут быть перекрытия. Если вы хотите начать подсчет intervalMS
после выполнения задачи, переместите onTimer()
вызов строки выше.
Ответ 10
Я считаю, что способ сделать это на андроиде - это то, что вам нужно использовать фоновый сервис. В этом фоновом приложении создайте таймер. Когда таймер "галочки" (установите интервал времени ожидания), запустите свою деятельность, которую вы хотите запустить.
http://developer.android.com/guide/topics/fundamentals.html (< - в этой статье объясняется взаимосвязь между действиями, услугами, намерениями и другими основными принципами разработки Android)
Ответ 11
Для синхронизации времени вы должны использовать Handler.
Если вам нужно запустить фоновый сервис, AlarmManager - это путь.
Ответ 12
Я использовал (Timer
, TimerTask
), а также Handler
, чтобы периодически запускать (время). Теперь я переключил все на RxJava. RxJava предоставляет Observable.timer
, который проще, менее подвержен ошибкам, без проблем.
public class BetterTimerFragment extends Fragment {
public static final String TAG = "BetterTimer";
private TextView timeView;
private Subscription timerSubscription;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_timer, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
timeView = (TextView) view.findViewById(R.id.timeView);
}
@Override
public void onResume() {
super.onResume();
// Right after the app is visible to users, delay 2 seconds
// then kick off a (heavy) task every 10 seconds.
timerSubscription = Observable.timer(2, 10, TimeUnit.SECONDS)
.map(new Func1<Long, String>() {
@Override
public String call(Long unused) {
// TODO: Probably do time-consuming work here.
// This runs on a different thread than the main thread.
return "Time: " + System.currentTimeMillis();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String timeText) {
// The result will then be propagated back to the main thread.
timeView.setText(timeText);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
Log.e(TAG, throwable.getMessage(), throwable);
}
});
}
@Override
public void onPause() {
super.onPause();
// Don't kick off tasks when the app gets invisible.
timerSubscription.unsubscribe();
}
}