wake-up-neo.com

So führen Sie den Async-Task nach festgelegten Zeitintervallen wiederholt aus

Wie mache ich, dass Async-Task nach einem bestimmten Zeitintervall wie Timer ausgeführt wird? Eigentlich entwickle ich eine Anwendung, die automatisch die neuesten ungelesenen Begrüßungen vom Server herunterlädt. Zu diesem Zweck muss ich nach einigen Korrekturen nach Updates vom Server suchen Zeitintervalle .... Ich weiß, dass dies einfach durch einen Timer erledigt werden kann, aber ich möchte eine asynchrone Task verwenden, die meiner Meinung nach für Android-Anwendungen effizienter ist. 

57
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
}
118
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

wäre es nicht effizienter, einen Dienst zu erstellen und diesen über Alarm Manager zu planen?

2
Richie

Sie können nur einen Handler:

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

Ich würde Ihnen jedoch empfehlen, dieses Framework zu überprüfen: http://code.google.com/intl/de-DE/Android/c2dm/ Anders ausgedrückt: Der Server benachrichtigt das Telefon, wenn etwas bereit ist So sparen Sie etwas Bandbreite und Leistung :))

2
kikoso

Die akzeptierte Antwort ist problematisch. Die Verwendung von TimerTask () zum Aktivieren einer asynchronen Task über einen Handler ist eine schlechte Idee. Beim Orientierungswechsel müssen Sie daran denken, auch den Timer und die Handleraufrufe abzubrechen. Wenn nicht, wird die async-Task bei jeder Rotation immer wieder aufgerufen. Die Anwendung wird den Server in die Luft sprengen (wenn es sich nicht um HTTP-Abrufanforderung handelt) und nicht um die X-Zeit - möglicherweise werden die Aufrufe viele Aufrufe auf jede Sekunde. (weil es viele Timer gibt, abhängig von der Anzahl der Bildschirmdrehungen). Wenn die Aktivität und die Aufgabe, die im Hintergrund ausgeführt wird, schwer sind, wird die Anwendung möglicherweise zerstört. Wenn Sie den Timer verwenden, machen Sie ihn zu einer Klasse memebr und brechen Sie ihn bei onStop () ab:

            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() {
                 ...

Versuchen Sie stattdessen, eine asynchrone Task zu vermeiden, und wenn Sie dann den Scheduler-Dienst verwenden müssen, um die async-Task auszuführen. oder die Anwendungsklasse wie in dieser Nizza Idee: https://fattybeagle.com/2011/02/15/Android-asynctasks-during-a-screen-rotation-part-ii/

Oder verwenden Sie einen einfachen Handler (ohne den Timer verwenden Sie einfach postDelayed). Außerdem empfiehlt es sich, die async-Task auf onStop () abzubrechen. Dieser Code funktioniert gut mit 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