เมื่อเรียกใช้ 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 } }
ฟังเหตุการณ์ Data Layer
เนื่องจาก Data Layer จะซิงค์และส่งข้อมูลระหว่างอุปกรณ์แบบพกพาและอุปกรณ์สวมใส่ คุณจึงมักจะต้องฟังเหตุการณ์สำคัญๆ เช่น การสร้างรายการข้อมูลและการรับข้อความ
หากต้องการฟังเหตุการณ์ Data Layer คุณมี 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 ข้อต่อไปนี้
- หากไม่ได้ระบุ Scheme สำหรับตัวกรอง Intent ระบบจะละเว้นแอตทริบิวต์ URI อื่นๆ ทั้งหมด
- หากไม่ได้ระบุโฮสต์สำหรับตัวกรอง ระบบจะละเว้นแอตทริบิวต์เส้นทางทั้งหมด
ใช้ Listener แบบสด
หากแอปของคุณสนใจเฉพาะเหตุการณ์ Data Layer เมื่อผู้ใช้โต้ตอบกับแอป ก็อาจไม่จำเป็นต้องมีบริการที่ทำงานเป็นเวลานานเพื่อจัดการการเปลี่ยนแปลงข้อมูลทุกครั้ง ในกรณีดังกล่าว คุณสามารถฟังเหตุการณ์ในกิจกรรมได้
หากต้องการใช้วิธีที่สะอาดและปลอดภัยยิ่งขึ้น ให้ใช้ตัวสังเกตวงจรการทำงาน การใช้ตัวสังเกตวงจรการทำงาน
จะช่วยให้คุณย้ายตรรกะการลงทะเบียนออกจาก
LifecycleResumeEventของกิจกรรมไปยังคลาสที่แยกต่างหากและนำกลับมาใช้ใหม่ได้ ซึ่ง
จะใช้ 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. การใช้งานในกิจกรรม
ตอนนี้กิจกรรมของคุณไม่จำเป็นต้องใช้ LifecycleResumeEvent หรือ
onPause สำหรับ Wear API คุณลงทะเบียนตัวสังเกต 1 ครั้งใน LaunchedEvent (หรือ 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 ... } }
เหตุผลที่วิธีนี้ดีกว่า
- กิจกรรมที่สะอาดขึ้น: คุณนำโค้ดที่ต้องเขียนซ้ำๆ ออกจากเมธอดวงจรกิจกรรม
- ความปลอดภัย:
DefaultLifecycleObserverช่วยยืนยันว่าได้นำ Listener ออกแล้ว แม้ว่ากิจกรรมจะถูกทำลายโดยไม่คาดคิด ซึ่งจะช่วยป้องกันการรั่วไหลของหน่วยความจำ - การนำกลับมาใช้ใหม่ได้: คุณสามารถเสียบ
WearDataLayerObserverนี้ลงในกิจกรรมหรือ Composable ใดก็ได้โดยไม่ต้องเขียนตรรกะการลงทะเบียนใหม่ - การแยกส่วน: ตรรกะสำหรับเวลาที่จะฟังจะแยกออกจากตรรกะของสิ่งที่ต้องทำกับข้อมูล
ใช้ตัวกรองกับ Listener แบบสด
ดังที่กล่าวไว้ก่อนหน้านี้ คุณสามารถระบุตัวกรอง Intent สำหรับ
ออบเจ็กต์ WearableListenerService ที่อิงตามไฟล์ Manifest ได้ เช่นเดียวกับที่คุณใช้ตัวกรอง Intent
เมื่อลงทะเบียน Listener แบบสดผ่าน Wearable API กฎเดียวกันนี้จะมีผลกับทั้ง Listener แบบสดที่อิงตาม API และ Listener ที่อิงตามไฟล์ Manifest
รูปแบบทั่วไปคือการลงทะเบียน Listener ที่มีเส้นทางหรือคำนำหน้าเส้นทางที่เฉพาะเจาะจง
โดยใช้ collectAsStateWithLifecycle() การติดตั้งใช้งาน Listener ในลักษณะนี้จะช่วยให้แอปของคุณรับเหตุการณ์ได้อย่างเลือกสรรมากขึ้น ซึ่งจะช่วยปรับปรุงการออกแบบและประสิทธิภาพของแอป