Wear'da Veri Katmanı etkinliklerini işleme

Veri katmanı API'sine bir çağrı yaptığınızda, çağrı tamamlandığında çağrının durumunu alabilirsiniz. Ayrıca, uygulamanızın Wear OS by Google ağında yaptığı veri değişikliklerinden kaynaklanan veri etkinliklerini de dinleyebilirsiniz.

Veri Katmanı API'si ile etkili bir şekilde çalışmaya dair örnek için Android DataLayer Sample uygulamasına bakın.

Veri katmanı çağrılarının durumunu bekleyin

Data Layer API'ye yapılan çağrılar (ör. DataClient sınıfının putDataItem yöntemi kullanılarak yapılan bir çağrı) bazen Task<ResultType> nesnesi döndürür. Task nesnesi oluşturulur oluşturulmaz işlem arka planda sıraya alınır. Bundan sonra başka bir işlem yapmazsanız işlem sonunda sessizce tamamlanır.

Ancak, işlem tamamlandıktan sonra sonuçla ilgili bir işlem yapmak isteyeceğiniz için Task nesnesi, sonucu eşzamansız veya eşzamanlı olarak beklemenize olanak tanır.

Eşzamansız aramalar

Kodunuz ana kullanıcı arayüzü iş parçacığında çalışıyorsa putDataItem'yı çağırmak için Data Layer API'ye engelleyici çağrılar yapmayın ve bir eş yordam kullanın:

private suspend fun Context.sendDataAsync(count: Int) {
    try {
        val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run {
            dataMap.putInt("count_key", count)
            asPutDataRequest()
        }
        val dataItem = Wearable.getDataClient(this).putDataItem(putDataReq).await()
        handleDataItem(dataItem)
    } catch (e: Exception) {
        handleDataItemError(e)
    } finally {
        handleTaskComplete()
    }
}

private fun handleDataItem(dataItem: DataItem) { }
private fun handleDataItemError(exception: Exception) { }
private fun handleTaskComplete() { }

Farklı görevlerin yürütülmesini zincirleme gibi diğer olasılıklar için Task API'ye bakın.

Eşzamanlı aramalar

Kodunuz arka plan hizmetinde ayrı bir işleyici iş parçacığında çalışıyorsa (ör. WearableListenerService), putDataItem'e engelleme çağrısı yapmak için runBlocking'yi kullanın.

Not: Bunu ana iş parçacığında çağırmayın.

private fun Context.sendDataSync(count: Int) = runBlocking {
    val putDataReq = PutDataMapRequest.create("/count").run {
        dataMap.putInt("count_key", count)
        asPutDataRequest()
    }

    try {
        val result = Wearable.getDataClient(this@sendDataSync)
            .putDataItem(putDataReq)
            .await()
        // Logic for success
    } catch (e: Exception) {
        // Handle failure
    }
}

Veri katmanı etkinliklerini dinleme

Veri katmanı, verileri senkronize edip elde taşınır ve giyilebilir cihazlara gönderdiğinden genellikle veri öğelerinin oluşturulması ve mesajların alınması gibi önemli etkinlikleri dinlemeniz gerekir.

Veri katmanı etkinliklerini dinlemek için iki seçeneğiniz vardır:

Bu seçeneklerin her ikisinde de, ilgilendiğiniz etkinlikler için veri etkinliği geri çağırma yöntemlerini geçersiz kılarsınız.

Not: Dinleyici uygulaması seçerken uygulamanızın pil kullanımını göz önünde bulundurun. Uygulamanın manifestinde bir WearableListenerService kaydedilir ve uygulama halihazırda çalışmıyorsa başlatılabilir. Yalnızca uygulamanız zaten çalışırken etkinlikleri dinlemeniz gerekiyorsa (bu durum genellikle etkileşimli uygulamalarda görülür) WearableListenerService kullanmayın. Bunun yerine canlı bir dinleyici kaydedin. Örneğin, DataClient sınıfının addListener yöntemini kullanın. Bu işlem, sistemdeki yükü ve pil kullanımını azaltabilir.

WearableListenerService kullanma

Genellikle hem giyilebilir cihaz hem de elde taşınabilir cihaz uygulamalarınızda WearableListenerService örnekleri oluşturursunuz. Ancak uygulamalardan birindeki veri etkinlikleriyle ilgilenmiyorsanız hizmeti bu uygulamada uygulamanız gerekmez.

