SORU
28 Temmuz 2010, ÇARŞAMBA


AsyncTask gerçekten kavramsal olarak kusurlu olduğunu ya da sadece bir şey eksik muyum?

Aylardır bu sorunu şimdi, tüm büyük kesmek oldukları için mutlu değilim ki farklı çözümler ile geldi, araştırdık. Hala tasarım defolu çerçeve ve kimse bu yüzden bir sınıf bunu konuşuyor, ben sadece bir şey eksik olmalı ki inanamıyorum.

Sorun AsyncTask ile. Belgelere göre

< . p ^"arka planı gerçekleştirmek için izin verir işlemleri ve yayınla ilgili sonuçlar İşlemek zorunda kalmadan UI iş parçacığı iş parçacıkları ve/veya işleyicileri."

Örnek daha sonra showDialog() bazı örnek yöntemi onPostExecute() denir nasıl göstermeye devam ediyor. Bu, ancak, görünüyortamamen yapmacıkbana, bir iletişim kutusu gösterme, çünkü her zaman geçerli bir başvuru gerekiyor Context ve bir AsyncTaskhiç bir içerik nesnesi için güçlü bir referans tutmak gerekir.

Aktivite yok olacak, görev tetikleyen ne? nedeni belli: Bu ekranı çevirdi, çünkü her zaman, örneğin olabilir. Eğer görev oluşturulduğu bağlam için bir başvuru yapacağını, sadece işe yaramaz bir bağlam (pencere yok edildi . nesne tutarak değilsin ^em>herhangi birUI etkileşimi bir istisna ile başarısız olur!), hatta bir bellek sızıntısı riskiyle karşı karşıya.

Tabii benim mantığım hatalı burada, bu çevirir: onPostExecute() tamamen işe yaramaz, çünkü ne işe yarar bu yöntem için gerekli olan UI iş parçacığı yoksa erişmek için herhangi bir konu var mı? Hiçbir şey anlamlı burada yapamazsın.

Bir geçici çözüm, bir AsyncTask ama Handler bir örneği örnekleri bağlam değil geçmek olacaktır. Bu eserler: bir İşleyici gevşek bağlam ve görev bağlar bu yana, bir sızıntı (değil mi?) riske atmadan onların arasında mesaj alışverişi yapabilirsiniz. Ama işleyicileri ile rahatsız etmek gerekmez AsyncTask öncül, yani yanlış olduğu anlamına gelir. Ayrıca gibi kötüye İşleyicisi beri mesaj gönderme ve alma aynı iş parçacığı (oluşturma üzerinde UI iş parçacığı ve Gönder onu onPostExecute() de yürütülen UI thread).

Hepsini, bu geçici çözüm bile üstüne, hala içerik yok olacak, zaman sorunu varbir kayıt yokgörevlerinden istifa etti. Yeniden başlamak yeniden oluştururken herhangi bir görev için, örneğin ekran yönünü değiştirdikten sonra içerik anlamına gelir. Bu yavaş ve gereksiz.

Bu benim çözüm (implemented in the Droid-Fu library) benzersiz bir uygulama nesnesinde mevcut örneklerine bileşen adları WeakReferences bir eşleme korumak için. Bir AsyncTask başlatıldığında, bu harita içinde arama bağlam kayıtları, ve her geri arama, eşleme, geçerli bağlam örnek alacağız. Bu hiç bayat bir bağlam örneği referans olmasını sağlarveher zaman anlamlı UI iş yapabileceğin çok geri, geçerli bir bağlam erişebilirsiniz. Ayrıca başvurular zayıf ve belirli bir bileşen örneği artık ne zaman silineceği için sızıntı yok.

Yine de, karmaşık bir çözüm olduğunu ve alt sınıfta Droid-Fu kütüphane sınıfları bazıları, bu çok müdahaleci bir yaklaşım yapmak gerekir.

Şimdi ben sadece bilmek istiyorum:Sadece kitlesel eksik bir şey ya da AsyncTask gerçekten tamamen kusurlu ben miyim? Nasıl deneyimleri ile çalışıyor musunuz? Nasıl bu sorunu çözmek mi?

Giriş için teşekkürler.

CEVAP
29 Temmuz 2010, PERŞEMBE


Nasıl bir şey hakkında bu gibi:

class MyActivity extends Activity {
    Worker mWorker;

    static class Worker extends AsyncTask<URL, Integer, Long> {
        MyActivity mActivity;

        Worker(MyActivity activity) {
            mActivity = activity;
        }

        @Override
        protected Long doInBackground(URL... urls) {
            int count = urls.length;
            long totalSize = 0;
            for (int i = 0; i < count; i  ) {
                totalSize  = Downloader.downloadFile(urls[i]);
                publishProgress((int) ((i / (float) count) * 100));
            }
            return totalSize;
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            if (mActivity != null) {
                mActivity.setProgressPercent(progress[0]);
            }
        }

        @Override
        protected void onPostExecute(Long result) {
            if (mActivity != null) {
                mActivity.showDialog("Downloaded "   result   " bytes");
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mWorker = (Worker)getLastNonConfigurationInstance();
        if (mWorker != null) {
            mWorker.mActivity = this;
        }

        ...
    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        return mWorker;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mWorker != null) {
            mWorker.mActivity = null;
        }
    }

    void startWork() {
        mWorker = new Worker(this);
        mWorker.execute(...);
    }
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Chuck Testa

    Chuck Testa

    14 AĞUSTOS 2011
  • TheDroidDemos

    TheDroidDemo

    15 ŞUBAT 2011
  • TopOfTheTech

    TopOfTheTech

    5 NİSAN 2010