9 Nisan 2018 Pazartesi

AsyncTask Sınıfı

Giriş
Şu satırı dahil ederiz.
import android.os.AsyncTask;
Açıklaması şöyle
AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.
AsyncTask bazı sıkıntılara sahip. Açıklaması şöyle
Long running tasks,
Having poorly being tied to Activity life cycle,
Device orientation problems, and
Memory leaks and so on.
Long Running Task Problemi
Açıklaması şöyle.
In most scenarios AsyncTask should suffice the requirement. However there are scenarios where AsyncTask can't be used. ie AsyncTask manages a thread pool, from which it pulls the threads to be used by task instances. Now the thread pools assume that they'll get their threads back after a reasonable period of time. So in a scenario where you do not know how long you'll need the thread you can't use an AsyncTask. And as of Android 4.4 , the size of thread pool can grow only to : (no of CPU cores * 2) + 1. So on a dual core processor, the maximum number of threads you can create is limited to 5.
Memory Leak Problemi
Açıklaması şöyle.
Normally when the orientation changes, Android framework destroys the activity (garbage collects the memory allocated) and creates a new one.

Now say you are running an AsyncTask which holds a reference to an Activity class object and the orientation changes. Here, Android framework would not be able to destroy the activity (as it is still referenced by your AsyncTask) while a new one will be created in its place. This is one of the ways how memory leaks happen.
Diğer Seçenekler
AsyncTask yerine şunlar kullanılabilir.
Handler
Runnable
Loader

Tanımlama
AsyncTask sınıfı şöyle bir iskelete sahiptir.
public abstract class AsyncTask<Params, Progress, Result> 
1. İlk generic parametre Params'tır. Task'ı çalıştırmak için gereken parametreyi belirtir.
2. İkinci generic parametre Progress'tir. onProgressUpdate() metoduna geçilecek parametre tipini belirtir.
3. Üçüncü generic parametre Result tipidir. doInBackground'un döndüreceği nesne tipini belirtir. Bu nesne tipi onPostExecute() metoduna sonuç olarak verilen nesnedir.
public class MyTask extends AsyncTask<String, String, String> {
  @Override
  protected void onPreExecute() {
    super.onPreExecute();
    ...
  }
  @Override
  protected String doInBackground(String... strings) {
    return ...;
  }
  @Override
  protected void onPostExecute(String Result) {
    super.onPostExecute(Result);
      ...
    }
}
cancel metodu
Activity içinde durdurmak için şöyle yaparız.
public void onPause() {
  super.onPause();
  myTask.cancel(true);
}
doInBackGround metodu
Metodun imzası şöyle
@Override
protected Void doInBackground(String... arg) {...}
Arka planda yapılması istenen iş burada kodlanır. Örneğin ağdan bir şeyler yüklemek için kullanılabilir.

execute metodu
Task'ı başlatır.
Örnek
Şöyle yaparız.
movieTask.execute("");
Örnek
doInBackGround metoduna paretre geçmek için şöyle yaparız.
myTask.execute("abc", "10", "Hello world");
Örnek
Activity içinde devam etmek için şöyle yaparız.
public void onResume() {
  super.onResume();
  myTask.execute(null);
}
executeOnExecutor metodu
Şöyle yaparız.
if (Build.VERSION.SDK_INT >= 11)
  task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
get metodu
Açıklaması şöyle.
Waits if necessary for the computation to complete, and then retrieves its result.
Task bitinceye kadar çağıran kod bloke olur.
Örnek
Şöyle yaparız.
String serverResponse = myTask.execute(...).get();
Örnek
Sınıfımızın String döndüğünü varsayarsak ve exceptionları da dikkate alırsak şöyle yaparız.
MyTask task = new MyTask();
String result = null;

try {
  result = task.execute("...").get();

  Log.i("Contents of the url:", result);

}
catch (InterruptedException e) {
  ...
}
catch (ExecutionException e) {
  ...
}
isCancelled metodu
doInBackGround içinde şöyle yaparız.
while (!isCancelled()) {
  ...
}
onPreExecute -  GUI güncellenebilir
İmzası şöyle
@Override
protected void onPreExecute() {...}
onProgressUpdate metodu - GUI güncellenebilir
onProgressUpdate () için doInBackGround() içinde publishProgress() çağrılır. Şöyle yaparız.
public class MyTask extends AsyncTask<String, Void, String> {

  @Override
  protected String doInBackground(String... params) {
    while(...){
      publishProgress();
    }
    return "done";
  }

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

    textView.setText("...");    
  }
}
onPostExecute metodu - GUI güncellenebilir
İmzası şöyle
@Override
protected void onPostExecute(String s) {...}
Mesela iş bitince başka bir iş başlatılabilir.


Hiç yorum yok:

Yorum Gönder