Вопрос по android, multithreading – Android: выполнять код через равные промежутки времени

31

Мне нужно регулярно выполнять код (подключаться к серверу и извлекать данные из базы данных MySQL каждую минуту). Для этого у меня есть класс Sync:

public class Sync {

    static private Handler handler = new Handler();
    Runnable task;

    public Sync(Runnable task, long time) {
        this.task = task;
        handler.removeCallbacks(task);
        handler.postDelayed(task, time);
    }
}

и в моей деятельности я имею:

public void onCreate(Bundle savedInstanceState) {
    ...
    Sync sync = new Sync(call,60*1000);
    ...
}

final private Runnable call = new Runnable() {
    public void run() {
    //This is where my sync code will be, but for testing purposes I only have a Log statement
    Log.v("test","this will run every minute");
    }
};

Я пробовал это с более коротким периодом времени для тестирования, но он запускается только один раз. Когда оно регистрирует сообщение в первый раз, оно также является последним. Кто-нибудь видит, что я здесь делаю? Спасибо!

scheduleWithFixedDelay от ScheduledThreadPoolExecutor - еще один вариант. Ravindra babu

Ваш Ответ

5   ответов
8

Во-вторых, вы должны снова использовать метод post Delay в runnable, чтобы запустить его снова.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Sync sync = new Sync(call,60*1000);

    }
    final private Runnable call = new Runnable() {
        public void run() {
        //This is where my sync code will be, but for testing purposes I only have a Log statement
        Log.v("test","this will run every minute");
        handler.postDelayed(call,60*1000);
        }
    };
    public final Handler handler = new Handler();
    public class Sync {


        Runnable task;

        public Sync(Runnable task, long time) {
            this.task = task;
            handler.removeCallbacks(task);
            handler.postDelayed(task, time);
        }
    }


}
1
      private void doSomethingRepeatedly() {
      timer.scheduleAtFixedRate( new TimerTask() {
            public void run() {

                  try{

                   //Your code

                  }
                  catch (Exception e) {
                      // TODO: handle exception
                  }

             }
            }, 0, 10000);
                     }
1

scheduleAtFixedRate:

private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

public void beepEvery10Seconds() {
     final Runnable beeper = new Runnable() {
       public void run() { System.out.println("beep"); }
     };
     final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper, 0, 10, SECONDS);
}
3

handler.postDelayed(task, time); будет выполняться только один раз, если вы хотите, чтобы код запускался через равные промежутки времени, я бы предложилTimer иTimerTask вместоHandler иRunnable.

TimerTasks можно настроить на запуск один раз, каждые x секунд или с фиксированным периодом, например х секунд - сколько бы времени ни потребовалось для запуска в прошлый раз.

51

Надеюсь, поможет!

final Handler handler = new Handler(); 
Runnable runnable = new Runnable() { 

    @Override 
    public void run() { 
        try{
            //do your code here
        }
        catch (Exception e) {
            // TODO: handle exception
        }
        finally{
            //also call the same runnable to call it at regular interval
            handler.postDelayed(this, 1000); 
        }
    } 
}; 

//runnable must be execute once
handler.post(runnable);
Я думаю, чтоhandler.postDelayed(this, 1000); должен быть только в разделе finally (не в конце блока try), иначе он будет опубликован два раза.
Это решило это, спасибо! :) Tomáš 'Guns Blazing' Frček
Хотя этот ответ был бы действительным на момент его ответа. Если вам нужно получать данные через определенный промежуток времени, вы должны использовать Firebase Job Dispatcher. Одной из причин этого является то, что это может помочь вашим пользователям сэкономить заряд батареи (в зависимости от установленных вами параметров), и вам не нужно беспокоиться о том, что ваши службы будут убиты, когда ОС работает в фоновом режиме на Android O +.
Да, это то, что я собирался сказать. AlarmManager тяжелее и требует обработки Intents для запуска вашего Runnable. Наличие вашего Runnable повторно опубликовать себя в конце, если путь. И вы должны обернуть свой код в Runnable с помощью try-finally и повторно опубликовать Runnable в разделе finally, чтобы убедиться, что он никогда не пропускается.
@ amram99 Ваше изменение было отклонено другими, но я считаю его корректным, поэтому оно обновлено, как вы предлагаете. Пармая Спасибо за комментарий.

Похожие вопросы