web-dev-qa-db-ja.com

一定の時間間隔の後に非同期タスクを繰り返し実行する方法

タイマーのように一定の時間間隔後に非同期タスクを繰り返し実行する方法...実際には、サーバーからすべての最新の未読グリーティングを自動的にダウンロードするアプリケーションを開発しています。そのために、いくつかの修正後にサーバーからの更新を確認する必要があります時間間隔....タイマーを介して簡単に実行できることはわかっていますが、Androidアプリケーションの場合はより効率的だと思う非同期タスクを使用したいと思います。

59
Waseem
public void callAsynchronousTask() {
    final Handler handler = new Handler();
    Timer timer = new Timer();
    TimerTask doAsynchronousTask = new TimerTask() {       
        @Override
        public void run() {
            handler.post(new Runnable() {
                public void run() {       
                    try {
                        PerformBackgroundTask performBackgroundTask = new PerformBackgroundTask();
                        // PerformBackgroundTask this class is the class that extends AsynchTask 
                        performBackgroundTask.execute();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                    }
                }
            });
        }
    };
    timer.schedule(doAsynchronousTask, 0, 50000); //execute in every 50000 ms
}
121
Rasel
  //Every 10000 ms   
       private void doSomethingRepeatedly() {
      Timer timer = new Timer();
      timer.scheduleAtFixedRate( new TimerTask() {
            public void run() {

                  try{

                     new SendToServer().execute(); 

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

             }
            }, 0, 10000);
                     }
6
ritesh4326

alarm Managerを使用してサービスを作成し、スケジュールする方が効率的ではないでしょうか?

2
Richie

ハンドラーだけができます:

private int m_interval = 5000; // 5 seconds by default, can be changed later
private Handle m_handler;

@Override
protected void onCreate(Bundle bundle)
{
  ...
  m_handler = new Handler();
}

Runnable m_statusChecker = new Runnable()
{
     @Override 
     public void run() {
          updateStatus(); //this function can change value of m_interval.
          m_handler.postDelayed(m_statusChecker, m_interval);
     }
}

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

void stopRepeatingTask()
{
    m_handler.removeCallback(m_statusChecker);
}

ただし、このフレームワークを確認することをお勧めします。 http://code.google.com/intl/de-DE/Android/c2dm/ 別のアプローチです:サーバーは、準備ができています(したがって、帯域幅とパフォーマンスを節約します:))

2
kikoso

受け入れられた答えには問題があります。 TimerTask()を使用して、ハンドラーを介して非同期タスクをアクティブ化するのは悪い考えです。方向の変更時には、タイマーとハンドラーの呼び出しもキャンセルすることを忘れないでください。そうでない場合は、各ローテーションで非同期タスクを繰り返し呼び出します。これにより、アプリケーションはX時間ではなくサーバーを爆破します(rest http getリクエストの場合)。最終的に、呼び出しは毎秒多くの呼び出しのインスタンスになります。 (画面の回転数に応じて多くのタイマーがあるため)。バックグラウンドスレッドで実行されているアクティビティとタスクが重い場合、アプリケーションがクラッシュする可能性があります。タイマーを使用する場合は、タイマーをクラスメンバーにして、onStop()をキャンセルします。

            TimerTask mDoAsynchronousTask;


            @Override
            public void onStop(){
               super.onStop();                 
               mDoAsynchronousTask.cancel();
               mHandler.removeCallbacks(null);
               ... 
            }


          public void callAsynchronousTask(final boolean stopTimer) {
             Timer timer = new Timer();
             mDoAsynchronousTask = new TimerTask() {
                 @Override
                 public void run() {
                     mHandler.post(new Runnable() {
                 ...

代わりに、非同期タスクを回避し、その後スケジューラサービスを使用して非同期タスクを実行する必要がある場合。またはこの素敵なアイデアのようなアプリケーションクラス: https://fattybeagle.com/2011/02/15/Android-asynctasks-during-a-screen-rotation-part-ii/

または、単純なハンドラーを使用し(タイマーを使用せず、postDelayedを使用するだけです)、非同期タスクonStop()をキャンセルして呼び出すことも有効です。このコードはpostDelayedを使用して正常に機能します。

           public class MainActivity extends AppCompatActivity {

                  MyAsync myAsync = new MyAsync();

                  private final Handler mSendSSLMessageHandler = new Handler();
                  private final Runnable mSendSSLRunnable = new Runnable(){

                  ..


                 @Override
                 protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_main);
                    ConnectivityManager connMgr = (ConnectivityManager)   
                    getSystemService(Context.CONNECTIVITY_SERVICE);
                    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
                    if (networkInfo != null && networkInfo.isConnected()) {
                            mSendSSLMessageHandler.post(mSendSSLRunnable);
                    }else
                    ..

                  @Override
                  public void onStop(){
                   super.onStop();
                      if ( progressDialog!=null && progressDialog.isShowing() ){
                           progressDialog.dismiss();
                      }
                    mSendSSLMessageHandler.removeCallbacks(mSendSSLRunnable);
                    myAsync.cancel(false);
                   }


              private final Runnable mSendSSLRunnable = new Runnable(){
              @Override
                public void run(){
                   try {
                    myAsync = new MyAsync();
                    myAsync.execute();
                   } catch (Exception e) {
                      // TODO Auto-generated catch block
                   }
                   mSendSSLMessageHandler.postDelayed(mSendSSLRunnable, 5000);
               }
          };


          class MyAsync extends AsyncTask<Void, Void, String> {
                boolean running = true;

                @Override
                protected void onPreExecute() {
                super.onPreExecute();
                  progressDialog = ProgressDialog.show               
                  (MainActivity.this, "downloading", "please wait");
                }

              @Override
              protected String doInBackground(Void... voids) {
                 if (!running) {
                       return null;
                  }
                 String result = null;
                 try{
                 URL url = new URL("http://192...");
                 HttpURLConnection urlConnection = (HttpURLConnection)            
                 url.openConnection();
                 InputStream in = new BufferedInputStream (urlConnection.getInputStream());
                 result = inputStreamToString(in);
                }catch(Exception e){
                   e.printStackTrace();
                }

               return result;
           }


    @Override
    protected void onCancelled() {
        boolean running = false;
    }
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        progressDialog.dismiss();
        try {

              ..


        } catch (JSONException e) {
            textView.append("json is invalid");
            e.printStackTrace();
        }

    }


}
0
Udi Reshef