AsyncTask ayrı bir sınıf olduğundan OnPostExecute () sonucunu ana etkinliğe nasıl alabilirim?


362

Bu iki dersim var. Benim asıl Aktivite ve genişleten bir AsyncTaskŞimdi benim ana Aktivite I sonucunu almak gerekir, OnPostExecute()içindeAsyncTask . Ana Faaliyetime nasıl sonuç verebilirim veya sonucu nasıl alabilirim?

İşte örnek kodlar.

Benim ana faaliyetim.

public class MainActivity extends Activity{

    AasyncTask asyncTask = new AasyncTask();

    @Override
    public void onCreate(Bundle aBundle) {
        super.onCreate(aBundle);            

        //Calling the AsyncTask class to start to execute.  
        asyncTask.execute(a.targetServer); 

        //Creating a TextView.
        TextView displayUI = asyncTask.dataDisplay;
        displayUI = new TextView(this);
        this.setContentView(tTextView); 
    }

}

Bu AsyncTask sınıfı

public class AasyncTask extends AsyncTask<String, Void, String> {

TextView dataDisplay; //store the data  
String soapAction = "http://sample.com"; //SOAPAction header line. 
String targetServer = "https://sampletargeturl.com"; //Target Server.

//SOAP Request.
String soapRequest = "<sample XML request>";    



@Override
protected String doInBackground(String... string) {

String responseStorage = null; //storage of the response

try {


    //Uses URL and HttpURLConnection for server connection. 
    URL targetURL = new URL(targetServer);
    HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
    httpCon.setDoOutput(true);
    httpCon.setDoInput(true);
    httpCon.setUseCaches(false); 
    httpCon.setChunkedStreamingMode(0);

    //properties of SOAPAction header
    httpCon.addRequestProperty("SOAPAction", soapAction);
    httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8"); 
    httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
    httpCon.setRequestMethod(HttpPost.METHOD_NAME);


    //sending request to the server.
    OutputStream outputStream = httpCon.getOutputStream(); 
    Writer writer = new OutputStreamWriter(outputStream);
    writer.write(soapRequest);
    writer.flush();
    writer.close();


    //getting the response from the server
    InputStream inputStream = httpCon.getInputStream(); 
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);

    int intResponse = httpCon.getResponseCode();

    while ((intResponse = bufferedReader.read()) != -1) {
        byteArrayBuffer.append(intResponse);
    }

    responseStorage = new String(byteArrayBuffer.toByteArray()); 

    } catch (Exception aException) {
    responseStorage = aException.getMessage(); 
    }
    return responseStorage;
}

protected void onPostExecute(String result) {

    aTextView.setText(result);

}       

}   

HelmiB gibi bir arayüz oluşturabilir veya yerel bir yayın alıcısı oluşturabilirsiniz Örnek yayın alıcısı uygulamasını burada görebilirsiniz wiki.workassis.com/android-local-broadcast-receiver
Bikesh M

Neden Observer desenini kullanmıyorsunuz?
JAAAY

Yanıtlar:


751

Kolay:

  1. İsteğe bağlı olarak interfacesınıf oluşturun String outputveya dönmek istediğiniz değişkenler olabilir.

    public interface AsyncResponse {
        void processFinish(String output);
    }
  2. AsyncTaskSınıfınıza gidin ve arayüzü AsyncResponsealan olarak bildirin:

    public class MyAsyncTask extends AsyncTask<Void, Void, String> {
      public AsyncResponse delegate = null;
    
        @Override
        protected void onPostExecute(String result) {
          delegate.processFinish(result);
        }
     }
  3. Ana Faaliyetinizde implementsarayüz oluşturmalısınız AsyncResponse.

    public class MainActivity implements AsyncResponse{
      MyAsyncTask asyncTask =new MyAsyncTask();
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
    
         //this to set delegate/listener back to this class
         asyncTask.delegate = this;
    
         //execute the async task 
         asyncTask.execute();
      }
    
      //this override the implemented method from asyncTask
      @Override
      void processFinish(String output){
         //Here you will receive the result fired from async class 
         //of onPostExecute(result) method.
       }
     }