Örneğin, veri öğesi nesnelerini ayarlayan ve alan bir elde taşınabilir uygulamanız ile kullanıcı arayüzünü güncellemek için bu güncellemeleri dinleyen bir giyilebilir cihaz uygulamanız olabilir. Giyilebilir cihaz uygulaması hiçbir veri öğesini güncellemediğinden elde taşınır cihaz uygulaması, giyilebilir cihaz uygulamasından gelen veri etkinliklerini dinlemez.

WearableListenerService kullanarak dinleyebileceğiniz etkinliklerden bazıları şunlardır:

  • onDataChanged(): Bir veri öğesi nesnesi oluşturulduğunda, silindiğinde veya değiştirildiğinde sistem, bu geri çağırmayı bağlı tüm düğümlerde tetikler.
  • onMessageReceived(): Bir düğümden gönderilen mesaj, hedef düğümde bu geri çağırmayı tetikler.
  • onCapabilityChanged(): Uygulamanızın bir örneğinin reklamını yaptığı bir özellik ağda kullanıma sunulduğunda bu etkinlik geri çağırmayı tetikler. Yakındaki bir düğümü arıyorsanız geri çağırmada sağlanan düğümlerin isNearby() yöntemini sorgulayabilirsiniz.

Ayrıca ChannelClient.ChannelCallback kaynaklı etkinlikleri de dinleyebilirsiniz. Örneğin, onChannelOpened().

Önceki tüm etkinlikler ana iş parçacığında değil, arka plan iş parçacığında yürütülür.

WearableListenerService oluşturmak için şu adımları uygulayın:

  1. WearableListenerService sınıfını genişleten bir sınıf oluşturun.
  2. İlgilendiğiniz etkinlikleri (ör. onDataChanged()) dinleyin.
  3. Sistemi WearableListenerService hakkında bilgilendirmek için Android manifestinizde bir intent filtresi tanımlayın. Bu beyan, sistemin hizmetinizi gerektiği gibi bağlamasına olanak tanır.

Aşağıdaki örnekte WearableListenerService nasıl uygulanacağı gösterilmektedir:

class DataLayerListenerService : WearableListenerService() {

    override fun onDataChanged(dataEvents: DataEventBuffer) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onDataChanged: $dataEvents")
        }

        // Loop through the events and send a message
        // to the node that created the data item.
        dataEvents
            .map { it.dataItem.uri }
            .forEach { uri ->
                // Get the node ID from the host value of the URI.
                val nodeId: String = uri.host!!
                // Set the data of the message to be the bytes of the URI.
                val payload: ByteArray = uri.toString().toByteArray()

                // Send the RPC.
                Wearable.getMessageClient(this)
                    .sendMessage(
                        nodeId,
                        DATA_ITEM_RECEIVED_PATH,
                        payload
                    )
            }
    }
}

Aşağıdaki bölümde, bu işleyiciyle amaç filtresinin nasıl kullanılacağı açıklanmaktadır.

WearableListenerService ile filtreleri kullanma

Önceki bölümde gösterilen WearableListenerService örneği için bir amaç filtresi şu şekilde görünebilir:

<service
    android:name=".snippets.datalayer.DataLayerListenerService"
    android:exported="true"
    tools:ignore="ExportedService" >
    <intent-filter>
        <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
        <data
            android:scheme="wear"
            android:host="*"
            android:path="/start-activity" />
    </intent-filter>
</service>

DATA_CHANGED işlem filtresi, sisteme uygulamanızın veri katmanı etkinlikleriyle ilgilendiğini bildirir.

Bu örnekte kol saati, /start-activity veri öğesini, telefon ise /data-item-received (DATA_ITEM_RECEIVED_PATH) mesaj yanıtını dinler.

Standart Android filtre eşleştirme kuralları geçerlidir. Manifest başına birden fazla hizmet, hizmet başına birden fazla amaç filtresi, filtre başına birden fazla işlem ve filtre başına birden fazla veri stanza'sı belirtebilirsiniz. Filtreler, joker karakterli bir ana makineyle veya belirli bir ana makineyle eşleşebilir. Joker karakterli bir ana makineyle eşleşmek için host="*" kullanın. Belirli bir ana makineyle eşleşmek için host=<node_id> değerini belirtin.

Ayrıca, tam bir yolu veya yol ön ekini de eşleştirebilirsiniz. Bunu yapmak için joker karakter veya belirli bir ana makine belirtmeniz gerekir. Aksi takdirde sistem, belirttiğiniz yolu yoksayar.

Wear OS'in desteklediği filtre türleri hakkında daha fazla bilgi için WearableListenerService ile ilgili API referans belgelerine bakın.

