หน้านี้อธิบายแนวทางปฏิบัติที่แนะนำในการสร้างวิดเจ็ตขั้นสูงยิ่งขึ้นเพื่อประสบการณ์ของผู้ใช้ที่ดียิ่งขึ้น
การเพิ่มประสิทธิภาพสำหรับการอัปเดตเนื้อหาวิดเจ็ต
การอัปเดตเนื้อหาวิดเจ็ตอาจใช้การคำนวณสูง เพิ่มประสิทธิภาพประเภท ความถี่ และเวลาในการอัปเดตเพื่อประหยัดแบตเตอรี่
ประเภทการอัปเดตวิดเจ็ต
การอัปเดตวิดเจ็ตมี 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
เพื่อลบล้างข้อมูลของมุมมองคอลเล็กชันในวิดเจ็ต ซึ่งจะทริกเกอร์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
มีความสำคัญได้
อัปเดตเพื่อตอบสนองต่อเหตุการณ์การออกอากาศ
ตัวอย่างเหตุการณ์ที่ออกอากาศซึ่งต้องใช้วิดเจ็ตในการอัปเดตคือเมื่อผู้ใช้ถ่ายรูป ในกรณีนี้ คุณต้องการอัปเดตวิดเจ็ตเมื่อตรวจพบรูปภาพใหม่
คุณสามารถกำหนดเวลางานด้วย JobScheduler
และระบุการออกอากาศเป็นทริกเกอร์โดยใช้เมธอด
JobInfo.Builder.addTriggerContentUri
คุณยังลงทะเบียน BroadcastReceiver
สำหรับการออกอากาศได้ด้วย เช่น
ฟัง
ACTION_LOCALE_CHANGED
อย่างไรก็ตาม เนื่องจากฟีเจอร์นี้ใช้ทรัพยากรของอุปกรณ์ โปรดใช้ฟีเจอร์นี้อย่างระมัดระวังและฟัง
เฉพาะการออกอากาศที่ต้องการ เมื่อเปิดตัวข้อจำกัดในการออกอากาศใน Android 7.0 (API ระดับ 24) และ Android 8.0 (API ระดับ 26) แอปต่างๆ จะลงทะเบียนการออกอากาศโดยนัยในไฟล์ Manifest ไม่ได้ โดยมีข้อยกเว้นบางประการ
ข้อควรพิจารณาเมื่ออัปเดตวิดเจ็ตจาก BroadcastReceiver
หากวิดเจ็ตได้รับการอัปเดตจาก BroadcastReceiver
ซึ่งรวมถึง
AppWidgetProvider
โปรดคำนึงถึงข้อควรพิจารณาต่อไปนี้เกี่ยวกับ
ระยะเวลาและความสำคัญของการอัปเดตวิดเจ็ต
ระยะเวลาการอัปเดต
ตามกฎแล้ว ระบบจะอนุญาตให้ตัวรับสัญญาณออกอากาศซึ่งมักจะทำงานในเทรดหลักของแอปทำงานได้นานสูงสุด 10 วินาทีก่อนที่จะถือว่าไม่ตอบสนองและทริกเกอร์ข้อผิดพลาดแอปพลิเคชันไม่ตอบสนอง (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
เมื่อผู้ใช้แตะส่วนใดส่วนหนึ่งของวิดเจ็ต