Bu dersimizde androiddeki looper kavramını anlatırken handler kullanımını tekrar etmiş olacağız ve günün sonunda main thread’den bir worker thread’e nasıl veri göndereceğimizi öğrenmiş olacağız.
Şuana kadar worker thread’den main thread’e direk erişim olamayacağından, ui elementlerin worker thread üzerinden güncellenemeyeceğinden ve bu sorunu aşmak için farklı çözümlerden bahsettik. Bu derste ise tam tersi bir işlemi handler kullanarak nasıl aşacağımızdan bahsetmeye çalışalım.
Main thread’in kendi içinde bir looperı ve mesaj kuyruğu zaten vardır. Daha önceki derste bir handler oluşturarak sendMessage ve handleMessage methotlarını kullanarak veri göndermeyi öğrenmiştik. Ve bildiğiniz gibi handler nesnesi nerede tanımlanıyorsa o threadin mesaj kuyruğuna bağlanıyordu.
Peki biz kendi thread’imizi oluşturduğumuzda ne oluyor? Yeni threadin mesaj alma ve gönderme işlemlerini ele alacak bir looper ve mesaj kuyruğu mekanizması yoktur. Bunları bizim tanımlamamız gerekiyor. Handler nesnesini kullanarak sendMessage deriz ve bu mesaj ilgili threadin mesaj kuyruğuna gider ve oradan da looper ile handleMessage methoduna iletilir.
Yani worker threadde main threadden gelecek mesajları ele almak için bir loopera ve mesaj kuyruğu yapısına ihtiyacımız var. İlgili threadde Looper.prepare() methodu ile o threadin loopera sahip olmasını sağlarız. Daha sonrada Looper.loop() methodu ile de kuyruktaki mesajların işlenmesini gerçekleştiririz. Main threadden gönderilen veri kuyruktan looper ile alınır ve handle nesnesinin onHandle mesajına gelir. Bu yüzden handler’ın tanımlanması worker thread içinde yapılmalı ki o threadin mesaj kuyruğuna baglansın. Aksi taktirde main thread’e ve onun mesaj kuyruğuna bağlanacağı için biz worker threadden main thread’e veri gönderebilirz, tam tersi durum olmaz.
Bu derste yazılan kodlar aşağıdaki gibidir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
public class MainActivity extends AppCompatActivity { MyThread myThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myThread = new MyThread(); myThread.start(); } public void sendMessagetoBackgroundThread(View view) { Message mesaj = Message.obtain(); mesaj.arg1 = 1; myThread.handler.sendMessage(mesaj); } } class MyThread extends Thread { Handler handler; public MyThread() { } @Override public void run() { Looper.prepare(); handler = new Handler() { @Override public void handleMessage(Message msg) { Log.i("emre", "Gelen veri:" + msg.arg1 + " Thread adı:" + Thread.currentThread().getName()); } }; Looper.loop(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.emrealtunbilek.looperkavrami.MainActivity"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="49dp" android:text="Send Message to Background Thread" android:layout_centerVertical="true" android:onClick="sendMessagetoBackgroundThread" android:layout_alignParentEnd="true" /> </RelativeLayout> |