Android ทำลายกิจกรรมกระบวนการฆ่า


117

สวัสดีฉันสงสัยว่า Android จัดการหน่วยความจำอย่างไรและฉันไม่พบคำตอบที่แน่นอน สมมติว่าฉันมีแอปพลิเคชันที่มี 5 กิจกรรมในสแต็กกิจกรรมปัจจุบัน (4 หยุดและ 1 จะกลับมาทำงานต่อ) ไม่มีบริการเชื่อมต่อ ฉันกดปุ่ม HOME เพื่อให้กิจกรรมทั้งหมดของฉันหยุดลง ฉันเปิดแอปพลิเคชั่นที่ใช้หน่วยความจำอื่น ๆ และหน่วยความจำอุปกรณ์โดยรวมเริ่มเหลือน้อย และคำถามคือ

... จะเกิดอะไรขึ้นกับใบสมัครของฉัน?

  1. ระบบสามารถทำลายกิจกรรมเพียงอย่างเดียวหรือบางส่วนเพื่อกู้คืนหน่วยความจำได้หรือไม่?
  2. ระบบจะฆ่ากระบวนการทั้งหมดของแอปพลิเคชันของฉันหรือไม่ กิจกรรมทั้งหมดจะถูกทำลายลงหรือไม่?
  3. จะเกิดอะไรขึ้นเมื่อฉันกลับไปที่แอปพลิเคชันของฉันเมื่อมันถูกฆ่าทั้งหมด? จะเริ่มจากการขอทาน (เช่นการเริ่มครั้งแรก) หรือจะพยายามกู้คืนกิจกรรมให้กลับสู่สถานะที่เป็นที่นิยม / ถ้าใช่ - เป็นเพียงกิจกรรมที่อยู่ด้านบนสุดของสแต็กหรือทั้งหมด?

UPDATE:

ก่อนที่จะถามคำถามนี้ฉันเคยเห็นวงจรชีวิตของกิจกรรมสองสามครั้ง แต่ไม่มีคำตอบสำหรับคำถามของฉัน ฉันทำแบบทดสอบและมีคำตอบ "หยุดกระบวนการ" ใน DDMS เป็นเบาะแสสำหรับการทดสอบ

ฉันยังไม่ได้ทดสอบคำตอบสำหรับคำถาม 1 แต่ตามที่ไกด์บอกว่า:

หากกิจกรรมถูกหยุดชั่วคราวหรือหยุดระบบสามารถยกเลิกกิจกรรมจากหน่วยความจำได้โดยขอให้กิจกรรมนั้นเสร็จสิ้นหรือเพียงแค่ฆ่ากระบวนการ

ดูเหมือนว่ากิจกรรมอย่างน้อยหนึ่งอย่างสามารถทำลายได้อย่างนุ่มนวล (ด้วยวิธี onDestroy) โดยไม่ต้องฆ่ากระบวนการ คุณจะได้รับ (onCreate + bundle) เมื่อกลับไปหาพวกเขา

คำถาม 2 คำตอบ:

ใช่. โดยทั่วไประบบจะฆ่ากระบวนการทั้งหมดซึ่งหมายความว่าข้อมูลทั้งหมดรวมถึงกิจกรรมและฟิลด์คงที่จะถูกทำลาย สิ่งนี้ไม่ได้ทำอย่างดี - คุณจะไม่ได้รับ onDestroy หรือ finialize () สำหรับกิจกรรมที่หยุดชั่วคราว / หยุด นี่คือเหตุผลที่ saveInstanceState () ถูกเรียกก่อนเมธอด onPause onPause เป็นวิธีสุดท้ายที่คุณควรบันทึกบางสิ่งเพราะหลังจากวิธีนี้คุณจะไม่เห็น onStop หรือ onDestroy ระบบสามารถฆ่ากระบวนการทำลายวัตถุทั้งหมดของคุณได้ทุกสิ่งที่พวกเขาถือและสิ่งที่พวกเขากำลังทำ

คำถาม 3 คำตอบ:

