如何在android中的每x分钟运行一个异步任务?

时间:2022-03-19 02:30:42

how to run the async task at specific time? (I want to run it every 2 mins)

如何在特定时间运行异步任务? (我想每2分钟运行一次)

I tried using post delayed but it's not working?

我试过使用post延迟但它不起作用?

    tvData.postDelayed(new Runnable(){

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

    }}, 100);

In the above code readwebpage is function which calls the async task for me..

在上面的代码中,readwebpage是为我调用异步任务的函数。

Right now below is the method which I am using

现在下面是我正在使用的方法

   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" });

    }

    }

This is what I my code is and it works perfectly fine but the big problem I drains my battery?

这就是我的代码是什么,它工作得很好,但是我耗尽电池的大问题?

9 个解决方案

#1


60  

You can use handler if you want to initiate something every X seconds. Handler is good because you don't need extra thread to keep tracking when firing the event. Here is a short snippet:

如果要每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);
}

Note that doSomething should not take long (something like update position of audio playback in UI). If it can potentially take some time (like downloading or uploading to the web), then you should use ScheduledExecutorService's scheduleWithFixedDelay function instead.

请注意,doSomething不应该花费很长时间(比如UI中音频播放的更新位置)。如果它可能需要一些时间(如下载或上传到Web),那么您应该使用ScheduledExecutorService的scheduleWithFixedDelay函数。

#2


28  

Use Handler and PostDelayed:

使用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)

#3


7  

you can use TimerTask instead of AsyncTask.

您可以使用TimerTask而不是AsyncTask。

ex:

例如:

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


private class MyTask extends TimerTask {

    public void run(){
      readWebPage();
    }

}

#4


1  

When phone goes to sleep mode, to save battery, and it is quite possible to happen within 2 mins interval, Handler.postDelayed() may miss scheduled time. For such activities you should use AlarmManager, get a lock with PowerManager to prevent going to sleep back while you're running the AsyncTask.

当手机进入睡眠模式,为了节省电池,并且很可能在2分钟的间隔内发生,Handler.postDelayed()可能会错过预定的时间。对于此类活动,您应该使用AlarmManager,使用PowerManager锁定以防止在运行AsyncTask时进入睡眠状态。

See my post with code sample here

在这里查看代码示例的帖子

Also you may want to read Scheduling Repeating Alarms

您还可以阅读“调度重复警报”

#5


0  

Try extending the Thread class, set a sleep time of 2000 millis and place your call into the run method. That should do it.

尝试扩展Thread类,设置2000毫秒的休眠时间并将调用放入run方法。应该这样做。

#6


0  

You can use Time with Handler and TimeTask

您可以使用Time with Handler和TimeTask

  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*/

You can check logcat to verify whether is running or not using 'check' tag name

您可以使用“check”标记名来检查logcat以验证是否正在运行

#7


0  

I suggest to go with Handler#postDelayed(Runnable). Keep in mind that this method will work only when your app is running (may be in background) but if user closes it manually or simply Android runs out of memory it'll stop working and won't be restarted again later - for that you need to use services.

我建议使用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

This code will wait 2 minutes, execute your code, and then keep doing that every 2 minutes. But if you want it to run instantly for the first time - and then start the wait-do loop, instead use:

此代码将等待2分钟,执行您的代码,然后每2分钟继续执行此操作。但是如果你想让它第一次立即运行 - 然后启动wait-do循环,而是使用:

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

or, if your code is longer than just one method (readWebsite() in this case), and you don't want that to be duplicated:

或者,如果您的代码长于一个方法(在本例中为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

(^ this one is just like the first example but has a 0ms delay before first run instead of 2 minutes)

(^这个就像第一个例子,但在第一次运行之前有0ms延迟,而不是2分钟)

(This answer is based on @Devashish Mamgain's one but I added too much details for an edit so I had to add a new one)

(这个答案基于@Devashish Mamgain的答案,但我为编辑添加了太多细节,所以我不得不添加一个新的)

#8


0  

Execute multiple messages(Runnables) then he should use the Looper class which is responsible for creating a queue in the thread. For example, while writing an application that downloads files from the internet, we can use Looper class to put files to be downloaded in the queue. This will help you to perform async task in android...

执行多个消息(Runnables)然后他应该使用负责在线程中创建队列的Looper类。例如,在编写从Internet下载文件的应用程序时,我们可以使用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);

#9


-13  

You could run a loop within the AsyncTask that sleeps for two seconds between doing the tasks. Something like this:

您可以在AsyncTask中运行一个循环,在执行任务之间休眠两秒钟。像这样的东西:

protected Result doInBackground (Params... params) {
    while (!interrupted) {
        doWork();
        Thread.sleep(2000);
    }
}

#1


60  

You can use handler if you want to initiate something every X seconds. Handler is good because you don't need extra thread to keep tracking when firing the event. Here is a short snippet:

如果要每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);
}

