Android. Повторно запускайте поток в течение таймера.
Прежде всего, я не мог даже выбрать способ использования, я читаю часами, и кто-то говорит, что использует "Обработчики", кто-то говорит, что использует "Таймер". Вот чего я пытаюсь добиться:
При настройках, есть параметр (флажок), который включает/отключает повторяющееся задание. Когда этот флажок установлен, таймер должен начать работать, и поток должен выполняться каждые x секунд. Поскольку флажок не установлен, таймер должен остановиться.
Здесь мой код:
Проверяется, установлен ли флажок или нет, если будет установлен флажок refreshAllServers, выполняющий задание с таймером.
boolean CheckboxPreference = prefs.getBoolean("checkboxPref", true);
if(CheckboxPreference == true) {
Main main = new Main();
main.refreshAllServers("start");
} else {
Main main = new Main();
main.refreshAllServers("stop");
}
RefreshAllServers void, который выполняет задание таймера:
public void refreshAllServers(String start) {
if(start == "start") {
// Start the timer which will repeatingly execute the thread
} else {
// stop the timer
}
И вот как я выполняю свой поток: (Хорошо работает без таймера)
Thread myThread = new MyThread(-5);
myThread.start();
Что я пробовал?
Я попробовал любой пример, который я мог видеть из Google (обработчики, таймер), ни один из них не работал, мне удалось запустить таймер один раз, но остановить его не удалось.
Самый простой и понятный код, который я видел в своих исследованиях, был следующим:
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here
}
},
5000
);
Ответы
Ответ 1
Просто используйте ниже фрагмент
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
//
// Do the stuff
//
handler.postDelayed(this, 1000);
}
};
runnable.run();
Чтобы остановить его, используйте
handler.removeCallbacks(runnable);
Должен сделать трюк.
Ответ 2
Спасибо всем, я исправил эту проблему с помощью таймера.
timer = new Timer();
timer.scheduleAtFixedRate(
new java.util.TimerTask() {
@Override
public void run() {
for(int i = 0; i < server_amount; i++) {
servers[i] = "Updating..."; handler.sendEmptyMessage(0);
new MyThread(i);
myThread.start();
}
}},
2000, 5000
);
Ответ 3
Я бы подумал использовать AlarmManager http://developer.android.com/reference/android/app/AlarmManager.html
Если флажок установлен на метод вызова, где
AlarmManager alarmManager = (AlarmManager)SecureDocApplication.getContext()
.getSystemService(Context.ALARM_SERVICE);
PendingIntent myService = PendingIntent.getService(context, 0,
new Intent(context, MyService.class), 0);
long triggerAtTime = 1000;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtTime, 5000 /* 5 sec*/,
myService);
Если флажок выключен, отмените диспетчер аварийных сообщений
alarmManager.cancel(myService);
Ответ 4
Используйте CountDownTimer. Как он работает, он будет вызывать метод для каждого тика таймера и другой метод, когда таймер заканчивается. В этот момент вы можете при необходимости перезапустить. Кроме того, я думаю, вам, вероятно, следует начинать с AsyncTask, а не с потоков. Пожалуйста, не пытайтесь управлять своими потоками в Android. Попробуйте, как показано ниже. Его работает как часы.
CountDownTimer myCountdownTimer = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
// Kick off your AsyncTask here.
}
public void onFinish() {
mTextField.setText("done!");
// the 30 seconds is up now so do make any checks you need here.
}
}.start();
Ответ 5
"Класс [ScheduledThreadPoolExecutor] предпочтительнее Таймера, когда необходимы несколько рабочих потоков или когда требуется дополнительная гибкость или возможности ThreadPoolExecutor (который распространяется по этому классу)".
на...
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html
Это не намного больше, чем обработчик, но имеет возможность запускать ровно все так часто (порог задержки после каждого завершения вычислений).
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
...
final int THREAD_POOL_SIZE = 10;
final int START_DELAY = 0;
final int TIME_PERIOD = 5;
final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
ScheduledThreadPoolExecutor pool;
Runnable myPeriodicThread = new Runnable() {
@Override
public void run() {
refreshAllServers();
}
};
public void startTimer(){
pool.scheduleAtFixedRate(myPeriodicThread,
START_DELAY,
TIME_PERIOD,
TIME_UNIT);
}
public void stopTimer(){
pool.shutdownNow();
}