จะเกิดอะไรขึ้นเมื่อคุณกลับไปที่แอปพลิเคชันที่ถูกฆ่า

  • ก่อนหน้า Android 2.2 - แอปพลิเคชันจะเริ่มต้นจากการเริ่มต้นพร้อมกับกิจกรรมตัวเรียกใช้งาน
  • เริ่มจาก 2.2 - ระบบจะกู้คืนสถานะแอปพลิเคชันก่อนหน้านี้ หมายความว่าอย่างไร? หมายความว่ากิจกรรมที่มองเห็นล่าสุดจะถูกสร้างขึ้นใหม่ (onCreate + bundle) จะเกิดอะไรขึ้นกับกองกิจกรรม สแต็คใช้ได้ดี แต่กิจกรรมทั้งหมดในนั้นตายไปแล้ว แต่ละรายการจะถูกสร้างขึ้นใหม่ (onCreate + bundle) เมื่อคุณกลับไปที่ปุ่มย้อนกลับ มีอีกอย่างหนึ่งเกี่ยวกับเรื่องนี้:

โดยปกติระบบจะล้างงาน (ลบกิจกรรมทั้งหมดออกจากสแต็กเหนือกิจกรรมรูท) ในบางสถานการณ์เมื่อผู้ใช้เลือกงานนั้นใหม่จากหน้าจอหลัก โดยทั่วไปแล้วจะเกิดขึ้นหากผู้ใช้ไม่ได้เข้าชมงานเป็นระยะเวลาหนึ่งเช่น 30 นาที

สรุป?

  1. อย่าคิดว่าการจัดการปัญหาการหมุนเวียนกิจกรรมสามารถแก้ไขได้ด้วย android: configChanges = "orientation" เมื่อคุณทำเช่นนั้นคุณจะได้รับปัญหาอื่น ๆ อีกมากมายที่คุณไม่รู้ด้วยซ้ำ
  2. ทดสอบแอปพลิเคชันของคุณด้วย DDMS - ปุ่มหยุดกระบวนการ ดูนี่
  3. ระมัดระวังเมื่อใช้ตัวแปรคงที่ อย่าคิดว่าเมื่อคุณเริ่มต้นในกิจกรรมที่ 1 คุณจะเริ่มต้นในกิจกรรมที่ 2 สถานที่ที่ปลอดภัยเพียงแห่งเดียวในการเริ่มต้นสถิติโลกคือคลาสแอปพลิเคชัน
  4. จำไว้ว่าคุณอาจไม่เคยเห็น onStop หรือ onDestroy ปิดไฟล์ / ฐานข้อมูลหยุดตัวดาวน์โหลดใน onPause เมื่อคุณต้องการให้แอปทำบางสิ่งใน BG - ใช้บริการเบื้องหน้า

ไม่ว่าจะเป็น ... หวังว่าฉันจะช่วยด้วย essey ของฉัน :)


สำหรับข้อสันนิษฐานของคุณกิจกรรมทั้ง 5 นี้มาจากแอพเดียวกันหรือหลายแอพ?
dumbfingers

1
"ฉันมีแอปพลิเคชันที่มี 5 กิจกรรมในกองกิจกรรมปัจจุบัน" แน่นอนว่าทั้งหมดมาจากแอปพลิเคชันกระบวนการเดียวของฉัน
มาร์ค

4
ขอบคุณนี่ก็เป็นคำถามของฉันเหมือนกัน ... คำถามและคำตอบของคุณช่วยฉันได้ไม่น้อย
craigrs84


@ มาร์ค: ตอนนี้แก้ปัญหาแล้วหรือยัง? ถ้าเป็นยังไง?
Ameer Moaaviah

คำตอบ:


30

ก่อนอื่นโปรดดูสิ่งนี้:

img1

onPause () เรียกเมื่อระบบกำลังจะเริ่มดำเนินการต่อกิจกรรมก่อนหน้านี้ โดยทั่วไปจะใช้เพื่อทำการเปลี่ยนแปลงข้อมูลที่ยังไม่ได้บันทึกหยุดภาพเคลื่อนไหวและสิ่งอื่น ๆ ที่อาจใช้ CPU เป็นต้นการใช้งานวิธีนี้จะต้องรวดเร็วมากเนื่องจากกิจกรรมถัดไปจะไม่ถูกดำเนินการต่อจนกว่าวิธีนี้จะกลับมา ตามด้วย onResume () หากกิจกรรมกลับไปที่ด้านหน้าหรือ onStop () หากผู้ใช้มองไม่เห็น

