IPC Yöntemleri 2 - Messenger ve Broadcast

Bir önceki yazıda IPC'nin tanımından ve AIDL yönteminden bahsetmiş, AIDL yöntemini kullanan, istemci-sunucu yapısında çalışan iki örnek uygulama yapmıştık. Yazıya buradan ulaşabilirsiniz.


Şimdi bu iki uygulamaya, Messenger ve Broadcast yöntemlerini de destekleyecekleri şekilde eklemeler yapacağız.


Messenger


Messenger, uzak process'e gönderilen bir Handler'dır.

Bu yöntemde, ilk yazıda bahsedilen AIDL yöntemi gibi Binder mimarisine sahiptir. Implement etmesi AIDL yönteminden çok daha kolaydır; nispeten kafa karıştırıcı olan AIDL dosyasını, arkaplanda kendisi oluşturur ve kullanır.


Ama zaman zaman karşılaştığımız gibi, implement etmesi kolay araçlar beraberinde kısıtlamalar getirebiliyorken, zor implement edilen araçlar ise esneklik avantajı sağlayabiliyor. Messenger ve AIDL yöntemi de tam olarak bu duruma uyuyor:


  • Örneğin AIDL ile, eşzamanlı (concurrent) işlemler yapma olanağınız vardır. Messenger'da ise çağrılar bir kuyruğa alınır ve sırayla (sequentially) gerçekleştirilir. Bir t anında en fazla bir process/thread'den çağrı alınacağı garantilenmiştir.


Bir önceki örnektekine benzer işler yapacağız. İstemci, yine sunucunun servisine bind olacak. Bu yolla, sunucuda oluşturduğumuz Messenger'ı istemciye döndüreceğiz. Böylece iki uygulama Message objeleri ile haberleşebilecekler.



Sunucu Uygulaması


Servise, istemci uygulamasından intent ile iletilecek "messengerexample" action'ını ekleyelim. Böylece bind olan bileşenin hangi IPC metodunu kullandığını belirlemiş olacağız.


  • Serviste, istemciden gelen mesajları ele alacağımız Handler objesini oluşturalım

  • Gelen mesaja göre grafik arayüzde kullanmak üzere RecentClient objemizi güncelliyoruz

  • Handler objesi ile Messenger'ı oluşturalım. Haberleşme bu obje üzerinden gerçekleşecek.

  • Burada msg.replyTo objesi istemcinin mesajından elde ediliyor. Bu örnekte böyle bir ihtiyacımız yok fakat, bunu yerel bir değişkene atayıp herhangi bir zamanda tekrar istemciye mesaj göndermek için kullanmak mümkün. Örneğin sunucuda uzun sürecek bir işlem tetiklendiyse, işlem bitiminde istemciye callback dönmek gibi bir senaryoda kullanılabilir. Messenger'ın belki en avantajlı taraflarından biri bu şekilde az bir eforla çift yönlü iletişim kurulabiliyor olması.


  • Mesajlardaki bundle keyi olarak kullandığımız sabitler:


  • "messengerexample" action'ı ile servise bind olan istemci için servisimizdeki onBind methodunu güncelleyelim.

  • Oluşturduğumuz Messenger objesi internal bir binder'a sahip. İstemciye bu binder'ı döndürüyoruz.


Servis uygulaması bu kadar. Messenger ile bir istemci bağlandığında grafik arayüz bu şekilde görünecek:





İstemci Uygulaması


  • Mesajlardaki bundle keyi olarak kullandığımız sabitleri burada da ekleyelim


  • Aidl fragmentı için kullandığımız xml'in aynısını kullanıyoruz. Sadece buton ismi farklı:



  • Bu sefer iki tane Messenger objesi tanımlıyoruz. clientMessenger, sunucuya mesaj göndermek için; serverMessenger, sunucuya "mesajımı yanıtlarken bu objeyi kullan" demek için.

  • Gelen mesajları ele almak için bir handler tanımlayalım. Burada grafik arayüzünü güncelleyelim.


  • Bağlan butonuna basıldığında sunucuya bind olalım, bağlantıyı kes butonunda unbind olalım.


  • bindService komutunu çağırdıktan sonra servis ile bağlantı kurulursa onServiceConnected callbackini alıyoruz.

  • Callbacki aldığımızda sunucuya mesaj gönderelim.

  • Mesajı hazırlarken, yanıtları beklediğimiz objeyi, message.replyTo = clientMessenger diyerek bildirelim.

  • Servis bağlantımız koptu ise grafik arayüzdeki bilgileri kaldıralım.


  • Servisten gelecek yanıtı başta tanımladığımız handler objemizde ele alacağız

  • Fragmetın son hali bu şekilde olacak:


