29 Temmuz 2013 Pazartesi

AsyncTask'den Değer Döndürmek


Merhabalar,

Android uygulaması geliştirirken bir kaynak tüketimi(internetten dosya çekmek vs.) söz konusu olduğunda bildiğiniz üzere, işlem sırasında grafik arayüzünün(ui) donmaması için bu tarz uzun süreli işlemleri ui thread yerine ayrı bir thread'de ele almak gerekir. Bu işlemi ayrı thread'de koştururken kullanıcıya da işlemin tamamlanma süreci progressbar ile gösterilirse hoş bir deneyim sağlanmış olur.

Android ortamında asenkron olarak thread koşturmak için genelde AsyncTask sınıfı kullanılır, bu sınıfın sunduğu yapı sayesinde, artalanda işlem yapmak kolaylaştırılmıştır. Çoğunlukla AsyncTask sınıfı activity'lerde iç sınıf olarak uygulanır, fakat birden çok activity içinde aynı kaynak tüketilecekse(bir sayfaya talep göndermek gibi) kod sadeliği, dry ve standardizasyon için bu sınıfı harici bir dosyaya çıkmak yerinde olacaktır. Yine oluşturulan bu sınıfın(AsyncTask) kullanımı sırasında tüketilen kaynağın/verinin bağlanacağı activity kontrollerinin(TextView vs.) referanslarının, parametre olarak bu sınıfa geçilmesi kod ve bağımlılık karmaşası yaratabilir. Bu sebeple AsyncTask sınıfının onPostExecute metodunun -bir arayüz yardımıyla- kullanıcı sınıfına(çoğu kez activity sınıfına) açılması uygun bir çözüm olacaktır. Kodlamaya koyulursak:

1) AsyncTask sınıfının onPostExecute metodunu kullanıcı sınıfa açmamıza yardımcı olacak arayüz:

public interface DownloadCallback {
   void onSuccess(String downloadedString);
   void onFailure(Exception exception);
}

2)  Birden çok yerde kullanılacak olan, artalan işlemi kotaran AsyncTask sınıfı:

// <Params, Progress, Result>
public class DownloadDataAsyc extends AsyncTask<String, Integer, String> {
  ProgressDialog mProgressDialog;
  DownloadCallback mDownloadCallback;
  Exception mException;
  Context mContext;


  public DownloadDataAsyc(Context context, DownloadCallback downloadCallback) {
    mContext = context;
    mDownloadCallback = downloadCallback;
  }

  @Override 
  protected void onPreExecute() {
    super.onPreExecute();
    mProgressDialog = new ProgressDialog(mContext);
    mProgressDialog.setMessage("Downloading.. ");
    mProgressDialog.show(); 
  }

  @Override 
protected String doInBackground(String... p) {
  try {
    return Helper.DownloadStringData(p[0]);
    } catch (Exception e) {
    mException = e;
    return null;
    }
}

  @Override 
  protected void onPostExecute(String result) {
    mProgressDialog.dismiss();
    if ( result== null ) {
       mDownloadCallback.onFailure(mException);
    } else {
       mDownloadCallback.onSuccess(sonuc);
    }
 }
}

3) Kullanıcı sınıf içerisinde  oluşturulan AsyncTask sınıfının kullanımı:

public void onClick(View view) {
   new DownloadDataAsyc(this, new DownloadCallback() {
     @Override 
     public void onSuccess(String downloadedString) {
     // sonucu ilgili kontrol(ler)e bağla
    }
    @Override 
     public void onFailure(Exception exception) {
    // hatayı logla, kullanıcıya duruma dair bir mesaj göster
    }
  });
}

Umarım faydalı olur, verimli kodlamalar :]

Hiç yorum yok:

Yorum Gönder