Android: Wie kann ich Parameter an onPreExecute () von AsyncTask übergeben?


116

Ich verwende eine AsyncTaskzum Laden von Operationen, die ich als innere Klasse implementiert habe.

In onPreExecute()zeige ich einen Ladedialog, in dem ich mich dann wieder verstecke onPostExecute(). Bei einigen Ladevorgängen weiß ich jedoch im Voraus, dass sie sehr schnell abgeschlossen werden, sodass ich den Ladedialog nicht anzeigen möchte.

Ich wollte dies durch einen booleschen Parameter anzeigen, an den ich übergeben könnte, onPreExecute()aber anscheinend werden aus irgendeinem Grund onPreExecute()keine Parameter verwendet.

Die offensichtliche Problemumgehung wäre wahrscheinlich, ein Mitgliedsfeld in meiner AsyncTask oder in der äußeren Klasse zu erstellen, das ich vor jedem Ladevorgang festlegen müsste, aber das scheint nicht sehr elegant zu sein. Gibt es einen besseren Weg, dies zu tun?

Antworten:


231

Sie können den Konstruktor überschreiben. Etwas wie:

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

    public MyAsyncTask(boolean showLoading) {
        super();
        // do stuff
    }

    // doInBackground() et al.
}

Führen Sie dann beim Aufrufen der Aufgabe Folgendes aus:

new MyAsyncTask(true).execute(maybe_other_params);

Bearbeiten: Dies ist nützlicher als das Erstellen von Elementvariablen, da es den Aufgabenaufruf vereinfacht. Vergleichen Sie den obigen Code mit:

MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();

3
Genau das habe ich jetzt getan. Ich brauche noch eine Mitgliedsvariable, aber in der AsyncTask und nicht in der äußeren Klasse, wenn Sie das meinen. Folgendes habe ich getan: private Klasse MyAsyncTask erweitert AsyncTask <Void, Void, Void> {private boolean showLoading; public MyAsyncTask (boolean showLoading) {super (); this.showLoading = showLoading; // mache Sachen} protected void onPreExecute () {if (showLoading) {// ...}} // doInBackground () et al. }
Steven Meliopoulos

1
Ja, das war so ziemlich die Idee :)
Felix

1
Im AsynkTask-Konstruktor benötigen Sie eigentlich kein super ().
Ostergaard

62

1) Für mich ist dies die einfachste Möglichkeit, Parameter an eine asynchrone Aufgabe zu übergeben

// To call the async task do it like this
Boolean[] myTaskParams = { true, true, true };
myAsyncTask = new myAsyncTask ().execute(myTaskParams);

Deklarieren und verwenden Sie die asynchrone Aufgabe wie hier

private class myAsyncTask extends AsyncTask<Boolean, Void, Void> {

    @Override
    protected Void doInBackground(Boolean...pParams) 
    {
        Boolean param1, param2, param3;

        //

          param1=pParams[0];    
          param2=pParams[1];
          param3=pParams[2];    
      ....
}                           

2) Übergeben von Methoden an die Async-Task Um zu vermeiden, dass die Async-Task-Infrastruktur (Thread, Messagenhandler, ...) mehrmals codiert wird, können Sie die Methoden, die in Ihrer Async-Task ausgeführt werden sollen, als Parameter übergeben. Das folgende Beispiel beschreibt diesen Ansatz. Außerdem müssen Sie möglicherweise die asynchrone Task in eine Unterklasse unterteilen, um die Initialisierungsparameter im Konstruktor zu übergeben.

 /* Generic Async Task    */
interface MyGenericMethod {
    int execute(String param);
}

protected class testtask extends AsyncTask<MyGenericMethod, Void, Void>
{
    public String mParam;                           // member variable to parameterize the function
    @Override
    protected Void doInBackground(MyGenericMethod... params) {
        //  do something here
        params[0].execute("Myparameter");
        return null;
    }       
}

// to start the asynctask do something like that
public void startAsyncTask()
{
    // 
    AsyncTask<MyGenericMethod, Void, Void>  mytest = new testtask().execute(new MyGenericMethod() {
        public int execute(String param) {
            //body
            return 1;
        }
    });     
}

11

Warum, wie und welche Parameter an Asynctask <> übergeben werden, siehe Details hier . Ich denke, das ist die beste Erklärung.

In der Android-Dokumentation von Google heißt es:

Eine asynchrone Aufgabe wird durch drei generische Typen definiert, die als Parameter, Fortschritt und Ergebnis bezeichnet werden, und vier Schritte, die als onPreExecute, doInBackground, onProgressUpdate und onPostExecute bezeichnet werden.

Generische Typen von AsyncTask:

Die drei von einer asynchronen Task verwendeten Typen sind die folgenden:

Params, der Typ der Parameter, die bei der Ausführung an die Task gesendet werden. Fortschritt, der Typ der Fortschrittseinheiten, die während der Hintergrundberechnung veröffentlicht wurden. Ergebnis, der Typ des Ergebnisses der Hintergrundberechnung. Nicht alle Typen werden immer von einer asynchronen Aufgabe verwendet. Um einen Typ als nicht verwendet zu markieren, verwenden Sie einfach den Typ Void:

 private class MyTask extends AsyncTask<Void, Void, Void> { ... }

