Başlangıç / Dünya / Android Arka Plan İşlemleri : Thread ve AsyncTask

Android Arka Plan İşlemleri : Thread ve AsyncTask

Process ve Thread

Yazılım tabanlı programlarda bir uygulama başlatıldığı zaman bir process başlatılır ve bu process tek bir thread tarafından yürütülmektedir. Buna main(ana) thread veya UI (user Interface-Arayüz) adı verilmektedir. Uygulamanız içerisinde gerçekleşecek tüm işlemler bu ana thread üzerinde çalışmaktadır.

Uygulama içerisinde tetiklenen bu yapı diğer tüm uygulamalar içinde geçerlidir. Uygulama içerisinde başlatmış olduğunuz bir işlem bir diğer uygulama bileşenini yok ederek uygulamanızı tek bir iş parçacığı ile başlatır. Yani kullanıcının herhangi bir sorgulama işlemi arayüzünü bloke ederek kullanıcının işlem yapmasına engel olmaktadır. Bu süreç içerisinde eğer 5 saniye içerisinde tamamlanmazsa sistem uygulamanızı ANR (Application Not Responding – Uygulama Cevap Vermiyor) hata mesajı ile kapanacaktır. Sonuç olarak Thread işlemi bir uygulama içerisinde aynı anda birden fazla işlem yapmamıza olanak sağlayan java programlama dilinin desteklediği bir imkândır.

Processes

İşlem süreci içerisinde uygulamada tüm bileşenler aynı süreçte çalıştırılmaktadır ve bunu kullanıcı değiştirememektedir. Örneğin bir dosya verisini işlemek için kullanıcı bazı bildirimler ile işlem süreci içerisinde denetlenmektedir ve bu süreci uygulamanız içerisinde belirtmek mümkündür. Android işlem niteliği; aktivite, hizmet, alıcı ve sağlayıcı için bildirim girişini desteklemektedir. Her bir bileşen işlem sürecini diğerleri yok iken paylaşmaktadır.

Processes Lifecycle

Android sistemler mümkün olduğunca uzun bir uygulama sürecini sürdürmek için geliştirilmişlerdir. Bu işlem için sürekli devam eden işlemler sonunda yeni ya da daha önemli süreçler için bellekten eski işlemler kaldırılarak gerçekleştirilir. Burada da karşımıza işlem önceliği için “Önem Hiyerarşisi” kavramı çıkmaktadır. Bir uygulama içerisinde işlem döngüsünün nasıl yer alacağı burada karar verilmektedir. Gerekli sistem kaynaklarını kurtarmak için süreçlerin önem derecesine göre elemesi yapılır. Önemli süreçler başa alınır ve daha düşük öneme sahip olanlar elenir. Önem aşamasının 5 aşaması vardır. Bunlar:

  • Foreground Process ( Önalan Süreç)
  • Visible Process (Görünür Süreç)
  • Service Process
  • Backgorund Process
  • Empty Process

Android uygulamalarında bir veri kaynağına bağlanarak okuma ya da yazma işlemlerini gerçekleştirmek isteyen bir kullanıcı bu işlemi arka arkaya tekrar etmesi halinde önceki işlemin bitmesini tamamlanmasını beklemesi gerekecektir. Bu işlem yazılım açısından verimliliği düşüren bir etkendir. Bu nedenle uygulama içerisinde thread kullanarak aynı anda başlayıp biten işlemlerin gerekli sonuçlar üretmesini sağlayabiliyoruz. Bu işlem için android’de kullanılan genel yapı aşağıdaki gibidir.

  1. Thread nesnesi oluştur
  2. Thread’in run() metodunu çalıştır ve işlemleri run() metodunda başlat
  3. Handler() sınıfı oluştur
  4. Handler sınıfı içerisinde handleMessage() ile thred’den dönen sonucu al.

Örnek: Hesaplaması uzun süren pi(π) sayısının hesaplama işlemi devam ederken aynı zamanda bu işlemin gerçekleştirildiğini bildiren iletişim kutusunu çalışmaya başlatarak pi sayısının işlemi bitince hesaplama sonucunu ekrana yazıp iletişim kutusunun kaldırılması işlemi.

1

 

Bu işlem için öncelikle Main.java Activity sınıf kodlarımız:

import android.app.Activity;

import android.app.ProgressDialog;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

public class Main extends Activity {

            Button threadTestButton;

            String piValue;

            TextView textView;

            ProgressDialog progressDialog;

            @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        threadTestButton = (Button) findViewById(R.id.threadTestButton);

        textView = (TextView) findViewById(R.id.hesaplananDeger);

        threadTestButton.setOnClickListener(new OnClickListener() {

                                   public void onClick(View v) {

                                               progressDialog = ProgressDialog.show(Main.this, "Hesaplanıyor..", "Pi sayısı hesaplanıyor");

                                               Thread thread = new Thread(new Runnable() {

                                                           public void run() {

                                                                       piValue = new Pi().computePi(800).toString();

                                                                       handler.sendEmptyMessage(0);

                                                           }

                                               });

                                               thread.start();

                                   }

                        });

    }

            private Handler handler = new Handler() {

        @Override

        public void handleMessage(Message msg) {

            textView.setText(piValue);

            progressDialog.dismiss();

        }

            };        

}

