หน้านี้อธิบายแนวทางปฏิบัติแนะนำสำหรับการสร้างวิดเจ็ตขั้นสูงขึ้นเพื่อประสบการณ์ของผู้ใช้ที่ดียิ่งขึ้น
การเพิ่มประสิทธิภาพสำหรับการอัปเดตเนื้อหาวิดเจ็ต
การอัปเดตเนื้อหาวิดเจ็ตอาจต้องใช้การคำนวณจำนวนมาก หากต้องการประหยัดแบตเตอรี่ ให้เพิ่มประสิทธิภาพประเภท ความถี่ และเวลาในการอัปเดต
ประเภทการอัปเดตวิดเจ็ต
การอัปเดตวิดเจ็ตทำได้ 3 วิธี ได้แก่ การอัปเดตแบบเต็ม การอัปเดตบางส่วน และการรีเฟรชข้อมูล (ในกรณีของวิดเจ็ตคอลเล็กชัน) โดยแต่ละวิธีจะมีค่าใช้จ่ายในการคำนวณและผลที่ตามมาแตกต่างกัน
คำอธิบายประเภทการอัปเดตแต่ละประเภทและตัวอย่างโค้ดสำหรับแต่ละประเภทมีดังนี้
การอัปเดตแบบเต็ม: เรียกใช้
AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews)เพื่ออัปเดตวิดเจ็ตแบบเต็ม ซึ่งจะแทนที่RemoteViewsที่ระบุไว้ก่อนหน้านี้ด้วยRemoteViewsใหม่ การอัปเดตประเภทนี้ต้องใช้การคำนวณมากที่สุดKotlin
val appWidgetManager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.getPackageName(), R.layout.widgetlayout).also { setTextViewText(R.id.textview_widget_layout1, "Updated text1") setTextViewText(R.id.textview_widget_layout2, "Updated text2") } appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
Java
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); remoteViews.setTextViewText(R.id.textview_widget_layout1, "Updated text1"); remoteViews.setTextViewText(R.id.textview_widget_layout2, "Updated text2"); appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
การอัปเดตบางส่วน: เรียกใช้
AppWidgetManager.partiallyUpdateAppWidgetเพื่ออัปเดตบางส่วนของวิดเจ็ต ซึ่งจะผสานRemoteViewsใหม่กับRemoteViewsที่ระบุไว้ก่อนหน้านี้ ระบบจะละเว้นเมธอดนี้หากวิดเจ็ต ไม่ได้รับการอัปเดตแบบเต็มอย่างน้อย 1 ครั้งผ่านupdateAppWidget(int[], RemoteViews)Kotlin
val appWidgetManager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.getPackageName(), R.layout.widgetlayout).also { setTextViewText(R.id.textview_widget_layout, "Updated text") } appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews)
Java
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); remoteViews.setTextViewText(R.id.textview_widget_layout, "Updated text"); appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews);
การรีเฟรชข้อมูลคอลเล็กชัน: เรียกใช้
AppWidgetManager.notifyAppWidgetViewDataChangedเพื่อล้างข้อมูลของ Collection View ในวิดเจ็ต ซึ่งจะทริกเกอร์RemoteViewsFactory.onDataSetChangedในระหว่างนี้ ระบบจะแสดงข้อมูลเก่าในวิดเจ็ต คุณสามารถทำงานที่ต้องใช้ทรัพยากรจำนวนมากแบบซิงโครนัสได้อย่างปลอดภัยด้วยเมธอดนี้Kotlin
val appWidgetManager = AppWidgetManager.getInstance(context) appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)
Java
AppWidgetManager 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มีลำดับความสำคัญ
อัปเดตเพื่อตอบสนองต่อเหตุการณ์การออกอากาศ
ตัวอย่างเหตุการณ์การออกอากาศที่ต้องให้อัปเดตวิดเจ็ตคือเมื่อผู้ใช้ถ่ายรูป ในกรณีนี้ คุณต้องการอัปเดตวิดเจ็ตเมื่อตรวจพบรูปภาพใหม่
คุณสามารถกำหนดเวลา Task ด้วย JobScheduler และระบุการออกอากาศเป็น
ทริกเกอร์โดยใช้
JobInfo.Builder.addTriggerContentUri
เมธอด
นอกจากนี้ คุณยังลงทะเบียน BroadcastReceiver สำหรับการออกอากาศได้ด้วย เช่น
การฟัง
ACTION_LOCALE_CHANGED
อย่างไรก็ตาม เนื่องจากวิธีนี้ใช้ทรัพยากรของอุปกรณ์ จึงควรใช้อย่างระมัดระวังและฟังเฉพาะการออกอากาศที่เฉพาะเจาะจง เมื่อมีการเปิดตัวข้อจำกัดการออกอากาศใน Android
7.0 (ระดับ API 24) และ Android 8.0 (ระดับ API 26) แอปต่างๆ จะลงทะเบียนการออกอากาศโดยนัย
ในไฟล์ Manifest ไม่ได้ ยกเว้นบาง
กรณี
ข้อควรพิจารณาเมื่ออัปเดตวิดเจ็ตจาก BroadcastReceiver
หากอัปเดตวิดเจ็ตจาก BroadcastReceiver รวมถึง AppWidgetProvider โปรดทราบข้อควรพิจารณาต่อไปนี้เกี่ยวกับระยะเวลาและลำดับความสำคัญของการอัปเดตวิดเจ็ต
ระยะเวลาการอัปเดต
โดยปกติแล้ว ระบบจะอนุญาตให้ Broadcast Receiver ซึ่งมักจะทำงานใน Main Thread ของแอป ทำงานได้นานสูงสุด 10 วินาทีก่อนที่จะถือว่าไม่ตอบสนองและทริกเกอร์ข้อผิดพลาด Application Not Responding (ANR) หากต้องการหลีกเลี่ยงการบล็อก
Main Thread ขณะจัดการการออกอากาศ ให้ใช้เมธอด
goAsync หากการอัปเดตวิดเจ็ตใช้เวลานานกว่านั้น ให้พิจารณากำหนดเวลา Task โดยใช้ 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 เมื่อผู้ใช้
แตะส่วนใดส่วนหนึ่งของวิดเจ็ต