2016-03-27 5 views
1

Ich habe versucht, Timeout während der Ausführung von AsyncTask mehr als 1 Minute zu erstellen. Wenn die Zeit abgelaufen ist, sollte mit Notification beendet werden.Wie Timeout für AsyncTask-Ausführung festlegen?

Dies ist mein Code:

private class GetLongLat extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     longlatDialog = new ProgressDialog(MainActivity.this); 
     longlatDialog.setMessage("Fetching Data. Please wait.."); 
     longlatDialog.setCancelable(false); 
     longlatDialog.show(); 

    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 

     GPSTracker gpsTracker; 

     //This is the timer to set time out 
     Timer timer = new Timer(); 
     timer.schedule(new TaskKiller(this), 3000); 
     timer.cancel(); 

     do{ 
      gpsTracker = new GPSTracker(MainActivity.this); 
      gpsTracker.getLocation(); 

     }while(!String.valueOf(gpsTracker.latitude).equals("0.0")); 

     return null; 
    } 

    protected void onCancelled() { 
    // do something, inform user etc. 
     Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show(); 
     System.exit(1); 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 
     if (longlatDialog.isShowing()) 
      longlatDialog.dismiss(); 
    } 

} 

Und das ist eine Klasse in doInBackground genannt, die Zeit bis zu setzen.

class TaskKiller extends TimerTask { 
private AsyncTask<?, ?, ?> mTask; 

    public TaskKiller(AsyncTask<?, ?, ?> task) { 
    this.mTask = task; 
    } 

    public void run() { 
    mTask.cancel(true); 
    } 
} 

Aber wenn ich den Code ausführen, passiert nichts. Ich meine, der Fortschrittsdialog läuft immer sehr lange.

EDIT Ich habe meinen Code bearbeiten GetLongLat so etwas zu nennen:

