เมื่อเรียกใช้ Data Layer API คุณจะได้รับสถานะของการเรียกใช้เมื่อการเรียกใช้เสร็จสมบูรณ์ นอกจากนี้ คุณยังฟังเหตุการณ์ข้อมูลที่เกิดจากการเปลี่ยนแปลงข้อมูลที่แอปของคุณทำได้ทุกที่ในเครือข่าย Wear OS by Google
ดูตัวอย่างการทำงานกับ Data Layer API อย่างมีประสิทธิภาพได้ที่แอป Android DataLayer Sample
รอสถานะของการเรียกใช้ Data Layer
การเรียกใช้ Data Layer API เช่น การเรียกใช้โดยใช้เมธอด putDataItem ของคลาส
DataClient บางครั้งจะแสดงผลออบเจ็กต์ Task<ResultType> ทันทีที่สร้างออบเจ็กต์ Task ระบบจะจัดคิวการดำเนินการในเบื้องหลัง
หากคุณไม่ดำเนินการใดๆ เพิ่มเติมหลังจากนี้ การดำเนินการจะเสร็จสมบูรณ์โดยไม่มีการแจ้งเตือน
อย่างไรก็ตาม โดยปกติแล้วคุณมักต้องการทำบางอย่างกับผลลัพธ์หลังจากที่การดำเนินการเสร็จสมบูรณ์ ดังนั้นออบเจ็กต์ Task จึงช่วยให้คุณรอสถานะผลลัพธ์ได้ ไม่ว่าจะเป็นแบบอะซิงโครนัสหรือซิงโครนัส
การเรียกแบบอะซิงโครนัส
หากโค้ดทำงานในเทรด UI หลัก อย่าทำการเรียกที่บล็อกไปยัง
Data Layer API และใช้โครูทีนเพื่อเรียก putDataItem
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() { }
ดูความเป็นไปได้อื่นๆ ได้ที่ Task API ซึ่งรวมถึงการเชื่อมโยงการดำเนินการ ของงานต่างๆ
การโทรแบบซิงโครนัส
หากโค้ดทำงานในเทรดแฮนเดิลแยกต่างหากในบริการเบื้องหลัง
เช่น ใน WearableListenerService ให้ใช้ runBlocking เพื่อทำการเรียกที่บล็อกไปยัง putDataItem
หมายเหตุ: อย่าเรียกใช้ฟังก์ชันนี้ในขณะที่อยู่ในเทรดหลัก
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 } }
รอรับเหตุการณ์ชั้นข้อมูล
เนื่องจากชั้นข้อมูลจะซิงค์และส่งข้อมูลในอุปกรณ์แบบพกพาและอุปกรณ์ที่สวมใส่ได้ คุณจึงมักจะต้องรอฟังเหตุการณ์สำคัญ เช่น การสร้างรายการข้อมูลและการรับข้อความ
หากต้องการรอรับเหตุการณ์ชั้นข้อมูล คุณมี 2 ตัวเลือก ดังนี้
- สร้างบริการที่ขยาย
WearableListenerService - สร้างกิจกรรมหรือคลาสที่ใช้
DataClient.OnDataChangedListenerอินเทอร์เฟซ
ทั้ง 2 ตัวเลือกนี้จะลบล้างวิธีการเรียกกลับของเหตุการณ์ข้อมูลสําหรับ เหตุการณ์ที่คุณสนใจจัดการ
หมายเหตุ: โปรดพิจารณาการใช้งานแบตเตอรี่ของแอปเมื่อเลือกการติดตั้งใช้งาน Listener
WearableListenerService จะลงทะเบียนในไฟล์ Manifest ของแอป
และสามารถเปิดแอปได้หากยังไม่ได้เรียกใช้ หากคุณต้องการฟังเหตุการณ์เฉพาะเมื่อแอปทำงานอยู่แล้ว ซึ่งมักเป็นกรณีของแอปพลิเคชันแบบอินเทอร์แอกทีฟ ให้ไม่ต้องใช้ WearableListenerService แต่ให้ลงทะเบียน Listener ที่ใช้งานจริงแทน เช่น ใช้วิธี addListener ของคลาส
DataClient ซึ่งจะช่วยลดภาระงานในระบบและลดการใช้แบตเตอรี่ได้
ใช้ WearableListenerService
โดยปกติแล้ว คุณจะสร้างอินสแตนซ์ของ WearableListenerService ในทั้งแอปที่ใช้กับอุปกรณ์สวมใส่และแอปที่ใช้กับอุปกรณ์ถือ อย่างไรก็ตาม หากไม่สนใจเหตุการณ์ข้อมูลในแอปใดแอปหนึ่ง คุณก็ไม่จำเป็นต้องติดตั้งใช้งานบริการในแอปนั้น
เช่น คุณอาจมีแอปแบบถือที่ตั้งค่าและรับออบเจ็กต์รายการข้อมูล และแอปบนอุปกรณ์ที่สวมใส่ได้ซึ่งรอรับการอัปเดตเหล่านี้เพื่ออัปเดต UI แอปบนอุปกรณ์สวมใส่ จะไม่เคยอัปเดตรายการข้อมูลใดๆ ดังนั้นแอปบนอุปกรณ์ถือจึงไม่ฟัง เหตุการณ์ข้อมูลใดๆ จากแอปบนอุปกรณ์สวมใส่
เหตุการณ์บางอย่างที่คุณสามารถฟังได้โดยใช้ WearableListenerService มีดังนี้
onDataChanged(): เมื่อใดก็ตามที่มีการสร้าง ลบ หรือ เปลี่ยนแปลงออบเจ็กต์รายการข้อมูล ระบบจะทริกเกอร์การเรียกกลับนี้ในโหนดที่เชื่อมต่อทั้งหมดonMessageReceived(): ข้อความที่ส่งจากโหนดจะทริกเกอร์ การเรียกกลับนี้ในโหนดเป้าหมายonCapabilityChanged(): เมื่อความสามารถที่อินสแตนซ์ของแอปโฆษณาพร้อมใช้งานในเครือข่าย เหตุการณ์ดังกล่าวจะทริกเกอร์การเรียกกลับนี้ หากต้องการค้นหาโหนดที่อยู่ใกล้เคียง คุณสามารถค้นหาเมธอดisNearby()ของโหนดที่ระบุไว้ในการเรียกกลับ
นอกจากนี้ คุณยังฟังเหตุการณ์จาก ChannelClient.ChannelCallback ได้ด้วย เช่น onChannelOpened()
เหตุการณ์ก่อนหน้าทั้งหมดจะดำเนินการในเธรดเบื้องหลัง ไม่ใช่ในเธรดหลัก
หากต้องการสร้าง WearableListenerService ให้ทำตามขั้นตอนต่อไปนี้
- สร้างคลาสที่ขยาย
WearableListenerService - ฟังเหตุการณ์ที่คุณสนใจ เช่น
onDataChanged() - ประกาศตัวกรอง Intent ในไฟล์ Manifest ของ Android เพื่อแจ้งให้ระบบทราบเกี่ยวกับ
WearableListenerServiceการประกาศนี้ช่วยให้ระบบเชื่อมโยงบริการของคุณได้ตามต้องการ
ตัวอย่างต่อไปนี้แสดงวิธีใช้ WearableListenerService
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 ) } } }
ส่วนต่อไปนี้จะอธิบายวิธีใช้ตัวกรอง Intent กับ Listener นี้
ใช้ตัวกรองกับ WearableListenerService
ตัวกรอง Intent สำหรับWearableListenerService ตัวอย่างที่แสดงในส่วนก่อนหน้า
อาจมีลักษณะดังนี้
<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 ตัวกรองการดำเนินการจะบอกระบบว่าแอปของคุณสนใจเหตุการณ์ใน Data
Layer
ในตัวอย่างนี้ นาฬิกาจะรอรับ/start-activityรายการข้อมูล และโทรศัพท์จะรอรับข้อความ /data-item-received (DATA_ITEM_RECEIVED_PATH) ตอบกลับ
ระบบจะใช้กฎการจับคู่ตัวกรอง Android มาตรฐาน คุณระบุบริการหลายรายการ
ต่อไฟล์ Manifest, ตัวกรอง Intent หลายรายการต่อบริการ, การดำเนินการหลายรายการต่อตัวกรอง
และกลุ่มข้อมูลหลายรายการต่อตัวกรองได้ ตัวกรองสามารถจับคู่กับโฮสต์ไวลด์การ์ดหรือโฮสต์ที่เฉพาะเจาะจง หากต้องการจับคู่ในโฮสต์ไวลด์การ์ด ให้ใช้ host="*" หากต้องการจับคู่ในโฮสต์ที่เฉพาะเจาะจง ให้ระบุ host=<node_id>
นอกจากนี้ คุณยังจับคู่เส้นทางที่ตรงกันทุกประการหรือค่าต่อท้ายของเส้นทางได้ด้วย โดยคุณต้องระบุ สัญลักษณ์แทนหรือโฮสต์ที่เฉพาะเจาะจง มิฉะนั้น ระบบจะไม่สนใจเส้นทางที่คุณระบุ
ดูข้อมูลเพิ่มเติมเกี่ยวกับประเภทตัวกรองที่ Wear OS รองรับได้ที่เอกสารอ้างอิง API
สำหรับ WearableListenerService
ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวกรองข้อมูลและกฎการจับคู่ได้ในเอกสารอ้างอิง API
สำหรับองค์ประกอบ Manifest ของ <data>
เมื่อจับคู่ตัวกรอง Intent โปรดคำนึงถึงกฎสำคัญ 2 ข้อต่อไปนี้
- หากไม่ได้ระบุสคีมาสำหรับตัวกรอง Intent ระบบจะเพิกเฉยต่อแอตทริบิวต์ URI อื่นๆ ทั้งหมด
- หากไม่ได้ระบุโฮสต์สำหรับตัวกรอง ระบบจะไม่สนใจแอตทริบิวต์เส้นทางทั้งหมด
ใช้ผู้ฟังสด
หากแอปสนใจเฉพาะเหตุการณ์ชั้นข้อมูลเมื่อผู้ใช้โต้ตอบกับแอป คุณอาจไม่จำเป็นต้องมีบริการที่ทำงานเป็นเวลานานเพื่อจัดการการเปลี่ยนแปลงข้อมูลทุกครั้ง ใน กรณีดังกล่าว คุณสามารถฟังเหตุการณ์ในกิจกรรมได้
หากต้องการแนะนำแนวทางที่สะอาดและปลอดภัยยิ่งขึ้น ให้ใช้ Lifecycle Observer การใช้ Lifecycle Observer จะช่วยย้ายตรรกะการลงทะเบียนออกจาก onResume() ของ Activity ไปยังคลาสที่แยกต่างหากและนำกลับมาใช้ใหม่ได้ ซึ่งจะใช้ DefaultLifecycleObserver
แนวทางนี้จะช่วยให้กิจกรรมของคุณมีประสิทธิภาพและป้องกันข้อบกพร่องที่พบบ่อย เช่น การลืม ยกเลิกการลงทะเบียน Listener
1. สร้าง Listener ที่รับรู้ถึงวงจรขององค์ประกอบ
คลาสนี้จะรวม DataClient.OnDataChangedListener และจัดการการสมัครใช้บริการของตัวเองโดยอัตโนมัติ
ตามวงจรของกิจกรรม
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. การใช้งานในกิจกรรมของคุณ
ตอนนี้กิจกรรมของคุณไม่จำเป็นต้องลบล้าง onResume() หรือ
onPause() สำหรับ Wear API คุณเพิ่มผู้สังเกตการณ์ได้ครั้งเดียวใน onCreate()
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 ... } }
ทำไมพรอมต์นี้จึงดีขึ้น
- กิจกรรม Cleaner: คุณนำโค้ดสำเร็จรูปออกจากเมธอดวงจรของกิจกรรม
- ความปลอดภัย:
DefaultLifecycleObserverช่วยยืนยันว่าระบบได้นำ Listener ออกแล้ว แม้ว่า Activity จะถูกทำลายโดยไม่คาดคิด ซึ่งจะช่วยป้องกันไม่ให้เกิดการรั่วไหลของหน่วยความจำ - การนำกลับมาใช้ใหม่: คุณสามารถเสียบ
WearDataLayerObserverนี้เข้ากับ Activity หรือ Fragment ใดก็ได้โดยไม่ต้องเขียนตรรกะการลงทะเบียนใหม่ - การแยกส่วน: แยกตรรกะของเวลาที่ต้องฟังออกจากตรรกะของ สิ่งที่ต้องทำกับข้อมูล
ใช้ตัวกรองกับผู้ฟังแบบเรียลไทม์
ดังที่ได้กล่าวไว้ก่อนหน้านี้ คุณสามารถระบุตัวกรอง Intent สำหรับออบเจ็กต์ WearableListenerServiceที่อิงตามไฟล์ Manifest ได้เช่นเดียวกับที่ใช้ตัวกรอง Intent เมื่อลงทะเบียน Listener แบบสดผ่าน Wearable API กฎเดียวกันนี้
มีผลกับทั้งผู้ฟังที่ใช้ API และผู้ฟังที่ใช้ไฟล์ Manifest
รูปแบบที่ใช้กันทั่วไปคือการลงทะเบียน Listener ด้วยเส้นทางหรือคำนำหน้าเส้นทางที่เฉพาะเจาะจง
โดยใช้ LifecycleObserver การใช้เครื่องมือฟังในลักษณะนี้จะช่วยให้แอปรับเหตุการณ์ได้อย่างเลือกสรรมากขึ้น ซึ่งจะช่วยปรับปรุงการออกแบบและ
ประสิทธิภาพ