Android: Bagaimana cara meneruskan parameter ke onPreExecute () AsyncTask?

116

Saya menggunakan AsyncTaskoperasi untuk memuat yang saya terapkan sebagai kelas dalam.

Di onPreExecute()saya menampilkan dialog pemuatan yang kemudian saya sembunyikan lagi onPostExecute(). Tetapi untuk beberapa operasi pemuatan, saya tahu sebelumnya bahwa mereka akan selesai dengan sangat cepat sehingga saya tidak ingin menampilkan dialog pemuatan.

Saya ingin menunjukkan ini dengan parameter boolean yang dapat saya berikan onPreExecute()tetapi tampaknya karena alasan tertentu onPreExecute()tidak mengambil parameter apa pun.

Solusi yang jelas mungkin akan membuat bidang anggota di AsyncTask saya atau di kelas luar yang harus saya atur sebelum setiap operasi pemuatan tetapi itu tidak tampak sangat elegan. Apakah ada cara yang lebih baik untuk melakukan ini?

Steven Meliopoulos
sumber

Jawaban:

230

Anda dapat mengganti konstruktor. Sesuatu seperti:

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

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

    // doInBackground() et al.
}

Kemudian, saat memanggil tugas, lakukan sesuatu seperti:

new MyAsyncTask(true).execute(maybe_other_params);

Edit: ini lebih berguna daripada membuat variabel anggota karena menyederhanakan pemanggilan tugas. Bandingkan kode di atas dengan:

MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();
Felix
sumber
3
Ini persis seperti yang saya lakukan sekarang. Saya masih membutuhkan variabel anggota tetapi di AsyncTask dan bukan kelas luar jika itu yang Anda maksud. Inilah yang saya lakukan: private class MyAsyncTask extends AsyncTask <Void, Void, Void> {private boolean showLoading; public MyAsyncTask (boolean showLoading) {super (); this.showLoading = showLoading; // lakukan hal-hal} dilindungi void onPreExecute () {if (showLoading) {// ...}} // doInBackground () dkk. }
Steven Meliopoulos
1
Yup, itu idenya :)
Felix
1
Anda sebenarnya tidak membutuhkan super () di konstruktor AsynkTask.
ostergaard
62

1) Bagi saya, itulah cara paling sederhana meneruskan parameter ke tugas asinkron seperti ini

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

Deklarasikan dan gunakan tugas asinkron seperti di sini

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) Meneruskan metode ke async-task Untuk menghindari pengkodean infrastruktur async-Task (thread, messagenhandler, ...) beberapa kali, Anda mungkin mempertimbangkan untuk meneruskan metode yang harus dijalankan di async-task Anda sebagai parameter. Contoh berikut menguraikan pendekatan ini. Selain itu, Anda mungkin perlu membuat subclass async-task untuk meneruskan parameter inisialisasi dalam konstruktor.

 /* 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
sumber
11

why, how dan parameter mana yang diteruskan ke Asynctask <>, lihat detailnya di sini . Saya pikir itu adalah penjelasan terbaik.

Dokumentasi Android Google Mengatakan bahwa:

Tugas asinkron ditentukan oleh 3 jenis umum, yang disebut Params, Progress dan Result, dan 4 langkah, yang disebut onPreExecute, doInBackground, onProgressUpdate, dan onPostExecute.

Jenis umum AsyncTask:

Tiga jenis yang digunakan oleh tugas asinkron adalah sebagai berikut:

Params, jenis parameter yang dikirim ke tugas setelah dijalankan. Progress, jenis unit kemajuan yang dipublikasikan selama komputasi latar belakang. Hasil, jenis hasil komputasi latar belakang. Tidak semua tipe selalu digunakan oleh tugas asinkron. Untuk menandai tipe sebagai tidak terpakai, cukup gunakan tipe Void:

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

Anda selanjutnya Dapat merujuk: http://developer.android.com/reference/android/os/AsyncTask.html

Atau Anda dapat menghapus apa peran AsyncTask dengan merujuk Blog Sankar-Ganesh

Struktur kelas AsyncTask biasanya seperti ini:

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

    protected void onPreExecute(){ 

    } 

Metode ini dijalankan sebelum memulai Thread baru. Tidak ada nilai input / output, jadi inisialisasi variabel atau apa pun yang menurut Anda perlu dilakukan.

protected Z doInBackground(X...x){

}

Metode paling penting di kelas AsyncTask. Anda harus menempatkan di sini semua hal yang ingin Anda lakukan di latar belakang, di utas yang berbeda dari utas utama. Di sini kita memiliki nilai input array objek dari tipe "X" (Apakah Anda lihat di header? Kami memiliki "... extends AsyncTask" Ini adalah JENIS parameter input) dan mengembalikan objek dari tipe "Z".

void dilindungi onProgressUpdate (Y y) {

} Metode ini dipanggil menggunakan metode publishProgress (y) dan biasanya digunakan ketika Anda ingin menampilkan kemajuan atau informasi apa pun di layar utama, seperti bilah kemajuan yang menunjukkan kemajuan operasi yang Anda lakukan di latar belakang.

void terlindungi onPostExecute (Z z) {

} Metode ini dipanggil setelah operasi di latar belakang selesai. Sebagai parameter masukan, Anda akan menerima parameter keluaran dari metode doInBackground.

Bagaimana dengan tipe X, Y dan Z?

Seperti yang dapat Anda simpulkan dari struktur di atas:

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.

Bagaimana kita menyebut tugas ini dari kelas luar? Hanya dengan dua baris berikut:

MyTask myTask = new MyTask();

myTask.execute(x);

Dimana x adalah parameter input dari tipe X.

Setelah kami menjalankan tugas kami, kami dapat mengetahui statusnya dari "luar". Menggunakan metode "getStatus ()".

myTask.getStatus (); dan kami dapat menerima status berikut:

RUNNING - Menunjukkan bahwa tugas sedang berjalan.

PENDING - Menunjukkan bahwa tugas belum dijalankan.

SELESAI - Menunjukkan bahwa onPostExecute (Z) telah selesai.

Petunjuk tentang menggunakan AsyncTask

Jangan panggil metode onPreExecute, doInBackground, dan onPostExecute secara manual. Ini secara otomatis dilakukan oleh sistem.

Anda tidak dapat memanggil AsyncTask di dalam AsyncTask atau Thread lain. Panggilan metode yang dieksekusi harus dilakukan di UI Thread.

Metode onPostExecute dijalankan di UI Thread (di sini Anda dapat memanggil AsyncTask!).

Parameter input tugas dapat berupa array Objek, dengan cara ini Anda dapat meletakkan objek dan tipe apa pun yang Anda inginkan.

Naveed Jamali
sumber
4

Anda bisa meneruskan parameter di konstruktor tugas atau saat Anda memanggil eksekusi:

AsyncTask<Object, Void, MyTaskResult>

Parameter pertama (Object) diteruskan di doInBackground. Parameter ketiga (MyTaskResult) dikembalikan oleh doInBackground. Anda dapat mengubahnya ke jenis yang Anda inginkan. Tiga titik berarti bahwa nol atau lebih objek (atau array dari mereka) dapat dilewatkan sebagai argumen.

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

        }
    }

}
cinta hidup
sumber