İstemci uygulamasını da tamamladık. Bağlantı kurulduğunda arayüz bu şekilde görünecek:





Broadcast


Her Android geliştiricinin aşina olduğu Broadcast, bir IPC yöntemi olarak diğer iki yöntemden farklı bir yapıdadır.


Broadcastler, sistem tarafından veya uygulamalar tarafından yayınlanabilir. Uygulamalar spesifik broadcastleri BroadcastReceiver ile dinlemek için kayıt olabilirler .


Receiverlar, varsayılan olarak, dışa açıktır (exported) ve herhangi başka uygulama tarafından gönderilen broadcasti karşılayabilir. Dışa açık receiverlar için Manifest'te <receiver> taginde izinler/action filtreleri tanımlanarak basit bir güvenlik katmanı oluşturulabilir. Gerekli izne/action'a sahip olmayan uygulamalardan gelebilecek broadcastler bu şekilde engellenmiş olur.


Bu örnekte, broadcasti sadece belirli bir uygulamaya/uygulamalara atmak istiyoruz, bu yüzden paket adı veya sınıf adı belirtilerek explicit intent kullanacağız.


API level 26 için Manifest'te tanımlanan broadcastler için getirilen kısıtlamalardan explicit broadcastler muaftır. Manifestte tanımlanan broadcastler uygulama yüklenirken register olur ve receiver, uygulama için bir başka giriş noktası haline gelir. Bu tanımda varsayılan olarak, FLAG_INCLUDE_STOPPED_PACKAGES flagi true olarak işaretlidir. Yani uygulama çalışmıyorken bu broadcast gelirse, sistem uygulamayı ayaklandırır. Tıpkı AIDL ve Messenger yönteminde bindService çağrısının servisi/uygulamayı ayaklandırdığı gibi.



İstemci Uygulaması


  • Bu sefer çift taraflı bir iletişim olmadığı için sunucu uygulamasının bilgilerini almıyor, sadece istemcinin bilgilerini içeren bir broadcast gönderiyoruz. Ekranda yalnızca broadcast gönderme zamanını göstereceğiz.


  • Butona basıldığında broadcasti göndereceğiz.

  • Broadcasti sadece belirli bir uygulama dinleyebilsin diye, sunucunun paket adı ve receiver'ın sınıf adını içeren explicit bir intent tanımlıyoruz.

  • Kullanıcıya sadece broadcast gönderme zamanını göstereceğiz.


İstemci uygulamasını tamamladık. Broadcast gönderildiğinde arayüzde bu şekilde görünecek:




Sunucu Uygulaması


  • Receiver'ı exported olarak işaretleyerek Manifest'te bildiriyoruz

  • Broadcast intent'inde kullandığımız filtreyi ekledik. Filtre bir paket adı olmak zorunda değil. Başka uygulamaların tanımladığı filtrelerle çakışma ihtimalini azalttığı için böyle kullandık.


  • Receiver olacak sınıfı oluşturalım

  • Intent ile aldığımız bilgilerle arayüzdeki istemci bilgilerini güncelleyelim


Sunucu uygulamasını da tamamladık. Broadcast geldiğinde arayüzde bu şekilde görünecek:




Android'de processler arası haberleşme yaklaşımlarına değindik ve üç ayrı IPC tekniğini destekleyen bir uygulama yaratmış olduk. Uygulamanın kaynak kodlarına aşağıdan ulaşabilirsiniz.



Kaynak Kod: github.com/perihanmirkelam/IPC-Examples


Bu yazıyı yazarken faydalandığım kaynaklar:


#ipc #interprocesscommunication #messenger #broadcast #android



0 yorum

Komünite

Platform

Mobiler.dev Anasayfa
  • Twitter
  • Instagram
  • development_düzenlendi_düzenlendi
  • Youtube
  • slack-icon-black_edited_edited_edited
  • Gri LinkedIn Simge
imageedit_2_9667998092.png
JetBrains Hakkında Detaylı Bilgi Alın

© 2020 by mobiler.dev

Kurumsal Yazar Hesapları

adesso.png
mobilerdevLogo.jpg
Yazarlık Başvurusu Hakkında Bilgi Alın, Başvuru Yapın.
Topluluk Yazarlarını Tanıyın