GÜNCELLEME

Bunun çoğunuz için bu kadar favori olduğunu bilmiyordum. İşte basit ve kolay kullanım yolu interface.

hala aynı kullanıyor interface. Bilginize, bunu AsyncTasksınıfta birleştirebilirsiniz .

içinde AsyncTasksınıfında:

public class MyAsyncTask extends AsyncTask<Void, Void, String> {

  // you may separate this or combined to caller class.
  public interface AsyncResponse {
        void processFinish(String output);
  }

  public AsyncResponse delegate = null;

    public MyAsyncTask(AsyncResponse delegate){
        this.delegate = delegate;
    }

    @Override
    protected void onPostExecute(String result) {
      delegate.processFinish(result);
    }
}

bunu Activitysınıfında yap

public class MainActivity extends Activity {

   MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse(){

     @Override
     void processFinish(String output){
     //Here you will receive the result fired from async class 
     //of onPostExecute(result) method.
     }
  }).execute();

 }

Veya arabirimi tekrar Faaliyete uygulamak

public class MainActivity extends Activity 
    implements AsyncResponse{

    @Override
    public void onCreate(Bundle savedInstanceState) {

        //execute the async task 
        new MyAsyncTask(this).execute();
    }

    //this override the implemented method from AsyncResponse
    @Override
    void processFinish(String output){
        //Here you will receive the result fired from async class 
        //of onPostExecute(result) method.
    }
}

Yukarıda 2 çözüm görebileceğiniz gibi, birincisi ve üçüncüsü, yöntem yaratmalı processFinish, diğeri, yöntem caller parametresinin içinde. Üçüncüsü daha düzenli çünkü yuvalanmış anonim sınıf yok. Bu yardımcı olur umarım

İpucu : Değişim String output, String responseve String resultfarklı eşleme türlerine farklı nesneleri almak için.


20
Tamamen hepsini yazdı ve sonra cevabını gördüm :) İşte benzer düşünmek için! +1. Ayrıca bu şekilde AsyncTask'ın sonuçlarını dinleyebilirsiniz!
Roloc

8
Temsilci null olarak ayarlandığından nullpointer istisnası alıyorum, lütfen temizle
Reyjohn

2
Sadece .net geliştiricileri için bir not, bunu başarmak için AutoResetEvents kullanabilirsiniz ve otomatik olarak yeniden başlayanlar için bir java uygulaması var ama bu çok daha temiz. Bu arada, ProcessFinish iş parçacığı güvenli midir?
Syler

13
null işaretçisi alan herkes için arayüzünüzü asyncTask sınıfı yapıcısına iletin, sonra bir değişkene atayın ve sonra bu değişken üzerinde processfinish () öğesini çağırın. Referans için bkz. Kabul edilen asnwer. stackoverflow.com/questions/9963691/…
Güneşli

2
@Sunny haklısın ... Ayrıca, async nesnesini async.delegate = this için başlatmalıyız; to work ..
Ninja_Coder

24

Birkaç seçenek vardır:

  • Nest AsyncTasksizin içinde sınıf Activitysınıfının. Aynı görevi birden fazla aktivitede kullanmadığınızı varsayarsak, bu en kolay yoldur. Tüm kodlarınız aynı kalır, sadece varolan görev sınıfını etkinliğinizin sınıfının içinde iç içe bir sınıf olarak taşıyabilirsiniz.

    public class MyActivity extends Activity {
        // existing Activity code
        ...
    
        private class MyAsyncTask extends AsyncTask<String, Void, String> {
            // existing AsyncTask code
            ...
        }
    }
  • İçin AsyncTaskreferans alan özel bir kurucu oluşturun Activity. Görevi benzer bir şeyle başlatırsınız new MyAsyncTask(this).execute(param1, param2).

    public class MyAsyncTask extends AsyncTask<String, Void, String> {
        private Activity activity;
    
        public MyAsyncTask(Activity activity) {
            this.activity = activity;
        }
    
        // existing AsyncTask code
        ...
    }