onStop ()เรียกเมื่อผู้ใช้ไม่สามารถมองเห็นกิจกรรมได้อีกต่อไปเนื่องจากกิจกรรมอื่นกลับมาทำงานต่อและครอบคลุมกิจกรรมนี้ สิ่งนี้อาจเกิดขึ้นได้เนื่องจากกิจกรรมใหม่กำลังเริ่มต้นกิจกรรมที่มีอยู่ถูกนำมาด้านหน้ากิจกรรมนี้หรือกิจกรรมนี้กำลังถูกทำลาย ตามด้วย onRestart () หากกิจกรรมนี้กลับมาเพื่อโต้ตอบกับผู้ใช้หรือ onDestroy () หากกิจกรรมนี้กำลังจะหายไป

ดังนั้นเมื่อคุณกดปุ่ม "HOME" บนอุปกรณ์ของคุณกิจกรรมเบื้องหน้าปัจจุบันของคุณจะถูกใส่ลงในonPause()นั้นonStop()อีก 4 รายการควรยังคงอยู่onStop()

ตามเอกสารของ Google:

  • หากกิจกรรมอยู่เบื้องหน้าของหน้าจอ (ที่ด้านบนสุดของสแต็ก) กิจกรรมนั้นกำลังทำงานอยู่
  • หากกิจกรรมสูญเสียโฟกัส แต่ยังมองเห็นได้ (นั่นคือกิจกรรมใหม่ที่ไม่ใช่ขนาดเต็มหรือโปร่งใสเน้นที่กิจกรรมของคุณ) กิจกรรมนั้นจะหยุดชั่วคราว กิจกรรมที่หยุดชั่วคราวยังคงมีชีวิตอยู่อย่างสมบูรณ์ (จะรักษาข้อมูลสถานะและข้อมูลสมาชิกทั้งหมดและยังคงติดอยู่กับตัวจัดการหน้าต่าง) แต่ระบบสามารถฆ่าได้ในสถานการณ์ที่หน่วยความจำเหลือน้อยมาก
  • หากกิจกรรมอื่นถูกบดบังโดยสิ้นเชิงกิจกรรมนั้นจะหยุดลง มันยังคงรักษาข้อมูลสถานะและข้อมูลสมาชิกทั้งหมดไว้อย่างไรก็ตามผู้ใช้ไม่สามารถมองเห็นได้อีกต่อไปดังนั้นหน้าต่างจึงถูกซ่อนไว้และมักจะถูกฆ่าโดยระบบเมื่อต้องการหน่วยความจำที่อื่น
  • หากกิจกรรมถูกหยุดชั่วคราวหรือหยุดระบบสามารถยกเลิกกิจกรรมจากหน่วยความจำได้โดยขอให้กิจกรรมนั้นเสร็จสิ้นหรือเพียงแค่ฆ่ากระบวนการ เมื่อแสดงต่อผู้ใช้อีกครั้งจะต้องเริ่มต้นใหม่ทั้งหมดและเรียกคืนสู่สถานะก่อนหน้า

และสำหรับวงจรชีวิตของกระบวนการ:

Process Lifecycle 3. กิจกรรมเบื้องหลัง (กิจกรรมที่ผู้ใช้มองไม่เห็นและถูกหยุดชั่วคราว) ไม่สำคัญอีกต่อไปดังนั้นระบบอาจฆ่ากระบวนการอย่างปลอดภัยเพื่อเรียกคืนหน่วยความจำสำหรับกระบวนการเบื้องหน้าหรือกระบวนการอื่นที่มองเห็นได้ หากกระบวนการของมันจำเป็นต้องถูกฆ่าเมื่อผู้ใช้กลับไปที่กิจกรรม (ทำให้มองเห็นได้บนหน้าจออีกครั้ง) เมธอด onCreate (Bundle) ของมันจะถูกเรียกพร้อมกับ saveInstanceState ที่เคยให้ไว้ใน onSaveInstanceState (Bundle) เพื่อให้ สามารถรีสตาร์ทตัวเองในสถานะเดียวกับที่ผู้ใช้ปล่อยทิ้งไว้

คำพูดทั้งหมดข้างต้นมาจาก: ข้อมูลอ้างอิงของนักพัฒนาซอฟต์แวร์ Android: กิจกรรม

ได้รับการยืนยันว่าระบบสามารถทำลายกิจกรรมที่ไม่ได้รับผลกระทบและรีไซเคิลความทรงจำเมื่อคุณเปิดตัวแอปพลิเคชันที่ใช้หน่วยความจำบางตัว และคุณสามารถใช้เช่น: isFinishing()ในกิจกรรมของคุณจากนั้นใช้ปุ่ม "ฆ่า" ใน DDMS เพื่อตรวจสอบว่ากิจกรรมใดของคุณถูกทิ้งโดยระบบ แต่ฉันเดาว่าระบบจะทำลายระบบที่เก่าแก่ที่สุดก่อน อย่างไรก็ตามมันไม่ใช่ประเด็นที่จะเก็บกิจกรรมอื่น ๆ ไว้เมื่อ "กิจกรรมเปิดตัว" ถูกนำกลับมาใช้ใหม่

