Android: Parametreleri AsyncTask'ın onPreExecute () öğesine nasıl iletebilirim?


116

AsyncTaskBir iç sınıf olarak gerçekleştirdiğim yükleme işlemleri için bir kullanıyorum .

İçinde, onPreExecute()daha sonra tekrar sakladığım bir yükleme iletişim kutusu gösteriyorum onPostExecute(). Ancak bazı yükleme işlemlerinin çok hızlı biteceğini önceden bildiğim için yükleme iletişim kutusunu görüntülemek istemiyorum.

Bunu, geçebileceğim bir boole parametresi ile belirtmek istedim, onPreExecute()ancak görünüşe göre onPreExecute()herhangi bir nedenle herhangi bir parametre almıyor.

Açık olan geçici çözüm, muhtemelen AsyncTask'ımda veya her yükleme işleminden önce ayarlamam gereken dış sınıfta bir üye alanı oluşturmak olabilir, ancak bu çok zarif görünmüyor. Bunu yapmanın daha iyi bir yolu var mı?

Yanıtlar:


230

Yapıcıyı geçersiz kılabilirsiniz. Gibi bir şey:

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

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

    // doInBackground() et al.
}

Ardından görevi çağırırken aşağıdaki gibi bir şey yapın:

new MyAsyncTask(true).execute(maybe_other_params);

Düzenleme: bu, görev çağrısını basitleştirdiği için üye değişkenleri oluşturmaktan daha kullanışlıdır. Yukarıdaki kodu şununla karşılaştırın:

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

3
Bu tam olarak şimdi yaptığım şey. Hala bir üye değişkene ihtiyacım var ama AsyncTask'ta ve dış sınıfta değil, demek istediğin buysa. Benim yaptığım buydu: özel sınıf MyAsyncTask, AsyncTask'ı genişletiyor <Void, Void, Void> {private boolean showLoading; public MyAsyncTask (boolean showLoading) {super (); this.showLoading = showLoading; // şeyler yap} korumalı boşluk onPreExecute () {if (showLoading) {// ...}} // doInBackground () et al. }
Steven Meliopoulos

1
Evet, fikir buydu :)
Felix

1
AsynkTask yapıcısında aslında super () 'e ihtiyacınız yoktur.
ostergaard

62

1) Benim için parametreleri eşzamansız göreve aktarmanın en basit yolu bu

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

Eşzamansız görevi burada olduğu gibi bildirin ve kullanın

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) Yöntemleri zaman uyumsuz göreve geçirme Zaman uyumsuz Görev altyapısını (thread, messagenhandler, ...) birden çok kez kodlamaktan kaçınmak için, zaman uyumsuz görevinizde çalıştırılması gereken yöntemleri parametre olarak geçirmeyi düşünebilirsiniz. Aşağıdaki örnek bu yaklaşımı özetlemektedir. Buna ek olarak, yapıcıdaki başlatma parametrelerini geçirmek için zaman uyumsuz görevi alt sınıflara ayırmanız gerekebilir.

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

Asynctask <> 'a neden, nasıl ve hangi parametreler aktarılır, ayrıntılara buradan bakın . Bence en iyi açıklama bu.

Google'ın Android Belgeleri şunları söylüyor:

Zaman uyumsuz bir görev, Params, Progress and Result adlı 3 genel tür ve onPreExecute, doInBackground, onProgressUpdate ve onPostExecute adlı 4 adımla tanımlanır.

AsyncTask'ın genel türleri:

Eşzamansız bir görev tarafından kullanılan üç tür şunlardır:

Parametreler, yürütüldükten sonra göreve gönderilen parametrelerin türü. İlerleme, arka plan hesaplaması sırasında yayınlanan ilerleme birimlerinin türü. Sonuç, arka plan hesaplamasının sonucunun türü. Tüm türler her zaman eşzamansız bir görev tarafından kullanılmaz. Bir türü kullanılmamış olarak işaretlemek için Void türünü kullanmanız yeterlidir:

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