İkinci seçenekte: Sınıf değilse neden bir yapıcı ve alanın acılarından geçiyorsunuz static? Sadece herhangi kullanmak fieldOrMethodgelen MyActivityveya MyActivity.this.fieldOrMethodo gölgeli eğer.
TWiStErRob

İkinci kabul @TWiStErRob MyAsyncTaskolan olmayan bir iç sınıfı.
quietmint

1
Ah, üzgünüm, private/ protectedüst düzey sınıflar için izin verilmiyor, bu yüzden staticiçsel olmayan bir sınıf olması gerektiğini düşündüm .
TWiStErRob

2
Sadece iç sınıf AsyncTask'in burada açıklandığı gibi bir bellek sızıntısı kaynağı olabileceğine dikkat edin garena.github.io/blog/2014/09/10/android-memory-leaks
Mark Pazon

2
Etkinlik referansını tutmak da bir bellek sızıntısıdır. Geri arama yaklaşımı bundan çok daha iyi
OneCricketeer

19

Aşağıdaki yaklaşımın çok kolay olduğunu hissettim.

Geri arama için bir arayüz beyan ettim

public interface AsyncResponse {
    void processFinish(Object output);
}

Ardından, her türlü paralel isteği yanıtlamak için eşzamansız Görev oluşturuldu

 public class MyAsyncTask extends AsyncTask<Object, Object, Object> {

    public AsyncResponse delegate = null;//Call back interface

    public MyAsyncTask(AsyncResponse asyncResponse) {
        delegate = asyncResponse;//Assigning call back interfacethrough constructor
    }

    @Override
    protected Object doInBackground(Object... params) {

      //My Background tasks are written here

      return {resutl Object}

    }

    @Override
    protected void onPostExecute(Object result) {
        delegate.processFinish(result);
    }

}

Sonra Class Class'ta bir düğmeyi tıklattığında eşzamansız görevi çağırdı.

public class MainActivity extends Activity{

    @Override
    public void onCreate(Bundle savedInstanceState) {

    Button mbtnPress = (Button) findViewById(R.id.btnPress);

    mbtnPress.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() {

                    @Override
                    public void processFinish(Object output) {
                        Log.d("Response From Asynchronous task:", (String) output);

                        mbtnPress.setText((String) output);
                   }
                });

                asyncTask.execute(new Object[] { "Your request to aynchronous task class is giving here.." });


            }
        });

    }



}

Teşekkürler


17

Bu kodu Ana sınıfınızda deneyebilirsiniz. Bu benim için çalıştı, ama başka bir şekilde yöntemler uyguladım

try {
    String receivedData = new AsyncTask().execute("http://yourdomain.com/yourscript.php").get();
} 
catch (ExecutionException | InterruptedException ei) {
    ei.printStackTrace();
}

2
Bunun OP'ye neden bu konuda yardımcı olabileceğini açıklayabilir misiniz?
John Odom

3
Bu bana yardımcı oldu. @HelmiB'in cevabı gibi başka bir şekilde denedim ama sonuç alamıyorum
Nicu P

Tamam, cevabım için üzgünüm. AsyncTask sınıfını çağırması ve ardından bu çağrıya bir parametre koyması gerekir. AsyncTask 3 genel tip tarafından tanımlanır: 1 parametre (sunucu etki alanı veya diğer parametre) 2 ilerleme (geçersiz olabilir), 3 sonuç. Bu türlerin tümü şunlar olabilir: JSONObject veya dizeler veya herhangi bir veri türü. Bir AsyncTask sınıfınız olduğunda, verilerin nereye gönderileceğini tanımlamanız gerekir. ör .: asyncTask.execute (" sampletargeturl.com"). get () ;
Nicu P

Bu yöntemi kullanırken, Logcat hakkında bir uyarı aldım: "I / Koreograf ﹕ 50 kare atlandı! Uygulama ana iş parçacığında çok fazla iş yapıyor olabilir." Bununla nasıl başa çıkılır? AsyncTask'ten döndürülmeyi beklerken kullanıcı arayüzü donuyor mu?
Huy Do