GetLongLat n = new GetLongLat(); 
n.execute(); 
try { 

    n.get(3000, TimeUnit.MILLISECONDS); 
} catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (ExecutionException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (TimeoutException e) { 
    // TODO Auto-generated catch block 
    Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show(); 
    System.exit(1); 
} 

Aber auch nicht funktioniert.

+0

http: // Stackoverflow.com/questions/7882739/android-setting-a-timeout-for-a-asynctask – Manifest

Antwort

1

Ich glaube, Sie AsyncTask.get verwenden können()

GetLongLat n = new GetLongLat(); 
n.get(30000, TimeUnit.MILLISECONDS); 

Sie die n.get in einem separaten Thread verwenden müssen ..

Editiert: ein weiteres anderes Verfahren aber nicht effizient. ,

GetLongLat n = new GetLongLat(); 
n.execute(); 
Handler handler = new Handler(); 
handler.postDelayed(new Runnable() 
{ 
    @Override 
    public void run() { 
     if (n.getStatus() == AsyncTask.Status.RUNNING) 
      n.cancel(true); 
    } 
}, 30000); 
+0

Ich habe den Code auf der Grundlage Ihrer Antwort bearbeiten. Ich weiß es nicht, aber es funktioniert nicht. @saran –

+0

@SamsulArifin was ist der Fehler/das Problem, dem Sie gegenüberstehen ..? – sharan

+0

und erstellen Sie einen separaten Thread zum Ausführen n.get führen Sie dies nicht im Hauptthread ... – sharan

0

warum löschen Sie den Timer? gleich nach dem Anruf schedule()?

Bricht die Timer und alle geplanten Aufgaben

timer.cancel(); entfernt werden sollte. Überprüfen Sie docs für Abbrechen()

0

Sie können dieses Verhalten auf viele Arten erreichen.

Hier ist ein Beispiel unter Verwendung von CountDownTimer

// Start your AsyncTask 
private YourAsyncTask mTask = new YourAsyncTask().execute(); 

// Run a timer after you started the AsyncTask 
new CountDownTimer(60000, 1000) { 

    public void onTick(long millisUntilFinished) { 
     // Do nothing 
    } 

    public void onFinish() { 
     mTask.cancel(true); 
    } 

}.start(); 

Sie Aufheben der Timer nur, nachdem es zu initiieren. Du kannst es auch so machen. Aber diese Art von beschäftigtem Warten wird überhaupt nicht empfohlen.

@Override 
protected Void doInBackground(Void... arg0) { 

    GPSTracker gpsTracker; 

    //This is the timer to set time out 
    new CountDownTimer(60000, 1000) { 

     public void onTick(long millisUntilFinished) { 
      // Do nothing 
     } 

     public void onFinish() { 
      // Set latitude to zero to finish the while loop outside. 
      // gpsTracker.latitude = "0.0"; // Something like this 
     } 

    }.start(); 

    do{ 
     gpsTracker = new GPSTracker(MainActivity.this); 
     gpsTracker.getLocation(); 

    }while(!String.valueOf(gpsTracker.latitude).equals("0.0")); 

    return null; 
} 
1

Hier ist ein anderer Ansatz. In Ihrer doInBackground Methode können Sie System.currentTimeMillis verwenden, um zu überprüfen, ob 1 Minute abgelaufen ist oder nicht.

protected Void doInBackground(Void... arg0) { 

     GPSTracker gpsTracker; 

     long startTime = System.currentTimeMillis(); 

     do{ 
      gpsTracker = new GPSTracker(MainActivity.this); 
      gpsTracker.getLocation(); 

     }while(!String.valueOf(gpsTracker.latitude).equals("0.0") 
       && ((System.currentTimeMillis() - startTime) <= 60000);//60000 millisecond = 1 minute 

     return null; 
} 

`

+0

dann, wo ich die setzen kann Code zum Beenden einer App, wenn eine Auszeit besteht? –

+0

Wenn die Zeitüberschreitung erreicht ist, wird die while-Schleife automatisch beendet und 'null' wird von' doInBackground'methd zurückgegeben, danach wird 'onPostExecute' aufgerufen und Sie können Ihren Code dort ablegen. –

+0

Ich versuche auch Ihren Code. Und ich denke effizienter und effektiver. Aber ich verwechsle immer noch zwischen timeout und nicht in onPostExute. Hast du eine Idee? –

0

einfach Ihren Code wie folgt ändern und überprüfen, ob Ihre async Aufgabe abgebrochen wird oder nicht bekommen.

  GetLongLat getLongLatAsync = new GetLongLat(); 
      getLongLatAsync.execute(); 
      try { 
      Handler handler = new Handler(); 
      /** 1st method **/ 
      handler.postDelayed(new Runnable() 
      { 
       @Override 
       public void run() { 
       if (getLongLatAsync.getStatus() == AsyncTask.Status.RUNNING) 
        getLongLatAsync.cancel(true); 
       } 
       }, 3000); //3 Seconds 
    /** 1st method ends **/ 
    /** second method */ 
      handler.post(new Runnable() 
      { 
       @Override 
       public void run() { 
     getLongLatAsync.get(3000, TimeUnit.MILLISECONDS);//You should run it in seperated thread or else it will block ui thread. 
    } 
    }); 
/** Second method ends**/ 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (ExecutionException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (TimeoutException e) { 
       // TODO Auto-generated catch block 
       Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show(); 
      } 

und in der onCancelld Methode schreiben Sie Ihre Logik

@Override 
protected void onCancelled() { 
Log.d(TAG,"Asynctask has been cancelled."); 
} 
+0

Ich habe Ihren Code versucht. alles davon. Dann das gleiche Ergebnis. Der Punkt, den ich oben gefragt habe, ist, wenn Benutzer das GPS einschalten, dann laden Sie das lange und Lat automatisch. Aber manchmal hat der Benutzer eine langsame Internetverbindung, also wenn der Benutzer den langen Lat nach 1 Minuten nicht laden kann. Die Apps werden beendet. –

+0

Die genannte Methode sollte funktionieren, es sei denn, Sie tun etwas anderes, weil es für uns arbeitet !!! –

+0

Danke für Ihre Antwort. Ich wurde anders gefunden. http://stackoverflow.com/questions/7882739/android-setting-a-timeout-for-an-asynctask Perfekt funktionieren. Aber dein Code funktioniert auch auf andere Weise. Danke nochmal –

Verwandte Themen