Sie können weiter verweisen: http://developer.android.com/reference/android/os/AsyncTask.html

Oder Sie können die Rolle von AsyncTask anhand des Blogs von Sankar-Ganesh klären

Nun, die Struktur einer typischen AsyncTask-Klasse sieht folgendermaßen aus:

private class MyTask extends AsyncTask<X, Y, Z>

    protected void onPreExecute(){ 

    } 

Diese Methode wird ausgeführt, bevor der neue Thread gestartet wird. Es gibt keine Eingabe- / Ausgabewerte. Initialisieren Sie also einfach Variablen oder was auch immer Sie tun müssen.

protected Z doInBackground(X...x){

}

Die wichtigste Methode in der AsyncTask-Klasse. Sie müssen hier alle Dinge, die Sie tun möchten, in den Hintergrund stellen, in einen anderen Thread als den Haupt-Thread. Hier haben wir als Eingabewert ein Array von Objekten vom Typ "X" (sehen Sie in der Kopfzeile? Wir haben "... erweitert AsyncTask" Dies sind die TYPEN der Eingabeparameter) und geben ein Objekt vom Typ zurück "Z".

protected void onProgressUpdate (Y y) {

} Diese Methode wird mit der Methode PublishProgress (y) aufgerufen. Sie wird normalerweise verwendet, wenn Sie Fortschritte oder Informationen im Hauptbildschirm anzeigen möchten, z. B. einen Fortschrittsbalken, der den Fortschritt des Vorgangs im Hintergrund anzeigt.

geschützte Leere onPostExecute (Z z) {

} Diese Methode wird aufgerufen, nachdem die Operation im Hintergrund ausgeführt wurde. Als Eingabeparameter erhalten Sie den Ausgabeparameter der Methode doInBackground.

Was ist mit den X-, Y- und Z-Typen?

Wie Sie aus der obigen Struktur ableiten können:

X  The type of the input variables value you want to set to the background process. This can be an array of objects.

 Y  The type of the objects you are going to enter in the onProgressUpdate method.

 Z  The type of the result from the operations you have done in the background process.

Wie nennen wir diese Aufgabe von einer externen Klasse? Nur mit den folgenden zwei Zeilen:

MyTask myTask = new MyTask();

myTask.execute(x);

Wobei x der Eingabeparameter vom Typ X ist.

Sobald wir unsere Aufgabe ausgeführt haben, können wir ihren Status von „außen“ herausfinden. Verwenden der Methode "getStatus ()".

myTask.getStatus (); und wir können den folgenden Status erhalten:

RUNNING - Zeigt an, dass die Aufgabe ausgeführt wird.

PENDING - Zeigt an, dass die Aufgabe noch nicht ausgeführt wurde.

FINISHED - Zeigt an, dass onPostExecute (Z) beendet wurde.

Hinweise zur Verwendung von AsyncTask

Rufen Sie die Methoden onPreExecute, doInBackground und onPostExecute nicht manuell auf. Dies erfolgt automatisch durch das System.

Sie können eine AsyncTask nicht in einer anderen AsyncTask oder einem anderen Thread aufrufen. Der Aufruf der Methode execute muss im UI-Thread erfolgen.

Die Methode onPostExecute wird im UI-Thread ausgeführt (hier können Sie eine andere AsyncTask aufrufen!).

Die Eingabeparameter der Aufgabe können ein Objektarray sein. Auf diese Weise können Sie beliebige Objekte und Typen einfügen.


4

Sie können den Parameter entweder im Taskkonstruktor übergeben oder beim Aufrufen execute ausführen:

AsyncTask<Object, Void, MyTaskResult>

Der erste Parameter (Objekt) wird in doInBackground übergeben. Der dritte Parameter (MyTaskResult) wird von doInBackground zurückgegeben. Sie können sie in die gewünschten Typen ändern. Die drei Punkte bedeuten, dass null oder mehr Objekte (oder ein Array davon) als Argument (e) übergeben werden können.

public class MyActivity extends AppCompatActivity {

    TextView textView1;
    TextView textView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);    
        textView1 = (TextView) findViewById(R.id.textView1);
        textView2 = (TextView) findViewById(R.id.textView2);

        String input1 = "test";
        boolean input2 = true;
        int input3 = 100;
        long input4 = 100000000;

        new MyTask(input3, input4).execute(input1, input2);
    }

    private class MyTaskResult {
        String text1;
        String text2;
    }

    private class MyTask extends AsyncTask<Object, Void, MyTaskResult> {
        private String val1;
        private boolean val2;
        private int val3;
        private long val4;


        public MyTask(int in3, long in4) {
            this.val3 = in3;
            this.val4 = in4;

            // Do something ...
        }

        protected void onPreExecute() {
            // Do something ...
        }

        @Override
        protected MyTaskResult doInBackground(Object... params) {
            MyTaskResult res = new MyTaskResult();
            val1 = (String) params[0];
            val2 = (boolean) params[1];

            //Do some lengthy operation    
            res.text1 = RunProc1(val1);
            res.text2 = RunProc2(val2);

            return res;
        }

        @Override
        protected void onPostExecute(MyTaskResult res) {
            textView1.setText(res.text1);
            textView2.setText(res.text2);

        }
    }

}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.