Veri filtreleri ve eşleştirme kuralları hakkında daha fazla bilgi için <data> manifest öğesiyle ilgili API referans belgelerine bakın.

Amaç filtrelerini eşleştirirken iki önemli kuralı unutmayın:

  • Niyet filtresi için şema belirtilmemişse sistem diğer tüm URI özelliklerini yoksayar.
  • Filtre için ana makine belirtilmezse sistem tüm yol özelliklerini yoksayar.

Canlı dinleyici kullanma

Uygulamanız yalnızca kullanıcı uygulamayla etkileşimde bulunurken veri katmanı etkinlikleriyle ilgileniyorsa her veri değişikliğini işlemek için uzun süreli bir hizmete ihtiyacı olmayabilir. Bu gibi durumlarda, bir etkinlikteki olayları dinleyebilirsiniz.

Daha temiz ve güvenli bir yaklaşım önermek için Lifecycle Observer'ı kullanın. Yaşam Döngüsü Gözlemcisi kullanarak kayıt mantığını Activity'nin onResume() bölümünden DefaultLifecycleObserver uygulayan ayrı ve yeniden kullanılabilir bir sınıfa taşırsınız.

Bu yaklaşım, etkinliğinizi yalın tutar ve dinleyici kaydını iptal etmeyi unutmak gibi yaygın hataları önler.

1. Yaşam döngüsüne duyarlı dinleyiciyi oluşturun

Bu sınıf, DataClient.OnDataChangedListener öğesini sarmalar ve kendi aboneliğini Etkinliğin yaşam döngüsüne göre otomatik olarak yönetir.

class WearDataLayerObserver(
    private val dataClient: DataClient,
    private val onDataReceived: (DataEventBuffer) -> Unit
) : DefaultLifecycleObserver, DataClient.OnDataChangedListener {

    // Implementation of the DataClient listener
    override fun onDataChanged(dataEvents: DataEventBuffer) {
        onDataReceived(dataEvents)
    }

    // Automatically register when the Activity starts
    override fun onResume(owner: LifecycleOwner) {
        dataClient.addListener(this)
    }

    // Automatically unregister when the Activity pauses
    override fun onPause(owner: LifecycleOwner) {
        dataClient.removeListener(this)
    }
}

2. Etkinliğinizdeki kullanım

Artık Wear API için Etkinliğinizin onResume() veya onPause()'ı geçersiz kılması gerekmiyor. Gözlemciyi onCreate()'ya bir kez eklersiniz.

class DataLayerLifecycleActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val dataClient = Wearable.getDataClient(this)

        // Create the observer and link it to the activity's lifecycle
        val wearObserver = WearDataLayerObserver(dataClient) { dataEvents ->
            handleDataEvents(dataEvents)
        }

        lifecycle.addObserver(wearObserver)
    }

    private fun handleDataEvents(dataEvents: DataEventBuffer) {
        // ... filter and process events ...
    }
}

Bu yöntem neden daha iyi?

  • Temizleyici Etkinliği: Etkinlik yaşam döngüsü yöntemlerinden ortak metinleri kaldırırsınız.
  • Güvenlik: DefaultLifecycleObserver, Etkinlik beklenmedik bir şekilde yok edilse bile dinleyicinin kaldırılmasını sağlayarak bellek sızıntılarını önler.
  • Yeniden kullanılabilirlik: Kayıt mantığını yeniden yazmadan bu WearDataLayerObserver öğesini herhangi bir Etkinliğe veya Parçaya bağlayabilirsiniz.
  • Ayrıştırma: Ne zaman dinleneceğine dair mantık, verilerle ne yapılacağına dair mantıktan ayrılır.

Canlı dinleyicilerle filtreleri kullanma

Daha önce de belirtildiği gibi, manifest tabanlı WearableListenerService nesneler için amaç filtreleri belirtebildiğiniz gibi, Wearable API aracılığıyla canlı bir dinleyici kaydederken de amaç filtrelerini kullanabilirsiniz. Aynı kurallar hem API tabanlı canlı dinleyiciler hem de manifest tabanlı dinleyiciler için geçerlidir.

Yaygın bir yöntem, LifecycleObserver kullanarak belirli bir yola veya yol önekine sahip bir dinleyici kaydetmektir. İşleyicileri bu şekilde uygulayarak uygulamanız etkinlikleri daha seçici bir şekilde alabilir, böylece tasarımını ve verimliliğini artırabilir.