ส่วนต่อไปนี้อธิบายวิธีอัปเดต GlanceAppWidget และจัดการสถานะ
จัดการสถานะ GlanceAppWidget
ระบบจะสร้างอินสแตนซ์ของคลาส GlanceAppWidget ที่ให้ไว้ทุกครั้งที่สร้างวิดเจ็ตหรือต้องมีการอัปเดต ดังนั้นคลาสนี้จึงควรเป็น stateless และ passive
แนวคิดเรื่องสถานะสามารถแบ่งออกได้ดังนี้
- สถานะของแอปพลิเคชัน: สถานะหรือเนื้อหาของแอปที่วิดเจ็ตต้องใช้ เช่น รายการปลายทางที่เก็บไว้ (เช่น ฐานข้อมูล) ซึ่งผู้ใช้กำหนดไว้
- สถานะ Glance: สถานะเฉพาะที่เกี่ยวข้องกับวิดเจ็ตแอปเท่านั้น และไม่จำเป็นต้องแก้ไขหรือส่งผลต่อสถานะของแอป เช่น มีการเลือกช่องทำเครื่องหมายในวิดเจ็ตหรือมีการเพิ่มตัวนับ
ใช้สถานะของแอปพลิเคชัน
วิดเจ็ตแอปควรเป็นแบบ passive แต่ละแอปพลิเคชันมีหน้าที่รับผิดชอบในการจัดการเลเยอร์ข้อมูลและการจัดการสถานะต่างๆ เช่น ไม่ได้ใช้งาน กำลังโหลด และข้อผิดพลาดที่แสดงใน UI ของวิดเจ็ต
ตัวอย่างเช่น โค้ดต่อไปนี้จะดึงข้อมูลปลายทางจากแคชในหน่วยความจำจากเลเยอร์ที่เก็บข้อมูล แสดงรายการปลายทางที่เก็บไว้ และแสดง UI ที่แตกต่างกันไปตามสถานะ
class DestinationAppWidget : GlanceAppWidget() { // ... @Composable fun MyContent() { val repository = remember { DestinationsRepository.getInstance() } // Retrieve the cache data everytime the content is refreshed val destinations by repository.destinations.collectAsState(State.Loading) when (destinations) { is State.Loading -> { // show loading content } is State.Error -> { // show widget error content } is State.Completed -> { // show the list of destinations } } } }
แอปมีหน้าที่รับผิดชอบในการแจ้งและอัปเดตวิดเจ็ตทุกครั้งที่สถานะหรือข้อมูลมีการเปลี่ยนแปลง ดูข้อมูลเพิ่มเติมได้ที่ อัปเดต GlanceAppWidget
อัปเดต GlanceAppWidget
คุณสามารถขออัปเดตเนื้อหาวิดเจ็ตโดยใช้ GlanceAppWidget ตามที่
อธิบายไว้ในส่วนGlanceAppWidgetจัดการสถานะวิดเจ็ตแอป
จะโฮสต์อยู่ในกระบวนการที่แตกต่างกัน Glance จะแปลเนื้อหาเป็น RemoteViews จริงและส่งไปยังโฮสต์ หากต้องการอัปเดตเนื้อหา Glance ต้องสร้าง RemoteViews ขึ้นมาใหม่และส่งอีกครั้ง
หากต้องการส่งการอัปเดต ให้เรียกใช้เมธอด update ของอินสแตนซ์ GlanceAppWidget โดยระบุ context และ glanceId
MyAppWidget().update(context, glanceId)
หากต้องการรับ glanceId ให้ค้นหา GlanceAppWidgetManager
val manager = GlanceAppWidgetManager(context) val widget = GlanceSizeModeWidget() val glanceIds = manager.getGlanceIds(widget.javaClass) glanceIds.forEach { glanceId -> widget.update(context, glanceId) }
หรือใช้ส่วนขยาย GlanceAppWidget update อย่างใดอย่างหนึ่ง
// Updates all placed instances of MyAppWidget MyAppWidget().updateAll(context) // Iterate over all placed instances of MyAppWidget and update if the state of // the instance matches the given predicate MyAppWidget().updateIf<State>(context) { state -> state == State.Completed }
คุณสามารถเรียกใช้เมธอดเหล่านี้จากส่วนใดก็ได้ของแอปพลิเคชัน เนื่องจากเป็นฟังก์ชัน suspend เราจึงแนะนำให้เรียกใช้ฟังก์ชันเหล่านี้ภายนอกขอบเขตของเทรดหลัก ในตัวอย่างต่อไปนี้ ฟังก์ชันเหล่านี้จะเรียกใช้ใน CoroutineWorker
class DataSyncWorker( val context: Context, val params: WorkerParameters, ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { // Fetch data or do some work and then update all instance of your widget MyAppWidget().updateAll(context) return Result.success() } }
ดูรายละเอียดเพิ่มเติมเกี่ยวกับ Coroutine ได้ที่ Kotlin Coroutines บน Android
เวลาที่ควรทำการอัปเดตวิดเจ็ต
อัปเดตวิดเจ็ตทันทีหรือเป็นระยะ
วิดเจ็ตสามารถอัปเดตได้ทันทีเมื่อแอปทำงานอยู่ เช่น
- เมื่อผู้ใช้โต้ตอบกับวิดเจ็ต ซึ่งจะทริกเกอร์การดำเนินการ การเรียกใช้ Lambda หรือ Intent เพื่อเปิดใช้กิจกรรม
- เมื่อผู้ใช้โต้ตอบกับแอปในเบื้องหน้า หรือในขณะที่แอปกำลังอัปเดตเพื่อตอบสนองต่อข้อความ Firebase Cloud Messaging (FCM) หรือการออกอากาศ
ในกรณีเหล่านี้ ให้เรียกใช้เมธอด update ตามที่อธิบายไว้ในคู่มือนี้
วิดเจ็ตสามารถอัปเดตเป็นระยะเมื่อแอปไม่ได้ทำงานอยู่ เช่น
- ใช้
updatePeriodMillisเพื่ออัปเดตวิดเจ็ตได้สูงสุด 1 ครั้งทุกๆ 30 นาที - ใช้
WorkManagerเพื่อกำหนดเวลาการอัปเดตที่บ่อยขึ้น เช่น ทุกๆ 15 นาที - อัปเดตวิดเจ็ตเพื่อตอบสนองต่อการออกอากาศ
แหล่งข้อมูล
- สร้างวิดเจ็ตด้วย Glance (Codelab)
- การสร้างเพื่ออนาคตของ Android: บทที่เกี่ยวกับวิดเจ็ต (วิดีโอ)