@NicuP aramayı unutmuş olabilirsiniz execute(), cevabımı görebilirsiniz, oraya yorum ekledim. güncellenmiş cevabımı kontrol etmek isteyebilirsiniz. Bu yardımcı olur umarım.
HelmiB

16

Bu cevap gecikebilir ama Activitybağımlı olduğunuzda birkaç şeyden bahsetmek istiyorum AsyncTask. Bu, çökmeleri ve bellek yönetimini önlemenize yardımcı olur. Yukarıdaki yanıtlarda da belirtildiği gibi interface, onlara geri aramalar da diyoruz. Bir muhbir olarak çalışacaklar, ancak bu durumlarda asla güçlü bir referans göndermeyecek Activityveya interfaceher zaman zayıf referans kullanamayacaklardır .

Bunun nasıl sorunlara neden olabileceğini öğrenmek için lütfen aşağıdaki ekran görüntüsüne bakın.

resim açıklamasını buraya girin

Başladığımız eğer Gördüğünüz gibi AsyncTaskbir ile güçlü sonra bizim hiçbir garantisi yoktur referans Activity/ FragmentElimizde veri alana kadar kullanımda daha iyi olurdu, böylece hayatta olacak WeakReferencedurumlarda ve bellek yönetimi o istek de yardım olarak biz tutun asla bizim güçlü referansActivity o zamanki , bozulmasından sonra çöp toplama için uygun olacaktır.

Harika WeakReference'ın nasıl kullanılacağını öğrenmek için aşağıdaki kod snippet'ini kontrol edin -

MyTaskInformer.java Bilgilendirici olarak çalışacak arayüz.

public interface MyTaskInformer {

    void onTaskDone(String output);

}

MySmallAsyncTask.javaAsyncTask kullanacak uzun çalışan görev yapmak WeakReference.

public class MySmallAsyncTask extends AsyncTask<String, Void, String> {

    // ***** Hold weak reference *****
    private WeakReference<MyTaskInformer> mCallBack;

    public MySmallAsyncTask(MyTaskInformer callback) {
        this.mCallBack = new WeakReference<>(callback);
    }

    @Override
    protected String doInBackground(String... params) {

        // Here do whatever your task is like reading/writing file
        // or read data from your server or any other heavy task

        // Let us suppose here you get response, just return it
        final String output = "Any out, mine is just demo output";

        // Return it from here to post execute
        return output;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        // Here you can't guarantee that Activity/Fragment is alive who started this AsyncTask

        // Make sure your caller is active

        final MyTaskInformer callBack = mCallBack.get();

        if(callBack != null) {
            callBack.onTaskDone(s);
        }
    }
}

MainActivity.javaBu sınıf, AsyncTaskuygulamamı interfacebu sınıfta ve overridebu zorunlu yöntemde başlatmak için kullanılır .

public class MainActivity extends Activity implements MyTaskInformer {

    private TextView mMyTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMyTextView = (TextView) findViewById(R.id.tv_text_view);

        // Start your AsyncTask and pass reference of MyTaskInformer in constructor
        new MySmallAsyncTask(this).execute();
    }

    @Override
    public void onTaskDone(String output) {

        // Here you will receive output only if your Activity is alive.
        // no need to add checks like if(!isFinishing())

        mMyTextView.setText(output);
    }
}

6

Oncreate () öğenizde:

'

myTask.execute("url");
String result = "";
try {
      result = myTask.get().toString();
} catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
}catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();

} '


6

Bunu birkaç satırda yapabilirsiniz, AsyncTask'ınızı çağırdığınızda onPostExecute'i geçersiz kılın. İşte size bir örnek:

new AasyncTask()
{
    @Override public void onPostExecute(String result)
    {
       // do whatever you want with result 
    }
}.execute(a.targetServer);

Umarım size yardımcı olmuştur, mutlu kodlama :)


Benim için işe yaramıyor. Sadece onPostExecuteyönteme girmez .
Francisco Romero

4

İnsanlar neden bu kadar zorlaştırıyor?

Bu yeterli olmalı.

