59

如何让异步任务在某个时间间隔后重复执行,就像定时器一样...实际上我正在开发一个应用程序,它将自动从服务器下载所有最新的未读问候语,为此我必须在一些修复后检查来自服务器的更新时间间隔....我知道这可以通过计时器轻松完成,但我想使用我认为对 android 应用程序更有效的异步任务。

4

5 回答 5

123
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
}
于 2011-06-30T08:52:01.870 回答
6
  //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);
                     }
于 2014-02-26T13:33:26.833 回答
2

你可以只是一个处理程序:

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/带宽和性能:))

于 2011-06-30T08:25:30.320 回答
2

通过警报管理器创建服务并安排它不是更有效吗?

于 2012-07-12T05:10:55.307 回答
1

接受的答案是有问题的。使用 TimerTask() 通过处理程序激活异步任务是一个坏主意。在方向更改时,您必须记住取消计时器和处理程序调用。如果不是,它将在每次轮换时一次又一次地调用异步任务。这将导致应用程序炸毁服务器(如果这是休息 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();
        }

    }


}
于 2018-10-03T15:39:20.630 回答