web-dev-qa-db-ja.com

Androidでx分ごとに非同期タスクを実行する方法は?

特定の時間に非同期タスクを実行する方法は? (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" });

    }

    }

これは私のコードであり、完全に正常に動作しますが、バッテリーを消耗する大きな問題はありますか?

40
Shan

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には時間がかからないことに注意してください(UIでのオーディオ再生の位置の更新など)。時間がかかる可能性がある場合(Webへのダウンロードやアップロードなど)、代わりに ScheduledExecutorServicescheduleWithFixedDelay関数を使用する必要があります。

68
inazaruk

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)
29
Jorgesys

asyncTaskの代わりにTimerTaskを使用できます。

例:

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


private class MyTask extends TimerTask {

    public void run(){
      readWebPage();
    }

}
7
Berkay

バッテリーを節約するために電話がスリープモードに移行し、2分間隔で発生する可能性が非常に高い場合、Handler.postDelayed()は予定時刻を逃す可能性があります。このようなアクティビティには、AlarmManagerを使用し、PowerManagerでロックを取得して、AsyncTaskの実行中にスリープ状態に戻らないようにする必要があります。

コードサンプルで私の投稿を参照してください here

また、読みたい場合があります 繰り返しアラームのスケジュール

1
Mixaz

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分ごとに実行し続けます。しかし、instantlyを初めて実行したい場合-およびthenwait-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(); 
_

または、コードが1つのメソッド(この場合は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
_

(^これは最初の例と同じですが、2分ではなく、最初の実行前に0msの遅延があります)

(この答えは@Devashish Mamgainのものに基づいていますが、編集のために詳細を追加しすぎたため、新しいものを追加する必要がありました)

1
Nicofisi

Threadクラスを拡張し、スリープ時間を2000ミリ秒に設定して、runメソッドを呼び出してみてください。それはそれを行う必要があります。

0
Egor

HandlerとTimerTaskでTimeを使用できます

  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
Ishan Fernando

複数のメッセージ(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