Daha fazla başvurabilirsiniz: http://developer.android.com/reference/android/os/AsyncTask.html

Veya Sankar-Ganesh'in Bloguna atıfta bulunarak AsyncTask'ın rolünün ne olduğunu netleştirebilirsiniz

Tipik bir AsyncTask sınıfının yapısı şu şekildedir:

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

    protected void onPreExecute(){ 

    } 

Bu yöntem, yeni İş Parçacığı başlatılmadan önce yürütülür. Giriş / çıkış değerleri yoktur, bu yüzden sadece değişkenleri veya yapmanız gerektiğini düşündüğünüz şeyi başlatın.

protected Z doInBackground(X...x){

}

AsyncTask sınıfındaki en önemli yöntem. Arka planda yapmak istediğiniz her şeyi buraya, ana olandan farklı bir konu başlığına yerleştirmelisiniz. Burada bir girdi değeri olarak "X" türünden bir dizi nesneye sahibiz (Başlıkta görüyor musunuz? "... extends AsyncTask" var Bunlar, girdi parametrelerinin TYPES'idir) ve türden bir nesne döndürür. “Z”.

korumalı void onProgressUpdate (Y y) {

} Bu yöntem, publishProgress (y) yöntemi kullanılarak çağrılır ve genellikle arka planda yaptığınız işlemin ilerlemesini gösteren bir ilerleme çubuğu gibi, ana ekranda herhangi bir ilerleme veya bilgi göstermek istediğinizde kullanılır.

korumalı void onPostExecute (Z z) {

} Bu yöntem, arka planda işlem yapıldıktan sonra çağrılır. Bir girdi parametresi olarak doInBackground yönteminin çıktı parametresini alacaksınız.

Peki ya X, Y ve Z türleri?

Yukarıdaki yapıdan da anlaşılacağı gibi:

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.

Bu görevi dışarıdan bir sınıftan nasıl adlandırabiliriz? Sadece aşağıdaki iki satırla:

MyTask myTask = new MyTask();

myTask.execute(x);

Burada x, X türünün giriş parametresidir.

Görevimizi çalıştırdığımızda, durumunu "dışarıdan" öğrenebiliriz. "GetStatus ()" yöntemini kullanma.

myTask.getStatus (); ve aşağıdaki durumu alabiliriz:

ÇALIŞIYOR - Görevin çalışmakta olduğunu gösterir.

BEKLEMEDE - Görevin henüz yürütülmediğini gösterir.

FINISHED - onPostExecute (Z) işleminin bittiğini gösterir.

AsyncTask kullanımıyla ilgili ipuçları

OnPreExecute, doInBackground ve onPostExecute yöntemlerini manuel olarak çağırmayın. Bu, sistem tarafından otomatik olarak yapılır.

Başka bir AsyncTask veya Thread içinde bir AsyncTask çağıramazsınız. Yürütme yönteminin çağrısı, UI İş Parçacığı içinde yapılmalıdır.

OnPostExecute yöntemi UI Thread içinde yürütülür (burada başka bir AsyncTask çağırabilirsiniz!).

Görevin girdi parametreleri bir Nesne dizisi olabilir, bu şekilde istediğiniz nesneleri ve türleri koyabilirsiniz.


4

Parametreyi görev yapıcısında veya execute çağırdığınızda iletebilirsiniz:

AsyncTask<Object, Void, MyTaskResult>

İlk parametre (Nesne) doInBackground'da iletilir. Üçüncü parametre (MyTaskResult) doInBackground tarafından döndürülür. Bunları istediğiniz türlere değiştirebilirsiniz. Üç nokta, sıfır veya daha fazla nesnenin (veya bunların bir dizisinin) bağımsız değişken (ler) olarak aktarılabileceği anlamına gelir.

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

        }
    }

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.