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();

}