OnPostExecute öğesini zaman uyumsuz görev üzerine uygulamayın, bunun yerine Aktiviteye uygulayın:

public class MainActivity extends Activity 
{

@Override
public void onCreate(Bundle savedInstanceState) {

    //execute the async task 
    MyAsyncTask task = new MyAsyncTask(){
            protected void onPostExecute(String result) {
                //Do your thing
            }       

    }

    task.execute("Param");

}


}

Bu benim için çalışıyor. Anlaması en basit ve en kolayıdır. Bence Java'nın yapmak için tasarlandığından faydalanıyor. Teşekkürler. Not: Eklemek gerekli @Overridemi?
Old Geezer

1
Hayır. @Override sadece bir ek açıklamadır. Java derleyicisine yöntemi geçersiz kılmak ve bunu yapmıyorsanız bilgi almak istediğinizi söylüyorsunuz.
bugdayci

4

(Veya aşırı yüklenmiş ) get()yöntemini çağırabilirsiniz . Bu yöntem , çalışmasını tamamlayana kadar engeller , bu noktada size geri döner .AsyncTaskget(long, TimeUnit)AsyncTaskResult

Zaman uyumsuz görevinizin oluşturulması / başlatılması ile getyöntemi çağırmak arasında başka işler yapmak akıllıca olacaktır , aksi takdirde zaman uyumsuz görevi çok verimli kullanmıyorsunuzdur.


1
Downvoted v çünkü get () ana iş parçacığını engelleyecektir. Engellerse AsyncTask'ı kullanmak için bir neden yok
GabrielBB

3

Kendi dinleyicinizi yazabilirsiniz. HelmiB ile aynı 'ın cevabı ancak bakar daha doğal:

Dinleyici arayüzü oluştur:

public interface myAsyncTaskCompletedListener {
    void onMyAsynTaskCompleted(int responseCode, String result);
}

Ardından eşzamansız görevinizi yazın:

public class myAsyncTask extends AsyncTask<String, Void, String> {

    private myAsyncTaskCompletedListener listener;
    private int responseCode = 0;

    public myAsyncTask() {
    }

    public myAsyncTask(myAsyncTaskCompletedListener listener, int responseCode) {
        this.listener = listener;
        this.responseCode = responseCode;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }


    @Override
    protected String doInBackground(String... params) {
        String result;
        String param = (params.length == 0) ? null : params[0];
        if (param != null) {
            // Do some background jobs, like httprequest...
            return result;
        }
        return null;
    }

    @Override
    protected void onPostExecute(String finalResult) {
        super.onPostExecute(finalResult);
        if (!isCancelled()) {
            if (listener != null) {
                listener.onMyAsynTaskCompleted(responseCode, finalResult);
            }
        }
    }
}

Son olarak dinleyiciyi faaliyete geçirin:

public class MainActivity extends AppCompatActivity implements myAsyncTaskCompletedListener {

    @Override
    public void onMyAsynTaskCompleted(int responseCode, String result) {

        switch (responseCode) {
            case TASK_CODE_ONE: 
                // Do something for CODE_ONE
                break;
            case TASK_CODE_TWO:
                // Do something for CODE_TWO
                break;
            default: 
                // Show some error code
        }        
    }

Ve asyncTask şöyle diyebilirsiniz:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Some other codes...
        new myAsyncTask(this,TASK_CODE_ONE).execute("Data for background job");
        // And some another codes...
}

2