UPDATE

นี่คือความคิดเห็นบางส่วนที่ฉันพบจากที่นี่ :

สถานะหยุด

เมื่อมองไม่เห็นกิจกรรม แต่ยังอยู่ในความทรงจำเราจะบอกว่าอยู่ในสถานะหยุดทำงาน กิจกรรมที่หยุดแล้วสามารถนำกลับมาที่ด้านหน้าเพื่อเป็นกิจกรรมวิ่งได้อีกครั้ง หรืออาจถูกทำลายและลบออกจากความทรงจำ

ระบบช่วยให้กิจกรรมต่างๆอยู่ในสถานะหยุดทำงานเนื่องจากมีแนวโน้มว่าผู้ใช้จะยังคงต้องการกลับไปที่กิจกรรมเหล่านั้นในเร็ว ๆ นี้และการเริ่มต้นกิจกรรมที่หยุดใหม่นั้นถูกกว่าการเริ่มต้นกิจกรรมตั้งแต่ต้น นั่นเป็นเพราะเรามีวัตถุทั้งหมดที่โหลดไว้ในหน่วยความจำอยู่แล้วและเพียงแค่ต้องนำมันทั้งหมดมาไว้ที่พื้นหน้า

กิจกรรมที่หยุดอยู่สามารถลบออกจากหน่วยความจำได้ทุกเมื่อ


4
เอกสารประกอบค่อนข้างสับสนในประเด็นนี้อย่างไรก็ตามมีเพียงกระบวนการทั้งหมดเท่านั้นที่สามารถฆ่าได้ไม่ใช่ส่วนประกอบแต่ละส่วน (กิจกรรมบริการ ฯลฯ ) ดู: stackoverflow.com/questions/7536988/…
greg7gkb

คำถามนี้ควรได้รับการอัปเดตด้วยข้อมูลในลิงก์ของความคิดเห็น @ greg7gkb ซึ่งทำให้เข้าใจผิด
Luke De Feo

1

ระบบสามารถทำลายกิจกรรมเพียงอย่างเดียวหรือบางส่วนเพื่อกู้คืนหน่วยความจำได้หรือไม่?

ใช่. Android ฆ่ากิจกรรมที่ทำงานอยู่เบื้องหลังเมื่อจำเป็นต้องใช้หน่วยความจำ การฆ่าหนึ่งหรือทั้งหมดอาจขึ้นอยู่กับเงื่อนไขบางประการ สำหรับอินสแตนซ์ที่หยุดชั่วคราวหรือหยุดสามารถทำให้ Android ฆ่ากิจกรรมหรือกระบวนการได้เอง ที่นี่ภายใต้วงจรชีวิตของกิจกรรมคุณจะได้รับคะแนนด้านล่าง ขอแนะนำให้คุณอ่านหน้านั้นให้ครบถ้วน จะคลายข้อสงสัยของคุณได้อย่างแน่นอน

หากกิจกรรมสูญเสียโฟกัส แต่ยังมองเห็นได้ (นั่นคือกิจกรรมใหม่ที่ไม่ใช่ขนาดเต็มหรือโปร่งใสเน้นที่กิจกรรมของคุณ) กิจกรรมนั้นจะหยุดชั่วคราว กิจกรรมที่หยุดชั่วคราวยังคงมีชีวิตอยู่อย่างสมบูรณ์ (จะรักษาข้อมูลสถานะและข้อมูลสมาชิกทั้งหมดและยังคงติดอยู่กับตัวจัดการหน้าต่าง) แต่ระบบสามารถฆ่าได้ในสถานการณ์ที่หน่วยความจำเหลือน้อยมาก

หากกิจกรรมอื่นถูกบดบังโดยสิ้นเชิงกิจกรรมนั้นจะหยุดลง มันยังคงรักษาข้อมูลสถานะและข้อมูลสมาชิกทั้งหมดไว้อย่างไรก็ตามผู้ใช้ไม่สามารถมองเห็นได้อีกต่อไปดังนั้นหน้าต่างจึงถูกซ่อนไว้และมักจะถูกฆ่าโดยระบบเมื่อต้องการหน่วยความจำที่อื่น

