Как запустить асинхронную задачу на каждые х минут в Android? - PullRequest
40 голосов
/ 02 июня 2011

как запустить асинхронную задачу в определенное время?(Я хочу запускать его каждые 2 минуты)

Я пытался использовать отложенную запись, но она не работает?

    tvData.postDelayed(new Runnable(){

    @Override
    public void run() {
        readWebpage();

    }}, 100);

В приведенном выше коде readwebpage - это функция, которая вызывает для меня асинхронную задачу..

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

   public void onCreate(Bundle savedInstanceState) {

         readwebapage();

   }

   public void readWebpage() {
    DownloadWebPageTask task = new DownloadWebPageTask();
    task.execute("http://www.google.com");

   }

   private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        String response1 = "";
        response1=read(); 
                   //read is my another function which does the real work    
        response1=read(); 
        super.onPostExecute(response1);
        return response1;
    }


      protected void onPostExecute(String result) {


         try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            TextView tvData = (TextView) findViewById(R.id.TextView01);
            tvData.setText(result);

        DownloadWebPageTask task = new DownloadWebPageTask();
        task.execute(new String[] { "http://www.google.com" });

    }

    }

Это мой код, и он работает отлично, но большая проблема - разрядка аккумулятора?

Ответы [ 9 ]

67 голосов
/ 02 июня 2011

Вы можете использовать обработчик, если хотите запускать что-то каждые X секунд. Обработчик хорош, потому что вам не нужны дополнительные потоки для отслеживания при запуске события. Вот короткий фрагмент:

private final static int INTERVAL = 1000 * 60 * 2; //2 minutes
Handler mHandler = new Handler();

Runnable mHandlerTask = new Runnable()
{
     @Override 
     public void run() {
          doSomething();
          mHandler.postDelayed(mHandlerTask, INTERVAL);
     }
};

void startRepeatingTask()
{
    mHandlerTask.run(); 
}

void stopRepeatingTask()
{
    mHandler.removeCallbacks(mHandlerTask);
}

Обратите внимание, что doSomething не должно занимать много времени (что-то вроде обновления позиции воспроизведения звука в пользовательском интерфейсе). Если это может занять некоторое время (например, загрузка или выгрузка в Интернет), то вместо этого следует использовать функцию ScheduledExecutorService * scheduleWithFixedDelay.

29 голосов
/ 02 июня 2011

Используйте Handler и PostDelayed:

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    public void run() {
        readWebpage();
        handler.postDelayed(this, 120000); //now is every 2 minutes
    }
 }, 120000); //Every 120000 ms (2 minutes)
7 голосов
/ 10 сентября 2012

вы можете использовать TimerTask вместо AsyncTask.

например:

Timer myTimer = new Timer("MyTimer", true);
myTimer.scheduleAtFixedRate(new MyTask(), ASAP, TWO_MINUTES);


private class MyTask extends TimerTask {

    public void run(){
      readWebPage();
    }

}
1 голос
/ 29 декабря 2016

Предлагаю перейти с Handler#postDelayed(Runnable). Имейте в виду, что этот метод будет работать только тогда, когда ваше приложение работает (может быть в фоновом режиме), но если пользователь закрывает его вручную или просто у Android не хватает памяти, он перестанет работать и не будет перезапущен еще раз позже - для этого вам нужно воспользоваться услугами.

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
        /* your code here */
    }
}, 2 * 60 * 1000); // first run after 2 minutes

Этот код будет ждать 2 минуты, выполнять ваш код, а затем продолжать делать это каждые 2 минуты. Но если вы хотите, чтобы он запускался мгновенно в первый раз - и , тогда запустите цикл ожидания, вместо этого используйте:

final Handler handler = new Handler();
 /* your code here */
new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
         /* and also here - your code */
    }
}.run(); 

или, если ваш код длиннее, чем один метод (readWebsite() в данном случае), и вы не хотите, чтобы его дублировали:

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
         /* your longer code here */
    }
}, 0); // first run instantly

(^ этот аналогичен первому примеру, но перед первым запуском имеет задержку 0 мс вместо 2 минут)

(Этот ответ основан на ответе @Devashish Mamgain, но я добавил слишком много деталей для редактирования, поэтому мне пришлось добавить новый)

1 голос
/ 30 ноября 2014

Когда телефон переходит в спящий режим, чтобы сэкономить заряд батареи, и это вполне возможно в течение 2 минут, Handler.postDelayed() может пропустить запланированное время.Для таких действий вы должны использовать AlarmManager, получить блокировку с помощью PowerManager, чтобы предотвратить переход в спящий режим во время работы AsyncTask.

См. Мой пост с примером кода здесь

Также вы можете прочитать Планирование повторяющихся сигналов

0 голосов
/ 11 марта 2018

Выполните несколько сообщений (Runnables), затем он должен использовать класс Looper, который отвечает за создание очереди в потоке. Например, при написании приложения, которое загружает файлы из Интернета, мы можем использовать класс Looper для помещения файлов для загрузки в очередь. Это поможет вам выполнить асинхронную задачу в Android ...

HandlerThread hThread = new HandlerThread("HandlerThread");
  hThread.start();
  Handler handler = new Handler(hThread.getLooper());
  final Handler handler1 = new Handler(hThread.getLooper());
  final long oneMinuteMs = 60 * 1000;

  Runnable eachMinute = new Runnable() { 
   @Override
   public void run() {
    Log.d(TAG, "Each minute task executing");
    handler1.postDelayed(this, oneMinuteMs);
    sendPostRequest();
   }
  };
 // sendPostRequest();
  // Schedule the first execution
  handler1.postDelayed(eachMinute, oneMinuteMs);
0 голосов
/ 06 апреля 2016

Вы можете использовать Time с Handler и TimerTask

  final Handler handler = new Handler();
        Timer timer = new Timer();
        TimerTask backtask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                        try {
                            //To task in this. Can do network operation Also
                            Log.d("check","Check Run" );
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                        }
                    }
                });
            }
        };
        timer.schedule(backtask , 0, 20000); //execute in every 20000 ms*/

Вы можете проверить logcat, чтобы проверить, работает или нет имя тега 'check'

0 голосов
/ 02 июня 2011

Вы можете запустить цикл внутри AsyncTask, который спит в течение двух секунд между выполнением задач.Как то так:

protected Result doInBackground (Params... params) {
    while (!interrupted) {
        doWork();
        Thread.sleep(2000);
    }
}
0 голосов
/ 02 июня 2011

Попробуйте расширить класс Thread, установите время ожидания 2000 миллисекунд и поместите ваш вызов в метод run. Это должно сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...