118 Stimmen

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

Ich verwende ein AsyncTask für Ladevorgänge, die ich als innere Klasse implementiert habe.

Sur onPreExecute() Ich zeige einen Ladedialog an, den ich dann wieder ausblende in onPostExecute() . Bei einigen Ladevorgängen weiß ich jedoch im Voraus, dass sie sehr schnell abgeschlossen sein werden, so dass ich den Ladedialog nicht anzeigen möchte.

Ich wollte dies durch einen booleschen Parameter angeben, den ich an onPreExecute() aber offenbar aus irgendeinem Grund onPreExecute() nimmt keine Parameter an.

Die offensichtliche Abhilfe wäre wahrscheinlich, ein Mitgliedsfeld in meiner AsyncTask oder in der äußeren Klasse zu erstellen, das ich vor jedem Ladevorgang setzen müsste, aber das scheint nicht sehr elegant zu sein. Gibt es eine bessere Möglichkeit, dies zu tun?

238voto

Felix Punkte 86442

Sie können den Konstruktor außer Kraft setzen. Etwa so:

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

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

    // doInBackground() et al.
}

Wenn Sie dann die Aufgabe aufrufen, tun Sie etwas wie:

new MyAsyncTask(true).execute(maybe_other_params);

Edita: Dies ist nützlicher als die Erstellung von Mitgliedsvariablen, weil es den Aufruf der Aufgabe vereinfacht. Vergleichen Sie den obigen Code mit:

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

65voto

Karl Punkte 2961

1) Für mich ist das der einfachste Weg, Parameter zu übergeben zur asynchronen Aufgabe ist wie folgt

// 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 folgt

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) Übergabe von Methoden an async-task Um zu vermeiden, dass die async-Task Infrastruktur (Thread, Messagenhandler, ...) mehrfach codiert wird, kann man überlegen, die Methoden, die in der async-Task ausgeführt werden sollen, als Parameter zu übergeben. Das folgende Beispiel skizziert diesen Ansatz. Darüber hinaus kann es notwendig sein, die async-Task zu subclassen, um 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;
        }
    });     
}

11voto

Naveed Jamali Punkte 698

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

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

Eine asynchrone Aufgabe wird durch 3 generische Typen definiert, die Params, Progress und Result heißen, und 4 Schritte, die onPreExecute, doInBackground, onProgressUpdate und onPostExecute heißen.

Die generischen Typen von AsyncTask :

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

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

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

Sie können sich weiter informieren: http://developer.Android.com/reference/Android/os/AsyncTask.html

Oder Sie können klar, was die Rolle der AsyncTask durch Verweis auf Sankar-Ganesh's Blog

Die Struktur einer typischen AsyncTask-Klasse sieht folgendermaßen aus:

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

    protected void onPreExecute(){ 

    } 

Diese Methode wird vor dem Start des neuen Threads ausgeführt. Es gibt keine Eingabe-/Ausgabewerte, also initialisieren Sie einfach Variablen oder was immer Sie für notwendig halten.

protected Z doInBackground(X...x){

}

Die wichtigste Methode in der AsyncTask-Klasse. Hier müssen Sie all die Dinge unterbringen, die Sie im Hintergrund, in einem anderen Thread als dem Hauptthread, erledigen wollen. Hier haben wir als Eingabewert ein Array von Objekten vom Typ "X" (Sehen Sie im Header? Wir haben "...extends AsyncTask" Das sind die TYPES der Eingabeparameter) und geben ein Objekt vom Typ "Z" zurück.

protected void onProgressUpdate(Y y){

} Diese Methode wird über die Methode publishProgress(y) aufgerufen und wird in der Regel verwendet, wenn Sie einen Fortschritt oder Informationen auf dem Hauptbildschirm anzeigen möchten, wie z. B. einen Fortschrittsbalken, der den Fortschritt der Operation anzeigt, die Sie im Hintergrund durchführen.

protected void onPostExecute(Z z){

} Diese Methode wird aufgerufen, nachdem der Vorgang im Hintergrund abgeschlossen ist. Als Eingabeparameter erhalten Sie den Ausgabeparameter der doInBackground-Methode.

Was ist mit den Typen X, Y und Z?

Wie Sie aus der obigen Struktur ersehen 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 können wir diese Aufgabe von einer externen Klasse aus aufrufen? Einfach mit den folgenden zwei Zeilen:

MyTask myTask = new MyTask();

myTask.execute(x);

Dabei ist x der Eingabeparameter vom Typ X.

Sobald unsere Aufgabe läuft, können wir ihren Status von "außen" abfragen. Dazu verwenden wir die Methode "getStatus()".

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

LÄUFT - Zeigt an, dass die Aufgabe ausgeführt wird.

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

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

Hinweise zur Verwendung von AsyncTask

Rufen Sie die Methoden onPreExecute, doInBackground und onPostExecute nicht manuell auf. Dies wird automatisch vom System erledigt.

Sie können eine AsyncTask nicht innerhalb einer anderen AsyncTask oder eines Threads 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 Objekt-Array sein, so dass Sie beliebige Objekte und Typen eingeben können.

5voto

live-love Punkte 40586

Sie können den Parameter entweder im Aufgabenkonstruktor oder beim Aufruf von execute übergeben:

AsyncTask<Object, Void, MyTaskResult>

Der erste Parameter (Object) wird in doInBackground übergeben. Der dritte Parameter (MyTaskResult) wird von doInBackground zurückgegeben. Sie können sie in die von Ihnen gewünschten Typen umwandeln. 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);

        }
    }

}

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