Note that doSomething should not take long (something like update position of audio playback in UI). If it can potentially take some time (like downloading or uploading to the web), then you should use ScheduledExecutorService's scheduleWithFixedDelay function instead.

请注意,doSomething不应该花费很长时间(比如UI中音频播放的更新位置)。如果它可能需要一些时间(如下载或上传到Web),那么您应该使用ScheduledExecutorService的scheduleWithFixedDelay函数。

#2


28  

Use Handler and PostDelayed:

使用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)

#3


7  

you can use TimerTask instead of AsyncTask.

您可以使用TimerTask而不是AsyncTask。

ex:

例如:

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


private class MyTask extends TimerTask {

    public void run(){
      readWebPage();
    }

}

#4


1  

When phone goes to sleep mode, to save battery, and it is quite possible to happen within 2 mins interval, Handler.postDelayed() may miss scheduled time. For such activities you should use AlarmManager, get a lock with PowerManager to prevent going to sleep back while you're running the AsyncTask.

当手机进入睡眠模式,为了节省电池,并且很可能在2分钟的间隔内发生,Handler.postDelayed()可能会错过预定的时间。对于此类活动,您应该使用AlarmManager,使用PowerManager锁定以防止在运行AsyncTask时进入睡眠状态。

See my post with code sample here

在这里查看代码示例的帖子

Also you may want to read Scheduling Repeating Alarms

您还可以阅读“调度重复警报”

#5


0  

Try extending the Thread class, set a sleep time of 2000 millis and place your call into the run method. That should do it.

尝试扩展Thread类,设置2000毫秒的休眠时间并将调用放入run方法。应该这样做。

#6


0  

You can use Time with Handler and TimeTask

您可以使用Time with Handler和TimeTask

  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*/

You can check logcat to verify whether is running or not using 'check' tag name

您可以使用“check”标记名来检查logcat以验证是否正在运行

#7


0  

I suggest to go with Handler#postDelayed(Runnable). Keep in mind that this method will work only when your app is running (may be in background) but if user closes it manually or simply Android runs out of memory it'll stop working and won't be restarted again later - for that you need to use services.

我建议使用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

This code will wait 2 minutes, execute your code, and then keep doing that every 2 minutes. But if you want it to run instantly for the first time - and then start the wait-do loop, instead use:

此代码将等待2分钟,执行您的代码,然后每2分钟继续执行此操作。但是如果你想让它第一次立即运行 - 然后启动wait-do循环,而是使用:

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

or, if your code is longer than just one method (readWebsite() in this case), and you don't want that to be duplicated:

或者,如果您的代码长于一个方法(在本例中为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

(^ this one is just like the first example but has a 0ms delay before first run instead of 2 minutes)

(^这个就像第一个例子,但在第一次运行之前有0ms延迟,而不是2分钟)

(This answer is based on @Devashish Mamgain's one but I added too much details for an edit so I had to add a new one)

(这个答案基于@Devashish Mamgain的答案,但我为编辑添加了太多细节,所以我不得不添加一个新的)

#8


0  

Execute multiple messages(Runnables) then he should use the Looper class which is responsible for creating a queue in the thread. For example, while writing an application that downloads files from the internet, we can use Looper class to put files to be downloaded in the queue. This will help you to perform async task in android...

执行多个消息(Runnables)然后他应该使用负责在线程中创建队列的Looper类。例如,在编写从Internet下载文件的应用程序时,我们可以使用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);

#9


-13  

You could run a loop within the AsyncTask that sleeps for two seconds between doing the tasks. Something like this:

您可以在AsyncTask中运行一个循环,在执行任务之间休眠两秒钟。像这样的东西:

protected Result doInBackground (Params... params) {
    while (!interrupted) {
        doWork();
        Thread.sleep(2000);
    }
}