Main.java Activity’sinin kullandığı layout dosyası main.xml içeriği:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<Button android:id="@+id/threadTestButton"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hesapla"
/>   
<TextView  
    android:id="@+id/hesaplananDeger"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />
</LinearLayout>

Örnekte yer alan hesaplamanın uzun sürdüğü işlem pi sayısının hesaplanmasıdır. Pi sayısının hesaplanma işlemi için Pi.java sınıfı yazılmıştır.

 

import java.math.BigDecimal;

public class Pi {
	
    private static final BigDecimal FOUR = BigDecimal.valueOf(4);

    private static final int roundingMode = BigDecimal.ROUND_HALF_EVEN;

    public static BigDecimal computePi(int digits) {
        int scale = digits + 5;
        BigDecimal arctan1_5 = arctan(5, scale);
        BigDecimal arctan1_239 = arctan(239, scale);
        BigDecimal pi = arctan1_5.multiply(FOUR).subtract(
                                  arctan1_239).multiply(FOUR);
        return pi.setScale(digits,
                           BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal arctan(int inverseX,int scale)
    {
        BigDecimal result, numer, term;
        BigDecimal invX = BigDecimal.valueOf(inverseX);
        BigDecimal invX2 = BigDecimal.valueOf(inverseX * inverseX);
        numer = BigDecimal.ONE.divide(invX,scale, roundingMode);
        result = numer;
        int i = 1;
        do {
            numer = numer.divide(invX2, scale, roundingMode);
            int denom = 2 * i + 1;
            term =   numer.divide(BigDecimal.valueOf(denom), scale, roundingMode);
            if ((i % 2) != 0) { result = result.subtract(term);
            } else { result = result.add(term);
            }
            i++;
        } while (term.compareTo(BigDecimal.ZERO) != 0);
        return result;
    }	
}

Android projemiz emülatör üzerinden derlenmemiştir. Android işletim sistemine sahip mobil telefon üzerinde derlenip alıştırılmıştır. Uygulamamızın ekran görüntüleri aşağıdaki gibidir:

SC20150410-011340 SC20150410-012123

 

Thread uygulamasını indirmek için =>

AsyncTask (Asenkron İşlemleri)

 

Android programlamada thread gibi asenkron işlemlerde kullanılan AsyncTask sınıfı bulunmaktadır. Çok işlemli (MultiThread) işlemlerde bu sınıf kullanılarak normalde yapamayacağımız işlemleri rahatlıkla yapabilmekteyiz.

 

AsyncTask sınıfının içerisinde aşağıdaki metotlar bulunmaktadır.

  1. onPreExecute() Asenkron işlem başlamadan önce çalışır
  2. doInBackground() Asenkron işlem başlayınca çalışır
  3. onPostExecute() Asenkron işlem tamamlanınca çalışır.

AsyncTask sınıfının kullanılabilmesi için Activity içerisinde bir iç sınıfa (inner class) ihtiyaç vardır. Bu sınıfı AsyncTask sınıfından üreterek asenkron işlemlerimizi gerçekleştirebiliriz.
Bu örnek için yukarıda kullanmış olduğumuz projenin layout dosyası ve Pi sınıfı aynen kullanılmıştır.

Pi sayısını hesaplamak için bir işlem başlatıp aynı anda ekrana hesaplamanın yapıldığı bir iletişim kutusu çıkaran programın Main.java Activity kodları:

2

 

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;

public class Main extends Activity {

	Button asyncTaskButton;
	String piValue;
	TextView hesaplananTextView;
	

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
	    hesaplananTextView = (TextView) findViewById(R.id.hesaplananDegerText);
        asyncTaskButton = (Button) findViewById(R.id.asnycTaskTest);
	    new IslemTask().execute();

    }
    
    private class IslemTask extends AsyncTask<String, Void, Void>{
    	ProgressDialog progressDialog;

		protected void onPreExecute() {
			  progressDialog = ProgressDialog.show(Main.this, "Hesaplanıyor..", "Pi sayısı hesaplanıyor");
		}
		
		@Override
		protected Void doInBackground(String... params) {
			piValue = Pi.computePi(800).toString();
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			Main.this.hesaplananTextView.setText(piValue);
			progressDialog.dismiss();
		}
		
	}
}

Burada gerçekleşen işlem, biz uygulamayı başlattığımız anda gerçekleşmekte ve program açılırken aynı anda pi sayısı hesaplanmakta ve kullanıcıya mesaj olarak bu bilgi mesaj penceresi aracılığı ile sunulmaktadır.

s1 SC20150410-030533

 

AsyncTask uygulamasını indirmek için => 

Hakkında: BilgiDili

Kontrol Ediliyor

Burma’daki Altın Kayanın sırrı çözüldü

Uçurumun kenarındaki Kutsal Altın taş Burma’nın Mon kentinde uçurumun kenarında kutsal sayılan altın bir taş …

Bir Cevap Yazın