Merhaba, böyle bir şey yapabilirsiniz:

  1. AsyncTask uygulayan sınıf oluşturma

    // TASK 
    public class SomeClass extends AsyncTask<Void, Void, String>>
    {
    
        private OnTaskExecutionFinished _task_finished_event;
    
        public interface OnTaskExecutionFinished
        {
            public void OnTaskFihishedEvent(String Reslut);
        }
    
        public void setOnTaskFinishedEvent(OnTaskExecutionFinished _event)
        {
            if(_event != null)
            {
                this._task_finished_event = _event;
            }
        }
    
        @Override
        protected void onPreExecute()
        {
            super.onPreExecute();
    
        }
    
        @Override
        protected String doInBackground(Void... params)
        {
            // do your background task here ...
    
            return "Done!";
        }
    
        @Override
        protected void onPostExecute(String result)
        {
            super.onPostExecute(result);
            if(this._task_finished_event != null)
            {
                this._task_finished_event.OnTaskFihishedEvent(result);
            }
            else
            {
                Log.d("SomeClass", "task_finished even is null");
            }
        }
    }
  2. Ana Etkinliğe Ekle

    // MAIN ACTIVITY
    public class MyActivity extends ListActivity
    {
       ...
        SomeClass _some_class = new SomeClass();
        _someclass.setOnTaskFinishedEvent(new _some_class.OnTaskExecutionFinished()
        {
        @Override
        public void OnTaskFihishedEvent(String result)
        {
            Toast.makeText(getApplicationContext(),
                    "Phony thread finished: " + result,
                    Toast.LENGTH_SHORT).show();
        }
    
       });
       _some_class.execute();
       ...
     }

1

Activity sınıfınızda statik bir üye oluşturun. Ardından,onPostExecute

Örneğin, AsyncTask öğenizin sonucu bir Dize ise, Etkinliğinizde genel bir statik dize oluşturun

public static String dataFromAsyncTask;

Ardından, onPostExecuteAsyncTask içinde ana sınıfınıza statik bir çağrı yapın ve değeri ayarlayın.

MainActivity.dataFromAsyncTask = "result blah";


1
bu senaryoda bellek sızıntısı olasılığı nedir?
antroid

0

İş parçacığı ve işleyici / ileti kullanarak çalışır hale getirmek. Aşağıdaki adımlar: Bir ilerleme durumu bildir İletişim kutusu

ProgressDialog loadingdialog;

İşlem tamamlandığında iletişim kutusunu kapatmak için bir işlev oluşturun.

   private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        loadingdialog.dismiss();

    }
    };

Yürütme ayrıntılarınızı kodlayın:

 public void startUpload(String filepath) {
    loadingdialog = ProgressDialog.show(MainActivity.this, "Uploading", "Uploading Please Wait", true);
    final String _path = filepath;
    new Thread() {
        public void run() {
            try {
                UploadFile(_path, getHostName(), getPortNo());
                handler.sendEmptyMessage(0);

            } catch (Exception e) {
                Log.e("threadmessage", e.getMessage());
            }
        }
    }.start();
}

0

İçin temsilci seçmek veya veri sağlamak için "protokoller" kullanmanız gerekir AsynTask.

Delegeler ve Veri Kaynakları

Temsilci, bir nesne bir programda bir olayla karşılaştığında başka bir nesne adına veya onunla koordineli olarak hareket eden bir nesnedir. ( Apple tanımı )

protokoller, bazı davranışları delege etmek için bazı yöntemleri tanımlayan arabirimlerdir.

İşte tam bir örnek !!!


0

bunu dene:

public class SomAsyncTask extends AsyncTask<String, Integer, JSONObject> {

    private CallBack callBack;

    public interface CallBack {
        void async( JSONObject jsonResult );
        void sync( JSONObject jsonResult );
        void progress( Integer... status );
        void cancel();
    }

    public SomAsyncTask(CallBack callBack) {
        this.callBack = callBack;
    }

    @Override
    protected JSONObject doInBackground(String... strings) {

        JSONObject dataJson = null;

        //TODO query, get some dataJson

        if(this.callBack != null)
            this.callBack.async( dataJson );// asynchronize with MAIN LOOP THREAD

        return dataJson;

    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);

        if(this.callBack != null)
            this.callBack.progress(values);// synchronize with MAIN LOOP THREAD

    }

    @Override
    protected void onPostExecute(JSONObject jsonObject) {
        super.onPostExecute(jsonObject);

        if(this.callBack != null)
            this.callBack.sync(jsonObject);// synchronize with MAIN LOOP THREAD
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();

        if(this.callBack != null)
            this.callBack.cancel();

    }
}

Ve kullanım örneği:

