Android: Jak mogę przekazać parametry do metody onPreExecute () AsyncTask?

116

Używam AsyncTask do operacji ładowania, które zaimplementowałem jako klasa wewnętrzna.

W onPreExecute()pokazuję okno dialogowe ładowania, które następnie ukrywamonPostExecute() . Ale w przypadku niektórych operacji ładowania wiem z góry, że kończą się one bardzo szybko, więc nie chcę wyświetlać okna dialogowego ładowania.

Chciałem to wskazać za pomocą parametru boolowskiego, do którego mogłem przejść, onPreExecute()ale najwyraźniej z jakiegoś powoduonPreExecute() nie przyjmuje żadnych parametrów.

Oczywistym obejściem byłoby prawdopodobnie utworzenie pola członkowskiego w moim AsyncTask lub w klasie zewnętrznej, które musiałbym ustawić przed każdą operacją ładowania, ale nie wydaje się to zbyt eleganckie. Czy jest lepszy sposób na zrobienie tego?

Steven Meliopoulos
źródło

Odpowiedzi:

231

Możesz przesłonić konstruktora. Coś jak:

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

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

    // doInBackground() et al.
}

Następnie, dzwoniąc do zadania, zrób coś takiego:

new MyAsyncTask(true).execute(maybe_other_params);

Edycja: jest to bardziej przydatne niż tworzenie zmiennych składowych, ponieważ upraszcza wywoływanie zadań. Porównaj powyższy kod z:

MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();
Felix
źródło
3
Dokładnie to zrobiłem teraz. Nadal potrzebuję zmiennej składowej, ale w AsyncTask, a nie w klasie zewnętrznej, jeśli to masz na myśli. Oto co zrobiłem: private class MyAsyncTask rozszerza AsyncTask <Void, Void, Void> {private boolean showLoading; public MyAsyncTask (boolean showLoading) {super (); this.showLoading = showLoading; // zrób coś} protected void onPreExecute () {if (showLoading) {// ...}} // doInBackground () et al. }
Steven Meliopoulos
1
Tak, to był właściwie pomysł :)
Felix
1
Właściwie nie potrzebujesz super () w konstruktorze AsynkTask.
ostergaard
62

1) Dla mnie jest to najprostszy sposób przekazywania parametrów do zadania asynchronicznego w ten sposób

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

Zadeklaruj i użyj zadania asynchronicznego, tak jak tutaj

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) Przekazywanie metod do zadania asynchronicznego Aby uniknąć wielokrotnego kodowania infrastruktury Async-Task (wątek, messagenhandler, ...), możesz rozważyć przekazanie metod, które powinny być wykonane w zadaniu asynchronicznym jako parametr. Poniższy przykład przedstawia to podejście. Ponadto może zajść potrzeba podklasy zadania asynchronicznego, aby przekazać parametry inicjalizacji w konstruktorze.

 /* 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;
        }
    });     
}
Karl
źródło
11

dlaczego, jak i które parametry są przekazywane do Asynctask <>, zobacz szczegóły tutaj . Myślę, że to najlepsze wyjaśnienie.

Dokumentacja Google dotycząca Androida mówi, że:

Zadanie asynchroniczne jest definiowane przez 3 typy ogólne, zwane Params, Progress i Result oraz 4 kroki, nazywane onPreExecute, doInBackground, onProgressUpdate i onPostExecute.

Typy ogólne AsyncTask:

Trzy typy używane przez zadanie asynchroniczne są następujące:

Params, rodzaj parametrów wysyłanych do zadania po jego wykonaniu. Postęp, typ jednostek postępu opublikowanych podczas obliczeń w tle. Wynik, typ wyniku obliczeń w tle. Nie wszystkie typy są zawsze używane przez zadanie asynchroniczne. Aby oznaczyć typ jako nieużywany, po prostu użyj typu Void:

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

Możesz dalej polecić: http://developer.android.com/reference/android/os/AsyncTask.html

Lub możesz wyjaśnić, jaką rolę pełni AsyncTask, kierując blog Sankar-Ganesh

Cóż, struktura typowej klasy AsyncTask wygląda następująco:

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

    protected void onPreExecute(){ 

    } 

Ta metoda jest wykonywana przed uruchomieniem nowego Thread. Nie ma wartości wejściowych / wyjściowych, więc po prostu zainicjuj zmienne lub cokolwiek myślisz, że musisz zrobić.

protected Z doInBackground(X...x){

}

Najważniejsza metoda w klasie AsyncTask. Musisz umieścić tutaj wszystkie rzeczy, które chcesz zrobić w tle, w innym wątku niż główny. Tutaj mamy jako wartość wejściową tablicę obiektów typu „X” (czy widzisz w nagłówku? Mamy „… extends AsyncTask” To są TYPY parametrów wejściowych) i zwraca obiekt z typu „Z”.

protected void onProgressUpdate (Y y) {

} Ta metoda jest wywoływana za pomocą metody publicProgress (y) i jest zwykle używana, gdy chcesz pokazać postęp lub informacje na ekranie głównym, takie jak pasek postępu pokazujący postęp operacji, którą wykonujesz w tle.

protected void onPostExecute (Z z) {

} Ta metoda jest wywoływana po wykonaniu operacji w tle. Jako parametr wejściowy otrzymasz parametr wyjściowy metody doInBackground.

A co z typami X, Y i Z?

Jak można wywnioskować z powyższej struktury:

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.

Jak nazywamy to zadanie z zewnątrz? Tylko z następującymi dwoma wierszami:

MyTask myTask = new MyTask();

myTask.execute(x);

Gdzie x jest parametrem wejściowym typu X.

Po uruchomieniu zadania możemy dowiedzieć się o jego statusie „z zewnątrz”. Korzystanie z metody „getStatus ()”.

myTask.getStatus (); i możemy otrzymać następujący status:

RUNNING - wskazuje, że zadanie jest uruchomione.

PENDING - wskazuje, że zadanie nie zostało jeszcze wykonane.

FINISHED - wskazuje, że onPostExecute (Z) został zakończony.

Wskazówki dotyczące korzystania z AsyncTask

Nie wywołuj ręcznie metod onPreExecute, doInBackground i onPostExecute. Jest to wykonywane automatycznie przez system.

Nie można wywołać AsyncTask wewnątrz innego AsyncTask lub Thread. Wywołanie metody należy wykonać w wątku interfejsu użytkownika.

Metoda onPostExecute jest wykonywana w wątku UI (tutaj możesz wywołać inny AsyncTask!).

Parametrami wejściowymi zadania może być tablica Object, w ten sposób możesz umieścić dowolne obiekty i typy.

Naveed Jamali
źródło
4

Możesz przekazać parametr w konstruktorze zadania lub podczas wywoływania execute:

AsyncTask<Object, Void, MyTaskResult>

Pierwszy parametr (Object) jest przekazywany w doInBackground. Trzeci parametr (MyTaskResult) jest zwracany przez funkcję doInBackground. Możesz je zmienić na żądane typy. Trzy kropki oznaczają, że zero lub więcej obiektów (lub ich tablica) może zostać przekazanych jako argumenty.

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);

        }
    }

}
miłość na żywo
źródło