หากกิจกรรมถูกหยุดชั่วคราวหรือหยุดระบบสามารถยกเลิกกิจกรรมจากหน่วยความจำได้โดยขอให้กิจกรรมนั้นเสร็จสิ้นหรือเพียงแค่ฆ่ากระบวนการ เมื่อแสดงต่อผู้ใช้อีกครั้งจะต้องเริ่มต้นใหม่ทั้งหมดและเรียกคืนสู่สถานะก่อนหน้า


ระบบจะฆ่ากระบวนการทั้งหมดของแอปพลิเคชันของฉันหรือไม่ กิจกรรมทั้งหมดจะถูกทำลายลงหรือไม่?

กิจกรรมเกี่ยวข้องกับแต่ละบุคคลในขณะที่กระบวนการเกี่ยวข้องกับกลุ่มของกิจกรรม ดูจุดที่สามด้านบนอีกครั้งว่าจะฆ่ากระบวนการดังกล่าว


จะเกิดอะไรขึ้นเมื่อฉันกลับไปที่แอปพลิเคชันของฉันเมื่อมันถูกฆ่าทั้งหมด?

คล้ายกับการรีสตาร์ท อีกครั้งจุดที่สามจะให้คำตอบเช่นWhen it is displayed again to the user, it must be completely restarted and restored to its previous state

ได้รับข้อมูลบางอย่างเพิ่มเติมเกี่ยวกับวัตถุดิบที่เกี่ยวข้องกับหน่วยความจำที่นี่

แก้ไข:
กิจกรรมทั้งหมดในแอปพลิเคชันทำงานในกระบวนการเดียว ดังนั้นเมื่อกระบวนการถูกฆ่ากิจกรรมทั้งหมดไม่ว่า 5 หรือ 10 จะถูกฆ่าเช่นเริ่มต้นใหม่ การรีสตาร์ทจะทำให้แอปพลิเคชันของคุณเริ่มต้นจากจุดเริ่มต้นโดยไม่มีสถานะที่บันทึกไว้


2
ฉันเห็น Activity Lifecycle อย่างน้อย 5 ครั้ง แต่ไม่ตอบคำถามของฉัน สิ่งที่คุณพูดจะหมายถึงเมื่อกระบวนการแอพของฉันถูกฆ่า - เมื่อฉันกลับไปที่แอพมันจะถูกกู้คืนกลับสู่สถานะก่อนหน้า ดังนั้นเมื่อฉันหยุดกิจกรรม 5 ครั้ง .. พวกเขาทั้งหมดตาย (เรียกจาก onDestroy) เมื่อกระบวนการถูกฆ่าหรือไม่? เมื่อฉันกลับไปที่แอปของฉันมีการคืนค่ากิจกรรมทั้งหมด (onCreate + bundle) หรือเพียงรายการเดียวที่อยู่ด้านบนของสแต็ก (ผู้ใช้มองเห็นได้)?
มาร์ค

1
กิจกรรมทั้งหมดในแอปพลิเคชันทำงานในกระบวนการเดียว ดังนั้นเมื่อกระบวนการถูกฆ่ากิจกรรมทั้งหมดไม่ว่า 5 หรือ 10 จะถูกฆ่าเช่นเริ่มต้นใหม่ การรีสตาร์ทจะทำให้แอปพลิเคชันของคุณเริ่มทำงานตั้งแต่ต้นโดยไม่มีสถานะที่บันทึกไว้ ..
Vinay

1
เกือบจะเป็นจริง แต่ไม่ใช่สำหรับ 2.2 ขึ้นไป ดูอัปเดตของฉันที่ด้านบนสุดของหน้า
ทำเครื่องหมาย

1
ไม่นี่ไม่เป็นความจริงและไม่เคยเป็นความจริง มันสับสนตามเอกสาร แต่ดู: stackoverflow.com/questions/7536988/…
greg7gkb

2
@JJPA Android ไม่สามารถทำลายกิจกรรมเดียวเพื่อเรียกคืนหน่วยความจำได้ แต่จะทำลายกระบวนการเท่านั้น ดูคำตอบนี้โดย Dianne Hackbor, Android สมาชิกทีมงานหลักที่เกี่ยวข้องในการ "ออกจากฆาตกรต่อความทรงจำ" การดำเนินงาน: stackoverflow.com/a/7576275/1290264
bcorso
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.