ในกรณีส่วนใหญ่ แอปพลิเคชัน Android ทุกแอปจะทำงานในกระบวนการ Linux ของตัวเอง ระบบจะสร้างกระบวนการนี้สําหรับแอปพลิเคชันเมื่อโค้ดบางส่วนต้องทํางานและยังคงทํางานต่อไปจนกว่าระบบจะต้องเรียกคืนหน่วยความจําเพื่อใช้โดยแอปพลิเคชันอื่นๆ และไม่จำเป็นต้องใช้กระบวนการดังกล่าวอีกต่อไป
ฟีเจอร์พื้นฐานที่ผิดปกติของ Android คือแอปพลิเคชันไม่ได้ควบคุมอายุการใช้งานของกระบวนการแอปพลิเคชันโดยตรง แต่ระบบจะกำหนดโดยพิจารณาจากส่วนต่างๆ ของแอปพลิเคชันที่ระบบทราบว่ากำลังทำงานอยู่ ความสำคัญของสิ่งเหล่านี้ต่อผู้ใช้ และปริมาณหน่วยความจำโดยรวมที่มีอยู่ในระบบ
นักพัฒนาแอปต้องเข้าใจว่าคอมโพเนนต์ต่างๆ ของแอป (โดยเฉพาะ Activity
, Service
และ BroadcastReceiver
) ส่งผลต่ออายุการใช้งานของกระบวนการของแอปอย่างไร การใช้คอมโพเนนต์เหล่านี้อย่างไม่ถูกต้องอาจส่งผลให้ระบบหยุดกระบวนการของแอปพลิเคชันขณะที่ดำเนินการงานสำคัญ
ตัวอย่างที่พบบ่อยของข้อบกพร่องเกี่ยวกับวงจรกระบวนการคือ BroadcastReceiver
ที่เริ่มต้นเธรดเมื่อได้รับ Intent
ในเมธอด BroadcastReceiver.onReceive()
แล้วแสดงผลลัพธ์จากฟังก์ชัน เมื่อกลับมาแล้ว ระบบจะถือว่า BroadcastReceiver
ไม่มีการใช้งานอีกต่อไป และไม่จำเป็นต้องใช้กระบวนการโฮสติ้งอีกต่อไป เว้นแต่ว่าคอมโพเนนต์แอปพลิเคชันอื่นๆ จะยังคงใช้งานอยู่
ดังนั้นระบบจึงสามารถฆ่ากระบวนการได้ทุกเมื่อเพื่อเรียกคืนหน่วยความจำ และการดำเนินการดังกล่าวจะสิ้นสุดเธรดที่สร้างขึ้นซึ่งทำงานอยู่ในกระบวนการ โดยปกติแล้ววิธีแก้ปัญหานี้คือการกําหนดเวลาJobService
จากBroadcastReceiver
เพื่อให้ระบบทราบว่ามีงานเกิดขึ้นในกระบวนการ
Android จะจัดลำดับความสำคัญของแต่ละกระบวนการตามคอมโพเนนต์ที่ทำงานอยู่และสถานะของคอมโพเนนต์เหล่านั้น เพื่อพิจารณาว่าจะฆ่ากระบวนการใดเมื่อหน่วยความจำเหลือน้อย กระบวนการเหล่านี้จัดตามลําดับความสําคัญดังนี้
- กระบวนการที่ทำงานอยู่เบื้องหน้าคือกระบวนการที่จําเป็นสําหรับสิ่งที่ผู้ใช้กําลังทําอยู่ คอมโพเนนต์แอปพลิเคชันต่างๆ อาจทําให้ระบบพิจารณากระบวนการที่รวมอยู่นั้นอยู่เบื้องหน้าในลักษณะต่างๆ ระบบจะถือว่ากระบวนการทำงานอยู่เบื้องหน้าหากเป็นไปตามเงื่อนไขข้อใดข้อหนึ่งต่อไปนี้
- มีการเรียกใช้
Activity
ที่ด้านบนของหน้าจอที่ผู้ใช้โต้ตอบอยู่ (มีการเรียกใช้เมธอดonResume()
) - มี
BroadcastReceiver
ที่กําลังทํางานอยู่ (วิธีการBroadcastReceiver.onReceive()
ดําเนินการอยู่) - เพราะมี
Service
ที่กําลังเรียกใช้โค้ดในหนึ่งในคอลแบ็ก (Service.onCreate()
,Service.onStart()
หรือService.onDestroy()
)
- มีการเรียกใช้
- กระบวนการที่มองเห็นได้จะทํางานตามที่ผู้ใช้รับรู้อยู่ในปัจจุบัน การสิ้นสุดกระบวนการดังกล่าวจึงส่งผลเสียต่อประสบการณ์ของผู้ใช้อย่างชัดเจน ระบบจะถือว่ากระบวนการมองเห็นได้ในเงื่อนไขต่อไปนี้
- มีการเรียกใช้
Activity
ที่ผู้ใช้มองเห็นบนหน้าจอแต่ไม่ได้อยู่ในเบื้องหน้า (มีการเรียกใช้เมธอดonPause()
) กรณีนี้อาจเกิดขึ้นได้ เช่น หากActivity
ที่อยู่เบื้องหน้าแสดงเป็นกล่องโต้ตอบที่มองเห็นActivity
ก่อนหน้าอยู่เบื้องหลัง - แอปมี
Service
ที่ทำงานเป็นบริการที่ทำงานอยู่เบื้องหน้าผ่านService.startForeground()
(ซึ่งขอให้ระบบถือว่าบริการเป็นสิ่งที่ผู้ใช้รับรู้ หรือโดยพื้นฐานแล้วราวกับว่ามองเห็นบริการนั้น) - บริการนี้โฮสต์บริการที่ระบบใช้สำหรับฟีเจอร์บางอย่างที่ผู้ใช้ทราบ เช่น วอลเปเปอร์เคลื่อนไหวหรือบริการวิธีการป้อนข้อมูล
จำนวนกระบวนการเหล่านี้ที่ทำงานอยู่ในระบบมีขอบเขตน้อยกว่ากระบวนการที่ทำงานอยู่เบื้องหน้า แต่ก็ยังคงควบคุมได้อยู่ ระบบจะถือว่ากระบวนการเหล่านี้มีความสำคัญอย่างยิ่งและจะไม่หยุดกระบวนการดังกล่าว เว้นแต่ว่าจะต้องหยุดเพื่อทำให้กระบวนการที่ทำงานอยู่เบื้องหน้าทั้งหมดทำงานต่อไป
- มีการเรียกใช้
- กระบวนการบริการคือกระบวนการที่มี
Service
ที่เริ่มต้นด้วยเมธอดstartService()
แม้ว่าผู้ใช้จะไม่เห็นกระบวนการเหล่านี้โดยตรง แต่โดยทั่วไปแล้วกระบวนการเหล่านี้จะทําสิ่งที่ผู้ใช้สนใจ (เช่น การอัปโหลดหรือดาวน์โหลดข้อมูลเครือข่ายในเบื้องหลัง) ดังนั้นระบบจะทําให้กระบวนการดังกล่าวทํางานอยู่เสมอ เว้นแต่ว่าจะมีหน่วยความจําไม่เพียงพอที่จะเก็บกระบวนการที่ทำงานอยู่เบื้องหน้าและกระบวนการที่มองเห็นได้ทั้งหมดบริการที่ทำงานมาเป็นเวลานาน (เช่น 30 นาทีขึ้นไป) อาจลดลำดับความสำคัญเพื่อให้กระบวนการของบริการนั้นไปอยู่ในรายการที่แคชไว้
กระบวนการที่ต้องทำงานเป็นระยะเวลานานจะสร้างได้ด้วย
setForeground
หากเป็นกระบวนการตามรอบที่กำหนดเวลาการเรียกใช้อย่างเข้มงวด คุณจะกำหนดเวลาผ่านAlarmManager
ได้ ดูข้อมูลเพิ่มเติมได้ที่การรองรับสำหรับงานที่ทำงานต่อเนื่องเป็นเวลานาน วิธีนี้จะช่วยหลีกเลี่ยงกรณีที่บริการที่ทำงานอยู่นานและใช้ทรัพยากรมากเกินไป เช่น การรั่วไหลของหน่วยความจำ ซึ่งทำให้ระบบมอบประสบการณ์การใช้งานที่ดีแก่ผู้ใช้ไม่ได้ - กระบวนการที่แคชไว้คือกระบวนการที่ไม่จำเป็นในขณะนี้ ดังนั้นระบบจึงสามารถหยุดกระบวนการดังกล่าวได้ตามต้องการเมื่อต้องใช้ทรัพยากรอื่นๆ เช่น หน่วยความจำ ในระบบที่ทำงานตามปกติ กระบวนการเหล่านี้เป็นกระบวนการเดียวที่เกี่ยวข้องกับการจัดการทรัพยากร
ระบบที่ทำงานได้อย่างราบรื่นจะมีกระบวนการแคชหลายรายการที่พร้อมใช้งานเสมอ เพื่อการสลับระหว่างแอปพลิเคชันอย่างมีประสิทธิภาพ และปิดแอปที่แคชไว้เป็นประจำตามความจำเป็น ระบบจะหยุดกระบวนการแคชทั้งหมดและเริ่มหยุดกระบวนการบริการก็ต่อเมื่ออยู่ในสถานการณ์ที่ร้ายแรงมากเท่านั้น
เนื่องจากระบบอาจหยุดกระบวนการที่แคชไว้ได้ทุกเมื่อ แอปจึงควรหยุดทํางานทั้งหมดขณะที่อยู่ในสถานะแคช หากแอปต้องทำงานที่สำคัญต่อผู้ใช้ ก็ควรใช้ API รายการใดรายการหนึ่งข้างต้นเพื่อทำงานจากสถานะกระบวนการที่ทำงานอยู่
กระบวนการที่แคชไว้มักจะเก็บอินสแตนซ์
Activity
อย่างน้อย 1 รายการที่ผู้ใช้ไม่เห็นในขณะนี้ (มีการเรียกใช้เมธอดonStop()
แล้วและแสดงผลแล้ว) ตราบใดที่นักพัฒนาแอปใช้วงจรชีวิตของActivity
อย่างถูกต้อง เมื่อระบบหยุดกระบวนการดังกล่าว ประสบการณ์ของผู้ใช้เมื่อกลับมาที่แอปนั้นจะไม่ได้รับผลกระทบ ระบบจะกู้คืนสถานะที่บันทึกไว้ก่อนหน้านี้ได้เมื่อกิจกรรมที่เกี่ยวข้องสร้างขึ้นใหม่ในกระบวนการใหม่ โปรดทราบว่าระบบไม่รับประกันว่าจะมีการเรียกใช้onDestroy()
ในกรณีที่ระบบหยุดกระบวนการ ดูรายละเอียดเพิ่มเติมได้ที่Activity
ตั้งแต่ Android 13 เป็นต้นไป กระบวนการของแอปอาจได้รับเวลาดำเนินการแบบจำกัดหรือไม่ได้รับเวลาดำเนินการเลยจนกว่าจะเข้าสู่สถานะวงจรการทำงานที่ใช้งานอยู่อย่างใดอย่างหนึ่งข้างต้น
ระบบจะเก็บกระบวนการที่แคชไว้เป็นรายการ นโยบายการจัดเรียงที่แน่นอนสำหรับรายการนี้คือรายละเอียดการใช้งานของแพลตฟอร์ม โดยทั่วไปแล้ว ระบบจะพยายามเก็บกระบวนการที่มีประโยชน์มากกว่าไว้ก่อน เช่น กระบวนการที่โฮสต์แอปพลิเคชันหน้าแรกของผู้ใช้หรือกิจกรรมล่าสุดที่ผู้ใช้เห็น ไว้ก่อนกระบวนการประเภทอื่นๆ นอกจากนี้ คุณยังใช้นโยบายอื่นๆ สำหรับการสิ้นสุดกระบวนการได้ด้วย เช่น การกำหนดขีดจำกัดสูงสุดของจำนวนกระบวนการที่อนุญาต หรือจำกัดระยะเวลาที่กระบวนการสามารถแคชไว้ได้อย่างต่อเนื่อง
ระบบจะมีกระบวนการดังกล่าวเพียงไม่กี่รายการเท่านั้น และระบบจะหยุดกระบวนการเหล่านี้ก็ต่อเมื่อเป็นทางเลือกสุดท้ายในกรณีที่หน่วยความจําเหลือน้อยมากจนแม้แต่กระบวนการเหล่านี้ยังทํางานต่อไปไม่ได้ โดยทั่วไปแล้ว หากเกิดเหตุการณ์นี้ขึ้น แสดงว่าอุปกรณ์อยู่ในสถานะการแบ่งหน่วยความจำ จึงจำเป็นต้องดำเนินการนี้เพื่อให้อินเทอร์เฟซผู้ใช้ตอบสนองได้อยู่เสมอ
เมื่อตัดสินใจว่าจะจัดประเภทกระบวนการอย่างไร ระบบจะพิจารณาจากระดับที่สำคัญที่สุดที่พบในคอมโพเนนต์ทั้งหมดที่ใช้งานอยู่ในกระบวนการ
ดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีที่คอมโพเนนต์แต่ละรายการเหล่านี้มีส่วนช่วยในวงจรโดยรวมของกระบวนการและแอปพลิเคชันได้ในเอกสารประกอบของ Activity
, Service
และ BroadcastReceiver
นอกจากนี้ ระบบอาจเพิ่มลําดับความสําคัญของกระบวนการตามลําดับความสําคัญของกระบวนการอื่นที่มีต่อกระบวนการนั้น ตัวอย่างเช่น หากกระบวนการ ก. เชื่อมโยงกับ Service
ที่มี Flag Context.BIND_AUTO_CREATE
หรือใช้ ContentProvider
ในกระบวนการ ข. การจัดประเภทของกระบวนการ ข. จะมีความสำคัญอย่างน้อยเท่ากับกระบวนการ ก. เสมอ