15

Ich verwende AsyncTask, um einige Hintergrundberechnungen durchzuführen, aber ich finde keine korrekte Möglichkeit, Ausnahmen zu behandeln. Derzeit bin ich mit dem folgenden Code:Asynctask Fehlerbehandlung

private class MyTask extends AsyncTask<String, Void, String> 
{ 
    private int e = 0; 

    @Override 
    protected String doInBackground(String... params) 
    { 
     try 
     { 
      URL url = new URL("http://www.example.com/"); 
     } 
     catch (MalformedURLException e) 
     { 
      e = 1; 
     } 

     // Other code here... 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String result) 
    { 
     if (e == 1) 
      Log.i("Some Tag", "An error occurred."); 

     // Perform post processing here... 
    } 
} 

Ich glaube, dass die Variable e maye sowohl von dem Haupt- und Worker-Thread geschrieben/zugegriffen werden. Wie ich weiß, dass onPostExecute() wird nur ausgeführt werden, nachdem doInBackround() beendet ist, kann ich keine Synchronisation weglassen?

Ist das ein schlechter Code? Gibt es einen vereinbarten oder korrekten Weg, Ausnahmen in einer AsyncTask zu behandeln?

+1

möglich Duplikat [AsyncTask und Fehler auf Android Handhabung] (http://stackoverflow.com/questions/1739515/asynctask-and-error-handling-on-android) – blahdiblah

Antwort

3

Ich habe das in meinen Apps gemacht, ich denke es gibt keinen besseren Weg.

Sie können auch Mark Murphy answer darüber lesen.

+0

Wenn es verursacht keine Probleme dann bin ich glücklich! – Leo

2

Dies funktioniert garantiert, auch auf SMP-Architektur. Die gesamte Synchronisation ist für Sie erledigt. Es wäre jedoch besser, den Rückgabewert dafür zu verwenden.

+1

Im eigentlichen Code verwende ich ein benutzerdefiniertes Objekt als Rückgabetyp, der sich nicht wirklich dazu eignet, Ausnahmeinformationen zu halten. Ich nehme an, dass ich die 'onPostExecute()' Funktion nicht sehr leicht überladen kann? – Leo

+4

Zuerst muss doInBackground ein Objekt des gleichen Typs wie der Parameter in onPostExecute() zurückgeben. Dann können Sie einfach eine benutzerdefinierte Klasse erstellen, um die result + -Ausnahme zu kapseln: class ResultHolder {Exception e; MyResult r; } –

2

Ich denke, Ihr Code würde zu dem Job, aber es ist bereits eine Art von Fehlerbehandlung in die AsyncTask Klasse eingebaut.

Sie können vermeiden, eine zusätzliche Variable zu verwenden, indem Sie die cancel()-Methode und ihre Handler-Methode onCancelled() verwenden. Wenn Sie cancel aufrufen innerhalb der Methode die onCancelled-Methode im UI-Thread. Ob Sie cancel (true) oder cancel (false) aufrufen, hängt von Ihren Anforderungen ab.


private class MyTask extends AsyncTask<String, Void, String> 
{  
    @Override 
    protected NewsItem doInBackground(String... params) 
    { 
     try 
     { 
      URL url = new URL("http://www.example.com/"); 
     } 
     catch (MalformedURLException e) 
     { 
      cancel(false/true); 
     } 

     // Other code here... 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String result) 
    {    
     // Perform successful post processing here... 
    } 

    @Override 
    protected void onCancelled() { 
     super.onCancelled(); 
     // Perform error post processing here... 
    } 
} 
+0

Diese Methode funktioniert nur, wenn wir einen Typ von Ausnahme haben. In meinem vollständigen Code gibt es mehrere Dinge, die schief gehen können und sie müssen anders gehandhabt werden. – Leo

+0

Warum? Sie können der try-Klausel so viel Catch-Klasse hinzufügen, wie Sie möchten. In jeder catch-Anweisung können Sie die cancel-Methode aufrufen. Sie können auch fangen (Ausnahme e), die alle Arten von Ausnahmen abfängt. Habe ich dich richtig verstanden, Leo? Ist es jedoch empfehlenswert, cancel() aufzurufen, wenn Exceptions ausgelöst werden oder gibt es eine andere Möglichkeit, die Exception-Behandlung zu implementieren? – OneWorld

+0

Die Methode cancel(), mit der der Fehler behandelt wird, liegt sehr nahe bei dem, was tatsächlich passiert. Ihre Verarbeitung wurde aufgrund eines Fehlers abgebrochen. Sie können immer noch einen Zustand auf der ASyncTask speichern, der vom Benutzeroberflächenthread gelesen werden kann, um weitere Informationen über den Fehler zu erhalten. – DukeMe