เมื่อเรียกใช้ Data Layer API คุณจะได้รับฟังก์ชัน สถานะของการโทรเมื่อเสร็จสมบูรณ์ นอกจากนี้ คุณยังฟังเหตุการณ์ข้อมูลได้ด้วย ซึ่งเป็นผลจากการเปลี่ยนแปลงข้อมูล ที่แอปของคุณทำขึ้นบน เครือข่าย Wear OS by Google
ดูตัวอย่างของการทำงานกับ Data Layer API ได้อย่างมีประสิทธิภาพได้ที่ แอปตัวอย่างชั้นข้อมูลบน Android
รอสถานะการเรียกใช้ชั้นข้อมูล
การเรียก Data Layer API เช่น การเรียกโดยใช้ putDataItem
ของวิธีการ
DataClient
คลาส บางครั้งก็แสดงผล
ออบเจ็กต์
Task<ResultType>
รายการ ทันทีที่ออบเจ็กต์ Task
จะสร้างการดำเนินการ
อยู่ในคิวเบื้องหลัง หากคุณไม่ดำเนินการใดๆ หลังจากนี้
ในที่สุดก็เสร็จสมบูรณ์แบบเงียบ
แต่อย่างไรก็ตาม โดยทั่วไปคุณต้องการดำเนินการบางอย่างกับ
ผลลัพธ์หลังการดำเนินการเสร็จสิ้น ดังนั้นออบเจ็กต์ Task
จะให้
คุณต้องรอสถานะของผลลัพธ์ ไม่ว่าจะเป็นแบบไม่พร้อมกันหรือแบบซิงโครนัส
การโทรไม่พร้อมกัน
หากโค้ดของคุณกำลังทำงานในเธรด UI หลัก อย่าบล็อกการเรียกไปยัง
API ชั้นข้อมูล เรียกใช้การเรียกแบบไม่พร้อมกันโดยเพิ่มเมธอด Callback
ไปยังออบเจ็กต์ Task
ซึ่งจะเริ่มทำงานเมื่อการดำเนินการเสร็จสมบูรณ์:
Kotlin
// Using Kotlin function references task.addOnSuccessListener(::handleDataItem) task.addOnFailureListener(::handleDataItemError) task.addOnCompleteListener(::handleTaskComplete) ... fun handleDataItem(dataItem: DataItem) { ... } fun handleDataItemError(exception: Exception) { ... } fun handleTaskComplete(task: Task<DataItem>) { ... }
Java
// Using Java 8 Lambdas. task.addOnSuccessListener(dataItem -> handleDataItem(dataItem)); task.addOnFailureListener(exception -> handleDataItemError(exception)); task.addOnCompleteListener(task -> handleTaskComplete(task));
โปรดดู Task API เพื่อความเป็นไปได้อื่นๆ รวมถึงการเชื่อมโยงการดำเนินการของ งานต่างๆ ได้
การโทรพร้อมกัน
หากโค้ดของคุณทำงานอยู่ในเทรดของตัวแฮนเดิลแยกต่างหากในบริการในเบื้องหลัง
เช่น ใน
WearableListenerService
การบล็อกก็สามารถทำได้ ในกรณีนี้ คุณสามารถโทรหา Tasks.await()
ผ่าน Task
ซึ่งจะบล็อกจนกว่าคำขอจะเสร็จสมบูรณ์และส่งกลับ
ออบเจ็กต์ Result
รายการ ตัวอย่างนี้จะแสดงในตัวอย่างต่อไปนี้
หมายเหตุ: โปรดอย่าเรียกใช้ส่วนนี้ขณะอยู่ในเทรดหลัก
Kotlin
try { Tasks.await(dataItemTask).apply { Log.d(TAG, "Data item set: $uri") } } catch (e: ExecutionException) { ... } catch (e: InterruptedException) { ... }
Java
try { DataItem item = Tasks.await(dataItemTask); Log.d(TAG, "Data item set: " + item.getUri()); } catch (ExecutionException | InterruptedException e) { ... }
ฟังเหตุการณ์ชั้นข้อมูล
เนื่องจากชั้นข้อมูลจะซิงค์ข้อมูลและส่งข้อมูลระหว่างอุปกรณ์พกพาและ อุปกรณ์ที่สวมใส่ได้ คุณมักจะต้องคอยฟังเหตุการณ์สำคัญๆ เช่น รายการข้อมูลที่กำลังสร้างและข้อความที่ได้รับ
คุณมี 2 ตัวเลือกในการวิเคราะห์เหตุการณ์ชั้นข้อมูล
- สร้างบริการที่ขยาย
WearableListenerService
- สร้างกิจกรรมหรือชั้นเรียนที่ใช้อินเทอร์เฟซ
DataClient.OnDataChangedListener
เมื่อใช้ทั้ง 2 ตัวเลือกนี้ คุณจะลบล้างเมธอด Callback ของเหตุการณ์ข้อมูลสำหรับพร็อพเพอร์ตี้ เหตุการณ์ที่คุณสนใจจัดการ
หมายเหตุ: ควรพิจารณาการใช้งานแบตเตอรี่ของแอปเมื่อเลือก
การติดตั้ง Listener ด้วย WearableListenerService
มีการลงทะเบียนในไฟล์ Manifest ของแอปและเปิดแอปได้หากยังไม่ได้ดำเนินการ
วิ่งอยู่ หากคุณต้องการฟังเฉพาะเหตุการณ์เมื่อแอปทำงานอยู่แล้ว
ซึ่งมักจะเป็นแอปพลิเคชันแบบอินเทอร์แอกทีฟ ดังนั้นอย่าใช้งาน
WearableListenerService
โปรดลงทะเบียนผู้ฟังแบบเรียลไทม์แทน
เช่น ใช้เมธอด addListener
ของ DataClient
ซึ่งจะช่วยลดภาระของระบบและลดการใช้งานแบตเตอรี่ได้
ใช้ WearableListenerService
โดยทั่วไปคุณจะสร้างอินสแตนซ์ของ
WearableListenerService
ทั้งในอุปกรณ์ที่สวมใส่ได้และ
แอปมือถือ แต่ถ้าคุณไม่สนใจเหตุการณ์ของข้อมูลในคอลัมน์
คุณไม่จำเป็นต้องใช้บริการดังกล่าวในแอปนั้น
เช่น คุณอาจมีแอปแบบพกพาที่ตั้งค่าและรับออบเจ็กต์รายการข้อมูล และแอปสำหรับอุปกรณ์ที่สวมใส่ได้ซึ่งคอยฟังการอัปเดตเหล่านี้เพื่ออัปเดต UI แอปสำหรับอุปกรณ์ที่สวมใส่ได้จะไม่อัปเดตรายการข้อมูลใดๆ ดังนั้นแอปแบบพกพาจึงไม่ ฟังเหตุการณ์ข้อมูลต่างๆ จากแอปที่สวมใส่ได้
เหตุการณ์บางอย่างที่คุณใช้ฟังได้
WearableListenerService
คือรายการต่อไปนี้
-
onDataChanged()
เมื่อมีการสร้าง ลบ หรือเปลี่ยนแปลงออบเจ็กต์รายการ ระบบจะทริกเกอร์ Callback นี้บนโหนดที่เชื่อมต่อทั้งหมด -
onMessageReceived()
: ข้อความที่ส่งจากทริกเกอร์โหนด Callback นี้ในโหนดเป้าหมาย -
onCapabilityChanged()
เมื่อมีความสามารถในการโฆษณาอินสแตนซ์ของแอป ในเครือข่าย เหตุการณ์ดังกล่าวจะทริกเกอร์ Callback นี้ หากคุณกำลังมองหา โหนดใกล้เคียง คุณสามารถค้นหา เมธอดisNearby()
ของโหนดที่ให้ไว้ใน Callback
นอกจากนี้ คุณยังฟังเหตุการณ์จาก
ChannelClient.ChannelCallback
เช่น onChannelOpened()
เหตุการณ์ก่อนหน้าทั้งหมดจะดำเนินการในเทรดในเบื้องหลัง ไม่ได้อยู่ในชุดข้อความหลัก
หากต้องการสร้าง WearableListenerService
ให้ทำตามขั้นตอนต่อไปนี้
- สร้างชั้นเรียนที่ขยายระยะเวลา
WearableListenerService
- ฟังกิจกรรมที่คุณสนใจ เช่น
onDataChanged()
- ประกาศตัวกรอง Intent ในไฟล์ Manifest ของ Android เพื่อแจ้งระบบเกี่ยวกับ
WearableListenerService
การประกาศนี้จะทำให้ระบบเชื่อมโยง บริการได้ตามต้องการ
ตัวอย่างต่อไปนี้แสดงวิธีใช้งาน WearableListenerService
แบบง่าย
Kotlin
private const val TAG = "DataLayerSample" private const val START_ACTIVITY_PATH = "/start-activity" private const val DATA_ITEM_RECEIVED_PATH = "/data-item-received" 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) } } }
Java
public class DataLayerListenerService extends WearableListenerService { private static final String TAG = "DataLayerSample"; private static final String START_ACTIVITY_PATH = "/start-activity"; private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received"; @Override public void onDataChanged(DataEventBuffer dataEvents) { 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. for (DataEvent event : dataEvents) { Uri uri = event.getDataItem().getUri(); // Get the node ID from the host value of the URI. String nodeId = uri.getHost(); // Set the data of the message to be the bytes of the URI. byte[] payload = uri.toString().getBytes(); // Send the RPC. Wearable.getMessageClient(this).sendMessage( nodeId, DATA_ITEM_RECEIVED_PATH, payload); } } }
ส่วนต่อไปนี้จะอธิบายวิธีใช้ตัวกรอง Intent กับ Listener นี้
ใช้ตัวกรองกับ WearableListenerService
ตัวกรอง Intent สำหรับตัวอย่าง WearableListenerService
ที่แสดงในส่วนก่อนหน้า
อาจมีลักษณะเช่นนี้
<service android:name=".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
จะแทนที่
ก่อนหน้านี้ได้แนะนำการดำเนินการ BIND_LISTENER
เพื่อให้มีเฉพาะ
เหตุการณ์ต่างๆ ปลุกหรือเปิดแอปของคุณ การเปลี่ยนแปลงนี้จะช่วยปรับปรุงประสิทธิภาพของระบบ
และลดการใช้แบตเตอรี่และค่าใช้จ่ายอื่นๆ ที่เกี่ยวข้องกับ
แอป ในตัวอย่างนี้ นาฬิกาจะคอยตรวจจับ
รายการข้อมูล /start-activity
และ
โทรศัพท์จะคอยฟังการตอบกลับข้อความ /data-item-received
ระบบจะใช้กฎการจับคู่ตัวกรอง Android มาตรฐาน คุณสามารถระบุหลายบริการได้
ต่อไฟล์ Manifest, ตัวกรอง Intent หลายรายการต่อบริการ, การดำเนินการหลายรายการต่อตัวกรอง
และข้อมูลหลายรายการต่อ 1 ตัวกรอง ตัวกรองสามารถจับคู่กับโฮสต์ไวลด์การ์ดหรือ
เรื่องใดเรื่องหนึ่งโดยเฉพาะ หากต้องการจับคู่กับโฮสต์ไวลด์การ์ด ให้ใช้ host="*"
เพื่อให้ตรงกัน
ในโฮสต์ที่ระบุ ให้ระบุ host=<node_id>
นอกจากนี้คุณยังจับคู่เส้นทางแบบลิเทอรัลหรือคำนำหน้าเส้นทางได้ด้วย วิธีการคือ คุณต้องระบุไวลด์การ์ดหรือโฮสต์เฉพาะ มิฉะนั้นระบบจะไม่สนใจเส้นทางที่คุณระบุ
ดูข้อมูลเพิ่มเติมเกี่ยวกับประเภทตัวกรองที่ Wear OS รองรับได้ที่
เอกสารอ้างอิง API สำหรับ
WearableListenerService
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวกรองข้อมูลและกฎการจับคู่ โปรดดูข้อมูลอ้างอิง API
เอกสารประกอบสำหรับ <data>
ของไฟล์ Manifest
เมื่อจับคู่ตัวกรอง Intent โปรดจดจำกฎที่สำคัญ 2 ข้อต่อไปนี้
- หากไม่ได้ระบุสกีมสำหรับตัวกรอง Intent ระบบจะไม่สนใจ แอตทริบิวต์ URI อื่นๆ ทั้งหมด
- หากไม่ได้ระบุโฮสต์สำหรับตัวกรอง ระบบจะไม่สนใจ แอตทริบิวต์เส้นทางทั้งหมด
ใช้การฟังแบบสด
หากแอปสนใจเฉพาะเหตุการณ์ชั้นข้อมูลเมื่อผู้ใช้โต้ตอบด้วย แอปนั้นอาจไม่ต้องใช้บริการที่ทำงานมานานเพื่อจัดการกับการเปลี่ยนแปลงข้อมูลทั้งหมด ใน ในกรณีเช่นนี้ คุณก็สามารถจับตาดูเหตุการณ์ในกิจกรรมได้โดยการนำเหตุการณ์ อินเทอร์เฟซต่อไปนี้เพิ่มเติม:
DataClient.OnDataChangedListener
MessageClient.OnMessageReceivedListener
CapabilityClient.OnCapabilityChangedListener
ChannelClient.ChannelCallback
หากต้องการสร้างกิจกรรมที่รอรับเหตุการณ์ข้อมูล ให้ทำตามขั้นตอนต่อไปนี้
- ใช้อินเทอร์เฟซที่ต้องการ
- ในเมธอด
onCreate()
หรือonResume()
ให้เรียกใช้Wearable.getDataClient(this).addListener()
,MessageClient.addListener()
,CapabilityClient.addListener()
หรือChannelClient.registerChannelCallback()
เพื่อแจ้ง Google Play บริการที่กิจกรรมของคุณสนใจที่จะฟังเหตุการณ์ชั้นข้อมูล - ใน
onStop()
หรือonPause()
ยกเลิกการลงทะเบียน Listener ทั้งหมดด้วยDataClient.removeListener()
,MessageClient.removeListener()
,CapabilityClient.removeListener()
หรือChannelClient.unregisterChannelCallback()
- หากกิจกรรมสนใจเฉพาะเหตุการณ์ที่มีคำนำหน้าเส้นทางที่เจาะจง คุณจะเห็น สามารถเพิ่ม Listener ที่มีตัวกรองคำนำหน้าที่เหมาะสม เพื่อรับเฉพาะข้อมูลที่ ที่เกี่ยวข้องกับสถานะปัจจุบันของแอปพลิเคชัน
- ติดตั้งใช้งาน
onDataChanged()
,onMessageReceived()
onCapabilityChanged()
หรือเมธอดจากChannelClient.ChannelCallback
ขึ้นอยู่กับอินเทอร์เฟซที่คุณใช้ เราจะเรียกวิธีการเหล่านี้ใน เทรดหลัก หรือคุณจะระบุLooper
ที่กำหนดเองโดยใช้WearableOptions
ก็ได้
นี่คือตัวอย่างที่นำ DataClient.OnDataChangedListener
ไปใช้
Kotlin
class MainActivity : Activity(), DataClient.OnDataChangedListener { public override fun onResume() { Wearable.getDataClient(this).addListener(this) } override fun onPause() { Wearable.getDataClient(this).removeListener(this) } override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents.forEach { event -> if (event.type == DataEvent.TYPE_DELETED) { Log.d(TAG, "DataItem deleted: " + event.dataItem.uri) } else if (event.type == DataEvent.TYPE_CHANGED) { Log.d(TAG, "DataItem changed: " + event.dataItem.uri) } } } }
Java
public class MainActivity extends Activity implements DataClient.OnDataChangedListener { @Override public void onResume() { Wearable.getDataClient(this).addListener(this); } @Override protected void onPause() { Wearable.getDataClient(this).removeListener(this); } @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_DELETED) { Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri()); } else if (event.getType() == DataEvent.TYPE_CHANGED) { Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri()); } } } }
ใช้ตัวกรองกับผู้ฟังแบบเรียลไทม์
ดังที่กล่าวมาแล้ว เช่นเดียวกับที่คุณสามารถระบุตัวกรอง Intent สำหรับ
WearableListenerService
ที่อิงตามไฟล์ Manifest
คุณสามารถใช้ตัวกรอง Intent เมื่อลงทะเบียน Listener แบบเรียลไทม์ผ่าน
สวมใส่ได้
API กฎเดียวกันจะใช้กับทั้ง Listener แบบสดที่ใช้ API และ
Listener ที่ใช้ไฟล์ Manifest
รูปแบบที่พบบ่อยคือการลงทะเบียน Listener ด้วยเส้นทางหรือคำนำหน้าเส้นทางที่เฉพาะเจาะจง
ในonResume()
ของกิจกรรม
และนำ Listener ในกิจกรรม
onPause()
วิธี
การใช้ Listener ในรูปแบบนี้ทำให้แอปของคุณมีความเปิดกว้างมากขึ้น
รับกิจกรรม ปรับปรุงการออกแบบและประสิทธิภาพ