2012-03-28 9 views
0

Ich rufe eine AsyncTask auf, um einen zuvor gestarteten Dienst zu stoppen. Aber der ProgressDialog rotiert nicht, während die Asyktask ausgeführt wird. Also ich denke, dass etwas nicht stimmt und ich könnte Probleme mit einem ANR-Fehler bekommen.AsyncTask scheint nicht wirklich async zu funktionieren

Irgendwelche Ideen?

new asyncTaskZieladresse().execute(); 

public class asyncTaskZieladresse extends AsyncTask<Void, Integer, Void> { 
    int progress; 
    @Override 
    protected void onPostExecute(Void result) { 
     // TODO Auto-generated method stub 
     final Spinner Fahrerauswahl = (Spinner)findViewById(R.id.spinner1); 
     final Spinner Fahrzeugauswahl = (Spinner)findViewById(R.id.spinner2); 
     final Spinner Nutzungsartauswahl = (Spinner)findViewById(R.id.spinner3); 
     Cursor mcursor = (Cursor) Fahrerauswahl.getSelectedItem(); 
     Fahrer = mcursor.getString(mcursor.getColumnIndexOrThrow("name")); 
     FahrerID = mcursor.getString(mcursor.getColumnIndexOrThrow("_id")); 
     mcursor.close(); 
     Cursor mcursor1 = (Cursor) Fahrzeugauswahl.getSelectedItem(); 
     Kennzeichen = mcursor1.getString(mcursor1.getColumnIndexOrThrow("fahrzeug_kennzeichen")); 
     KennzeichenID = mcursor1.getString(mcursor1.getColumnIndexOrThrow("_id")); 
     mcursor1.close(); 
     Cursor mcursor2 = (Cursor) Nutzungsartauswahl.getSelectedItem(); 
     Nutzungsart = mcursor2.getString(mcursor2.getColumnIndexOrThrow("nutzungsart")); 
     NutzungsartID = mcursor2.getString(mcursor2.getColumnIndexOrThrow("_id")); 
     mcursor2.close(); 
     VariablenUebergebenGpsFahrt(); 
     progressDialog.dismiss(); 
    } 
    @Override 
    protected void onPreExecute() { 
     // TODO Auto-generated method stub 
     progressDialog = ProgressDialog.show(Main.this, "GPS", "Ziel-Standort wird ermittelt..."); 
    } 
    @Override 
    protected void onProgressUpdate(Integer... values) { 
     // TODO Auto-generated method stub 
    } 
    @Override 
    protected Void doInBackground(Void... arg0) { 
     // TODO Auto-generated method stub 
     stopService(new Intent(Main.this, GPSService.class)); 
     return null; 
    }  

}

+0

Da Sie nichts im Hintergrund tun, was ist der Sinn einer 'AsyncTask'? Es ist wie das Forking eines Threads mit einer leeren 'run()' Methode. – CommonsWare

+0

Ich habe das Problem, dass es manchmal sehr lange dauert, bis die nächste Aktivität aufgerufen wird. Was ich mache, ist einen Dienst zu stoppen (in den Diensten onDestroy() sind einige Werte in sharedprefs geschrieben, so dass ich die gesammelten Werte aus dem Dienst lesen kann, nachdem der Dienst in einer anderen Aktivität gestoppt wurde), und dann die ausgewählten Werte von Spinner geben die Spinner-Werte über intent.putextra ab und rufen schließlich die neue Aktivität über startActivity (intent) auf. Für mich hat es den Anschein, dass der stopService viel Zeit in Anspruch genommen hat, also habe ich versucht, ihn in der AsyncTask zu stoppen. Bin ich falsch? – venni

+0

'stopService()' sollte gut unter einer Millisekunde dauern. Es tut nichts direkt - das tatsächliche Stoppen des Dienstes geschieht asynchron. – CommonsWare

Antwort

1

Das ist der Grund getan, warum ich versucht haben, den Dienst mit dem AsyncTask zu stoppen .

Das wird nicht helfen, wie ich versucht habe, in den Kommentaren zu Ihrer Frage zu erklären. Wenn onDestroy() zu lange dauert, müssen Sie diese Arbeit früher und in einem Hintergrundthread erledigen. Den Aufruf stopService() in einen Hintergrundthread zu setzen ist völlig sinnlos.

Der Dienst selbst läuft bereits im Hintergrund und nicht im UI-Thread.

Nein, ist es nicht.

onDestroy() wird im Hauptanwendungs-Thread aufgerufen. Immer.

Ihr Service könnte auch haben einen Hintergrund-Thread seiner eigenen für andere Arbeiten, aber die Lifecycle-Methoden (onCreate(), onStartCommand(), onBind() und onDestroy()) sind immer auf der Hauptanwendung Thread aufgerufen.

Also, wenn das Stoppen des Dienstes lange gedauert hat, warum hängt die App?

Weil Sie zu viel Arbeit in onDestroy() tun.

Der Dienst und der Befehl, der auf die Rückgabe des angehaltenen Dienstes wartet, werden im UI-Thread nicht ausgeführt.

onDestroy() wird im Hauptanwendungs-Thread (a.k.a., "UI-thread") aufgerufen.


UPDATE basierend auf ersten Kommentar:

Als ich onDestroy() innerhalb des Service

Sie nie onDestroy() rufen nennen. Android ruft onDestroy() an. Du bist kein Android.

Die onDestroy() wird nicht innerhalb des Dienstes für den Dienst selbst aufgerufen, sondern im Hauptthread?

Sie scheinen zu denken, dass ein Dienst ein Thread ist. Es ist nicht. Sie können dies erkennen, indem Sie the documentation lesen ("Beachten Sie, dass Dienste wie andere Anwendungsobjekte im Hauptthread ihres Hostingprozesses ausgeführt werden."). Bitte lesen Sie die Dokumentation.

+0

OK, nur um sicher zu gehen, dass ich es richtig verstehe. Wenn ich onDestroy() innerhalb des Dienstes (nicht im Main) aufruft, wird onDestroy() nicht innerhalb des Dienstes für den Dienst selbst aufgerufen, sondern in der Hauptthread? Meiner Meinung nach hat der Dienst eine onDestroy() für den Dienst selbst. Unabhängig von der Aktivität. Wenn ja, wie bekomme ich den Stop-Befehl im Dienst, um meine Arbeit zu erledigen, bevor der onDestroy() des Dienstes aufgerufen wird "Im Moment ist der Aufruf von onDestroy() im Dienst der einzige Weg, um zu erfahren, dass mein Dienst vom Benutzer gestoppt wird. Ich muss einige sharedprefs auf den Stoppdienst schreiben. – venni

1

Es ist schwer zu verstehen, warum die ANR, aber das viele Sachen scheinen Sie in den onPostExecute() Exec auf den doInBackground() bewegt werden kann. Android-Entwickler schlagen vor, SQL-Lite-Operation (Content Provider) und jede Schwergewichtsoperation asynchron auszuführen.

1

Alle Code in OnPostExecute wird auf dem UI-Thread ausgeführt werden, wird nur der Code in doInBackground wird im Hintergrund ...