Как выполнить асинхронную задачу повторно после фиксированных временных интервалов


Как сделать асинхронную задачу повторно выполнить через некоторый интервал времени, как таймер...На самом деле я разрабатываю приложение, которое будет автоматически загружать все последние непрочитанные приветствия с сервера, и для этого мне нужно проверить наличие обновлений с сервера через определенные промежутки времени....Я знаю, что это можно легко сделать с помощью таймера, но я хочу использовать асинхронную задачу, которая, по моему мнению, более эффективна для приложений android.

5 57

5 ответов:

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

вы можете просто обработчик:

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/ это другой подход: сервер будет уведомлять телефон, когда что-то будет готово (таким образом, сохраняя некоторую пропускную способность и производительность:))

не было бы более эффективным создать сервис и запланировать его через Alarm Manager?

принятый ответ проблематичен. Использование TimerTask () для активации асинхронной задачи через обработчик-плохая идея. при повороте вы должны помнить, чтобы отменить также таймер и обработчик звонков. если нет, то он будет вызывать асинхронную задачу снова и снова на каждом повороте. Это приведет к тому, что приложение взорвет сервер (если это запрос rest http get) вместо времени X - в конечном итоге вызовы будут экземпляром много вызовов в каждую секунду. (потому что там будет много таймеров по количество оборотов экрана). Это может раздавить приложение, если активность и задача, выполняемая в фоновом потоке, являются тяжелыми. если вы используете таймер, то сделайте его классом memebr и отмените его 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();
        }

    }


}