หน้านี้อธิบายแนวทางปฏิบัติที่แนะนำในการสร้างวิดเจ็ตขั้นสูงยิ่งขึ้นเพื่อประสบการณ์ของผู้ใช้ที่ดียิ่งขึ้น
การเพิ่มประสิทธิภาพสำหรับการอัปเดตเนื้อหาวิดเจ็ต
การอัปเดตเนื้อหาวิดเจ็ตอาจใช้การคำนวณมาก เพิ่มประสิทธิภาพประเภท ความถี่ และเวลาในการอัปเดตเพื่อประหยัดแบตเตอรี่
ประเภทการอัปเดตวิดเจ็ต
การอัปเดตวิดเจ็ตมี 3 วิธี ได้แก่ การอัปเดตแบบเต็ม การอัปเดตบางส่วน และการรีเฟรชข้อมูล (ในกรณีของวิดเจ็ตคอลเล็กชัน) โดยแต่ละวิธีมี ค่าใช้จ่ายในการคำนวณและผลที่ตามมาแตกต่างกัน
ต่อไปนี้จะอธิบายการอัปเดตแต่ละประเภทและแสดงตัวอย่างโค้ดสำหรับการอัปเดตแต่ละประเภท
- อัปเดตทั้งหมด: โทรหา
AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews)เพื่ออัปเดตวิดเจ็ตทั้งหมด การดำเนินการนี้จะแทนที่RemoteViewsที่ระบุไว้ก่อนหน้านี้ ด้วยRemoteViewsใหม่ การอัปเดตนี้ใช้การคำนวณมากที่สุด
val appWidgetManager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.packageName, R.layout.widgetlayout).apply { setTextViewText(R.id.textview_widget_layout1, "Updated text1") setTextViewText(R.id.textview_widget_layout2, "Updated text2") } appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
- การอัปเดตบางส่วน: เรียกใช้
AppWidgetManager.partiallyUpdateAppWidgetเพื่ออัปเดตบางส่วนของวิดเจ็ต ซึ่งจะรวมRemoteViewsใหม่กับRemoteViewsที่ระบุไว้ก่อนหน้านี้ ระบบจะละเว้นวิธีนี้หากวิดเจ็ต ไม่ได้รับการอัปเดตอย่างน้อย 1 ครั้งผ่านupdateAppWidget(int[], RemoteViews)
val appWidgetManager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.packageName, R.layout.widgetlayout).apply { setTextViewText(R.id.textview_widget_layout, "Updated text") } appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews)
- การรีเฟรชข้อมูลคอลเล็กชัน: เรียกใช้
AppWidgetManager.notifyAppWidgetViewDataChangedเพื่อล้างข้อมูลของมุมมองคอลเล็กชันในวิดเจ็ต ซึ่งจะทริกเกอร์RemoteViewsFactory.onDataSetChangedในระหว่างนี้ ข้อมูลเก่าจะแสดงในวิดเจ็ต คุณสามารถ ทำงานที่ใช้ทรัพยากรมากแบบซิงโครนัสได้อย่างปลอดภัยด้วยวิธีนี้
val appWidgetManager = AppWidgetManager.getInstance(context) appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)
คุณเรียกใช้เมธอดเหล่านี้ได้จากทุกที่ในแอป ตราบใดที่แอปมี UID เดียวกันกับคลาส AppWidgetProvider ที่เกี่ยวข้อง
กำหนดความถี่ในการอัปเดตวิดเจ็ต
วิดเจ็ตจะได้รับการอัปเดตเป็นระยะๆ โดยขึ้นอยู่กับค่าที่ระบุสำหรับแอตทริบิวต์
updatePeriodMillis
วิดเจ็ตสามารถอัปเดตเพื่อตอบสนองต่อการโต้ตอบของผู้ใช้ อัปเดตการออกอากาศ หรือทั้ง 2 อย่าง
อัปเดตเป็นระยะๆ
คุณควบคุมความถี่ของการอัปเดตเป็นระยะได้โดยระบุค่าสำหรับ
AppWidgetProviderInfo.updatePeriodMillis ใน XML ของ appwidget-provider การอัปเดตแต่ละครั้งจะทริกเกอร์เมธอด AppWidgetProvider.onUpdate() ซึ่งเป็นตำแหน่งที่คุณวางโค้ดเพื่ออัปเดตวิดเจ็ตได้ อย่างไรก็ตาม โปรดพิจารณาทางเลือกสำหรับ
การอัปเดต Broadcast Receiver ที่อธิบายไว้ใน
ส่วนถัดไป หากวิดเจ็ตต้องโหลดข้อมูลแบบไม่พร้อมกันหรือใช้เวลาอัปเดตนานกว่า 10 วินาที เนื่องจากหลังจาก 10 วินาที ระบบจะถือว่า BroadcastReceiver ไม่ตอบสนอง
updatePeriodMillis ไม่รองรับค่าที่น้อยกว่า 30 นาที แต่หากต้องการปิดใช้การอัปเดตเป็นระยะ คุณสามารถระบุ 0 ได้
คุณอนุญาตให้ผู้ใช้ปรับความถี่ในการอัปเดตในการกำหนดค่าได้ เช่น อาจต้องการให้แถบเลื่อนหุ้นอัปเดตทุก 15 นาทีหรือวันละ 4 ครั้งเท่านั้น ในกรณีนี้ ให้ตั้งค่า updatePeriodMillis เป็น 0 แล้วใช้
WorkManager แทน
อัปเดตเพื่อตอบสนองต่อการโต้ตอบของผู้ใช้
วิธีที่แนะนำในการอัปเดตวิดเจ็ตตามการโต้ตอบของผู้ใช้มีดังนี้
จากกิจกรรมของแอป: เรียกใช้โดยตรง
AppWidgetManager.updateAppWidgetเพื่อตอบสนองต่อการโต้ตอบของผู้ใช้ เช่น การแตะของผู้ใช้จากการโต้ตอบระยะไกล เช่น การแจ้งเตือนหรือวิดเจ็ตแอป: สร้าง
PendingIntentจากนั้นอัปเดตวิดเจ็ตจากActivity,BroadcastหรือServiceที่เรียกใช้ คุณเลือกกำหนดลำดับความสำคัญเองได้ เช่น หากเลือกBroadcastสำหรับPendingIntentคุณจะเลือกการออกอากาศเบื้องหน้าเพื่อให้BroadcastReceiverมีความสำคัญได้
อัปเดตเพื่อตอบสนองต่อเหตุการณ์ที่ออกอากาศ
ตัวอย่างเหตุการณ์ที่ออกอากาศซึ่งต้องใช้วิดเจ็ตในการอัปเดตคือเมื่อ ผู้ใช้ถ่ายรูป ในกรณีนี้ คุณต้องการอัปเดตวิดเจ็ตเมื่อตรวจพบรูปภาพใหม่
คุณสามารถกำหนดเวลางานด้วย WorkManager และระบุทริกเกอร์ URI เนื้อหาได้โดยใช้เมธอด Constraints.Builder.addContentUriTrigger
คุณยังลงทะเบียน BroadcastReceiver สำหรับการออกอากาศได้ด้วย เช่น
ฟัง ACTION_LOCALE_CHANGED
อย่างไรก็ตาม เนื่องจากฟีเจอร์นี้ใช้ทรัพยากรของอุปกรณ์ จึงควรใช้อย่างระมัดระวังและฟัง
เฉพาะการออกอากาศที่ต้องการ เมื่อมีการเปิดตัวข้อจำกัดในการออกอากาศใน Android 7.0 (ระดับ API 24) และ Android 8.0 (ระดับ API 26) แอปต่างๆ จะลงทะเบียนการออกอากาศโดยนัยในไฟล์ Manifest ไม่ได้ โดยมีข้อยกเว้นบางอย่าง
ข้อควรพิจารณาเมื่ออัปเดตวิดเจ็ตจาก BroadcastReceiver
หากอัปเดตวิดเจ็ตจาก BroadcastReceiver ซึ่งรวมถึง
AppWidgetProvider โปรดคำนึงถึงข้อควรพิจารณาต่อไปนี้เกี่ยวกับ
ระยะเวลาและความสำคัญของการอัปเดตวิดเจ็ต
ระยะเวลาการอัปเดต
ตามกฎแล้ว ระบบจะอนุญาตให้ตัวรับสัญญาณออกอากาศซึ่งมักจะทำงานในเทรดหลักของแอปทำงานได้นานสูงสุด 10 วินาทีก่อนที่จะถือว่าไม่ตอบสนองและทริกเกอร์ข้อผิดพลาด Application Not Responding (ANR) หากต้องการหลีกเลี่ยงการบล็อก
เทรดหลักขณะจัดการการออกอากาศ ให้ใช้วิธี goAsync หากการอัปเดตวิดเจ็ตใช้เวลานานขึ้น ให้พิจารณา
กำหนดเวลางานโดยใช้ WorkManager
Caution: Any work you do here blocks further broadcasts until it completes,
so it can slow the receiving of later events.
ดูข้อมูลเพิ่มเติมได้ที่ข้อควรพิจารณาและแนวทางปฏิบัติแนะนำด้านความปลอดภัย
ลำดับความสำคัญของการอัปเดต
โดยค่าเริ่มต้น การออกอากาศ รวมถึงการออกอากาศที่สร้างโดยใช้
AppWidgetProvider.onUpdate จะทำงานเป็นกระบวนการเบื้องหลัง ซึ่งหมายความว่า
ทรัพยากรของระบบที่โอเวอร์โหลดอาจทำให้การเรียกใช้ Broadcast
Receiver ล่าช้า หากต้องการให้ความสำคัญกับการออกอากาศ ให้เปลี่ยนเป็นกระบวนการที่ทำงานอยู่เบื้องหน้า
เช่น เพิ่มแฟล็ก Intent.FLAG_RECEIVER_FOREGROUND
ลงใน Intent ที่ส่งไปยัง PendingIntent.getBroadcast เมื่อผู้ใช้แตะส่วนใดส่วนหนึ่งของวิดเจ็ต