กระบวนการในพื้นหลังอาจต้องใช้หน่วยความจำและแบตเตอรี่มาก ตัวอย่างเช่น การออกอากาศโดยปริยายอาจเริ่มต้น กระบวนการเบื้องหลังมากมายที่เคยลงทะเบียนกับ ตั้งใจรับฟัง แม้ว่ากระบวนการเหล่านั้น จะไม่ได้ผลมากนักก็ตาม ซึ่งอาจ ส่งผลอย่างมากต่อทั้งประสิทธิภาพของอุปกรณ์และประสบการณ์ของผู้ใช้
หากต้องการหลีกเลี่ยงข้อจำกัดของระบบ โปรดตรวจสอบว่าคุณใช้ API ที่เหมาะสมสำหรับ งานในเบื้องหลัง เอกสารประกอบเกี่ยวกับภาพรวมของงานในเบื้องหลังช่วยให้คุณเลือก API ที่เหมาะกับความต้องการของคุณ
ข้อจำกัดที่เริ่มต้นโดยผู้ใช้
หากแอปแสดงลักษณะการทำงานที่ไม่ถูกต้องบางอย่างตามที่อธิบายไว้ใน Android Vitals ระบบจะแจ้งให้ผู้ใช้จำกัดสิทธิ์การเข้าถึงทรัพยากรระบบของแอป
หากระบบสังเกตเห็นว่าแอปใช้ทรัพยากรมากเกินไป ก็จะแจ้งเตือน ให้แก่ผู้ใช้ และให้ตัวเลือกแก่ผู้ใช้ในการจำกัดการดำเนินการของแอป ลักษณะการทำงานที่ทริกเกอร์การแจ้งเตือนได้มีดังนี้
- Wake Lock มากเกินไป: Wake Lock บางส่วนค้างไว้เป็นเวลา 1 ชั่วโมงเมื่อหน้าจอ ปิด
- บริการในเบื้องหลังมากเกินไป: หากแอปกำหนดเป้าหมายระดับ API ต่ำกว่า 26 และมีบริการที่ทำงานอยู่เบื้องหลังมากเกินไป
ผู้ผลิตอุปกรณ์เป็นผู้กำหนดข้อจำกัดที่แน่นอน สำหรับ ตัวอย่างเช่น ในบิลด์ AOSP แอปที่ถูกจำกัดจะไม่สามารถเรียกใช้งาน ทริกเกอร์การปลุก หรือใช้ เครือข่าย ยกเว้นเมื่อแอปทำงานอยู่เบื้องหน้า
ข้อจำกัดในการรับการกระจายข้อมูลกิจกรรมในเครือข่าย
แอปจะไม่ได้รับการแจ้งเตือน CONNECTIVITY_ACTION
หากลงทะเบียน
รับไฟล์ในไฟล์ Manifest และกระบวนการที่ต้องใช้การเผยแพร่นี้
ไม่เริ่มทำงาน ซึ่งอาจเป็นปัญหาสำหรับแอปที่ต้องการฟังเครือข่าย
เปลี่ยนแปลงหรือดำเนินกิจกรรมเครือข่ายจำนวนมากเมื่ออุปกรณ์เชื่อมต่อกับ
เครือข่ายที่ไม่มีการตรวจวัด มีวิธีที่หลากหลายเพื่อหลบเลี่ยงข้อจำกัดนี้
อยู่ในเฟรมเวิร์กของ Android แต่การเลือกตัวแปรที่เหมาะสมจะขึ้นอยู่กับสิ่งที่คุณ
ที่แอปต้องการบรรลุผลสำเร็จ
กำหนดเวลาทำงานในการเชื่อมต่อแบบไม่จำกัดปริมาณอินเทอร์เน็ต
เมื่อสร้าง WorkRequest
ให้เพิ่ม Constraint
ของ NetworkType.UNMETERED
fun scheduleWork(context: Context) {
val workManager = WorkManager.getInstance(context)
val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.build()
)
.build()
workManager.enqueue(workRequest)
}
เมื่อเป็นไปตามเงื่อนไขการทำงาน แอปจะได้รับการติดต่อกลับเพื่อเรียกใช้งาน
เมธอด doWork()
ในคลาส Worker
ที่ระบุ
ตรวจสอบการเชื่อมต่อเครือข่ายขณะที่แอปทำงานอยู่
แอปที่กำลังทำงานอยู่ยังคงฟัง CONNECTIVITY_CHANGE
ได้ด้วย
ลงทะเบียน BroadcastReceiver
แล้ว แต่ ConnectivityManager
API
ให้วิธีการที่มีประสิทธิภาพมากกว่าในการขอให้ติดต่อกลับเมื่อเครือข่ายที่ระบุเท่านั้น
ตรงตามเงื่อนไข
ออบเจ็กต์ NetworkRequest
กำหนดพารามิเตอร์ของ Callback ของเครือข่ายใน
ข้อกำหนดของ NetworkCapabilities
คุณสร้างออบเจ็กต์ NetworkRequest
รายการ
กับชั้นเรียน NetworkRequest.Builder
registerNetworkCallback
จากนั้นส่งออบเจ็กต์ NetworkRequest
ไปยังระบบ เมื่อเครือข่าย
ตรงตามเงื่อนไข แอปจะได้รับ Callback เพื่อดำเนินการ
ได้กำหนดเมธอด onAvailable()
ไว้ใน
ConnectivityManager.NetworkCallback
ชั้นเรียน
แอปจะยังคงได้รับการติดต่อกลับจนกว่าแอปจะออกหรือเรียกใช้ unregisterNetworkCallback()
ข้อจำกัดในการรับการออกอากาศรูปภาพและวิดีโอ
แอปไม่สามารถส่งหรือรับACTION_NEW_PICTURE หรือ ACTION_NEW_VIDEO ที่ออกอากาศ ข้อจำกัดนี้ช่วยลด ประสิทธิภาพและประสบการณ์ของผู้ใช้จะส่งผลต่อเมื่อแอปหลายแอปต้องทำงาน เพื่อประมวลผลรูปภาพหรือวิดีโอใหม่
ระบุว่าหน่วยงานเนื้อหาใดทริกเกอร์การทำงาน
WorkerParameters
ทำให้แอปของคุณได้รับข้อมูลที่เป็นประโยชน์เกี่ยวกับสิ่งที่
หน่วยงานเนื้อหาและ URI ที่เรียกใช้การทำงาน:
List<Uri> getTriggeredContentUris()
แสดงผลรายการ URI ที่ทริกเกอร์งาน ฟิลด์นี้จะว่างเปล่าถ้า ไม่มี URI ใดที่ทริกเกอร์งานดังกล่าว (ตัวอย่างเช่น มีการทริกเกอร์งานเนื่องจาก กำหนดเวลาหรือเหตุผลอื่น) หรือจำนวน URI ที่เปลี่ยนแปลงมากกว่า 50.
List<String> getTriggeredContentAuthorities()
แสดงผลรายการสตริงของหน่วยงานด้านเนื้อหาที่ทริกเกอร์การทำงาน ถ้า
รายการที่ส่งคืนไม่ว่างเปล่า โปรดใช้ getTriggeredContentUris()
เพื่อเรียกข้อมูล
รายละเอียดของ URI ที่มีการเปลี่ยนแปลง
โค้ดตัวอย่างต่อไปนี้จะลบล้างเมธอด CoroutineWorker.doWork()
และบันทึกหน่วยงานเนื้อหาและ URI ที่เรียกใช้งาน
class MyWorker(
appContext: Context,
params: WorkerParameters
): CoroutineWorker(appContext, params)
override suspend fun doWork(): Result {
StringBuilder().apply {
append("Media content has changed:\n")
params.triggeredContentAuthorities
.takeIf { it.isNotEmpty() }
?.let { authorities ->
append("Authorities: ${authorities.joinToString(", ")}\n")
append(params.triggeredContentUris.joinToString("\n"))
} ?: append("(No content)")
Log.i(TAG, toString())
}
return Result.success()
}
}
แอปทดสอบภายใต้ข้อจำกัดของระบบ
การเพิ่มประสิทธิภาพให้แอปทำงานบนอุปกรณ์ที่มีหน่วยความจำต่ำหรือในสภาวะที่มีหน่วยความจำต่ำ จะช่วยปรับปรุงประสิทธิภาพและประสบการณ์ของผู้ใช้ การนำทรัพยากร Dependency ออกในเบื้องหลัง บริการและ Broadcast Receiver แบบโดยนัยซึ่งลงทะเบียนไฟล์ Manifest สามารถช่วยให้แอปของคุณ ทำงานบนอุปกรณ์เหล่านี้ได้ดีกว่า ขอแนะนำให้คุณเพิ่มประสิทธิภาพแอปเพื่อให้ทำงานได้ โดยไม่ใช้กระบวนการเบื้องหลังเหล่านี้โดยสิ้นเชิง
คำสั่งเพิ่มเติมของ Android Debug Bridge (ADB) บางส่วนสามารถช่วยคุณทดสอบแอปได้ การทำงานเมื่อปิดใช้กระบวนการเบื้องหลังเหล่านั้น
เพื่อจำลองเงื่อนไขที่การออกอากาศโดยนัยและบริการที่ทำงานอยู่เบื้องหลัง ไม่พร้อมใช้งาน ให้ป้อนคำสั่งต่อไปนี้
$ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore
หากต้องการเปิดใช้การออกอากาศโดยนัยและบริการเบื้องหลังอีกครั้ง ให้ป้อนข้อมูลต่อไปนี้ คำสั่ง:
$ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND allow
เพิ่มประสิทธิภาพแอปให้ดียิ่งขึ้น
เกี่ยวกับวิธีดีๆ อื่นๆ ในการเพิ่มประสิทธิภาพงานในเบื้องหลัง พฤติกรรม โปรดดู เพิ่มประสิทธิภาพการใช้งานแบตเตอรี่สำหรับ API การกำหนดเวลางาน เอกสารประกอบ