3 Stimmen

Warum wird eine AsyncTask nicht gestartet, wenn sie wiederholt gestartet/gestoppt wird?

Also, ich habe ein Problem in meinem Spiel zu debuggen, wo, wenn ich starten, dann stoppen Sie es wiederholt, ich habe bemerkt, dass manchmal eine Asynctask scheint nicht gestartet werden, auch wenn ich das Richtige zu tun scheinen, um es zu starten. Ich habe eine Menge unnötigen Code entfernt, um zu zeigen, was passiert, aber im Grunde sehe ich, dass ich dabei bin, eine Asynctask zu starten, aber die Aufgabe wird nie gestartet.

public void onStart()
{
    super.onStart();
    Log.d(TAG,"About to execute");
    Play_level.execute();
}

AsyncTask<Void,Integer,Integer> Play_level=new AsyncTask<Void, Integer, Integer>(){
     protected void onProgressUpdate(Integer ...time) {
            //Stuff goes in here.
     }
    @Override
    protected Integer doInBackground(Void... params) {
        Log.d(TAG,"In Task");
    }

};

Und das Logcat zeigt:

03-10 19:28:16.983: D/Level(1535): About to execute
03-10 19:28:17.503: D/Level(1535): onStop()
03-10 19:28:17.993: D/Level(1535): onPause()
03-10 19:28:19.174: D/AJEG(1535): Starting Tongue
03-10 19:28:19.313: D/Level(1535): ImageList Previously Loaded
03-10 19:28:19.313: D/Level(1535): About to execute
03-10 19:28:19.853: D/Level(1535): onStop()
03-10 19:28:20.283: D/Level(1535): onPause()
03-10 19:28:21.464: D/AJEG(1535): Starting Tongue
03-10 19:28:21.604: D/Level(1535): ImageList Previously Loaded
03-10 19:28:21.604: D/Level(1535): About to execute
03-10 19:28:22.134: D/Level(1535): onStop()
03-10 19:28:22.404: D/Level(1535): onPause()
03-10 19:28:23.504: D/AJEG(1535): Starting Tongue
03-10 19:28:23.644: D/Level(1535): ImageList Previously Loaded
03-10 19:28:23.644: D/Level(1535): About to execute
03-10 19:28:24.184: D/Level(1535): onStop()

Außerdem kann der Code offenbar auch durch erneutes Eingeben der Aufgabe nicht neu gestartet werden, wie der letzte Textabschnitt zeigt.

Um den Kontext zu verdeutlichen: Starting Tongue wird in der onStart() der übergeordneten Aktivität (AJEG) abgespielt, Level ist der Name der Aktivität, die ich gerade starte. Der ImageList-Befehl kann getrost ignoriert werden, aber ich habe ihn der Vollständigkeit halber eingefügt. Teil der doInBackground enthält den Text "Starting Level _ ", wobei _ ist die Ebene, die gerade gestartet wird. onStop() und onPause() sind in der Methode, um zu zeigen, wann onStop() y onPause() in der Aufgabe Level auftreten.

5voto

PearsonArtPhoto Punkte 37354

Die Lösung des Problems lautet also wie folgt dieser Blog-Artikel :

AsyncTask verwendet eine statische interne Arbeitswarteschlange mit einer harten 10 Elementen

Also, im Wesentlichen hatte ich eine AsyncTask, die nie beendet, um den Betrag von 10, durch neu starten meine Thread so viel. Um dies zu umgehen, tat ich das folgende:

  1. Ich habe die AsyncTask in eine Klasse umgewandelt und sichergestellt, dass nur eine Instanz ausgeführt wird, wie mah vorgeschlagen hat.
  2. Ich habe die Aufgabe im Befehl onStop() abgebrochen, wie Mike D. in seinem Kommentar vorgeschlagen hat.
  3. Ich habe sichergestellt, dass ich prüfe, ob die ASyncTask in der doInBackground .

Das Ergebnis sieht in etwa so aus:

private LevelPlay Play_level;

public void onStop()
{
    super.onStop();
    Play_level.cancel(true);
}

public void onStart()
{
    super.onStart();
    Play_level=new LevelPlay();
    Play_level.execute();
}

class LevelPlay extends AsyncTask<Void, Integer, Integer>
{
     protected void onProgressUpdate(Integer ...time) {
     }
    @Override
    protected Integer doInBackground(Void... params) {
        Log.d(TAG,"In Task");
            Boolean keepRunning=true;
        while(keepRunning && !isCancelled ())
        {
                 //DoStuffHere
        }
     }
}

3voto

Hier ist der Code, der bei mir funktioniert:

public class ImageActivity extends Activity {

    private Thread worker;

    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.main);

        worker = new Thread(new Runnable(){

            private void updateUI(final List<Object> list)
            {
                if(worker.isInterrupted()){
                    return;
                }
                runOnUiThread(new Runnable(){

                    @Override
                    public void run()
                    {
                        // Update view and remove loading spinner etc...
                    }
                });
            }

            private List<Object> download()
            {
                // Simulate download
                SystemClock.sleep(1000);
                return new ArrayList<Object>();
            }

            @Override
            public void run()
            {
                Log.d(TAG, "Thread run()");
                updateUI(download());
            }

        });
        worker.start(); }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        worker.interrupt();
    }
}

Und die Einschränkung bei AsyncTask

Ich hoffe, es hilft Ihnen.

1voto

Mike D Punkte 4858

Angenommen, Sie sprechen von der onStart() Methode eines Activity kann es daran liegen, dass Ihre Anwendung nicht aus dem Speicher entfernt wurde, als Sie zu ihr zurückkehrten, was bedeutet, dass Ihre onStart() Methode wird wahrscheinlich nicht aufgerufen. Vielleicht sollten Sie die Verwendung von onResume() o onRestart() (oder vielleicht beides), und möglicherweise die AsyncTask in onPause() . Das würde auch bedeuten, dass Sie in Ihrer Hintergrundaufgabe prüfen sollten, ob sie abgebrochen wurde.

Zur Frage, warum das passiert, siehe die Antwort von mah.

Lebenszyklus einer Aktivität .

AsyncTask .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X