public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);

         final Context _localContext = getContext();
         SomeAsyncTask.CallBack someCallBack = new SomeAsyncTask.CallBack() {

                @Override
                public void async(JSONObject jsonResult) {//async thread
                    //some async process, e.g. send data to server...
                }

                @Override
                public void sync(JSONObject jsonResult) {//sync thread
                    //get result...

                    //get some resource of Activity variable...
                    Resources resources = _localContext.getResources();
                }

                @Override
                public void progress(Integer... status) {//sync thread
                    //e.g. change status progress bar...
                }

                @Override
                public void cancel() {

                }

            };

            new SomeAsyncTask( someCallBack )
                                .execute("someParams0", "someParams1", "someParams2");

    }

0

Muhtemelen biraz denize gidiyor ama idam kodu ve sonuçları için geri aramalar sağladı. Açıkçası iş parçacığı güvenliği için yürütme geri aramasında ne eriştiğinize dikkat etmek istiyorsunuz.

AsyncTask uygulaması:

public class AsyncDbCall<ExecuteType,ResultType> extends AsyncTask<ExecuteType, Void,  
ResultType>
{
    public interface ExecuteCallback<E, R>
    {
        public R execute(E executeInput);
    }
    public interface PostExecuteCallback<R>
    {
        public void finish(R result);
    }

    private PostExecuteCallback<ResultType> _resultCallback = null;
    private ExecuteCallback<ExecuteType,ResultType> _executeCallback = null;


    AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback, PostExecuteCallback<ResultType> postExecuteCallback)
    {
        _resultCallback = postExecuteCallback;
        _executeCallback = executeCallback;
    }

    AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback)
    {
        _executeCallback = executeCallback;
    }

    @Override
    protected ResultType doInBackground(final ExecuteType... params)
    {
        return  _executeCallback.execute(params[0]);
    }

    @Override
    protected void onPostExecute(ResultType result)
    {
        if(_resultCallback != null)
            _resultCallback.finish(result);
    }
}

Geri arama:

 AsyncDbCall.ExecuteCallback<Device, Device> updateDeviceCallback = new 
 AsyncDbCall.ExecuteCallback<Device, Device>()
    {
        @Override
        public Device execute(Device device)
        {
            deviceDao.updateDevice(device);
            return device;
        }
    };

Ve son olarak zaman uyumsuz görevin yürütülmesi:

 new AsyncDbCall<>(addDeviceCallback, resultCallback).execute(device);

0

Başından Umut bu okuyunuz değilse.

https://developer.android.com/reference/android/os/AsyncTask

Sonuç verilerinin niteliğine bağlı olarak, aklınıza gelebilecek en iyi seçeneği seçmelisiniz.

Arayüz kullanmak için mükemmel bir seçimdir

diğer bazı seçenekler ..

  • AsyncTask sınıfı sonucu kullanmak istediğiniz sınıfın içinde tanımlanmışsa Statik bir global değişken veya get () kullanın, bunu dış sınıftan kullanın ( gerekirse değişken değişken ). ancak AsyncTask ilerlemesinin farkında olmalı veya en azından görevin tamamlandığından ve sonucun global değişken / get () yöntemiyle kullanılabilir olduğundan emin olmalıdır. Eğer kullanabilir yoklama, onProgressUpdate (İlerleme ...) , senkronizasyon veya arabirimleri (hangisi sizin için hiç takım elbise en iyi)

  • Sonuç paylaşılanPreference girişi olarak uyumluysa veya belleğe bir dosya olarak kaydedilmesi uygunsa , arka plan görevinin kendisinden bile kaydedebilir ve sonuç kullanılabilir olduğunda bildirim almak için onPostExecute () yöntemini
    kullanabilirsiniz. bellek.

  • Dize yeterince küçükse ve bir etkinliğin başlangıcında kullanılacaksa. onPostExecute () içinde intents ( putExtra () ) kullanmak mümkündür , ancak statik bağlamların üstesinden gelmenin o kadar güvenli olmadığını unutmayın .

  • Mümkünse, onPostExecute () yönteminden statik bir yöntem çağırabilirsiniz ve sonuç parametrenizdir.

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.