วงจรชีวิตของวัตถุคงที่ของ Android


101

ฉันกำลังสร้างแอปพลิเคชันการค้นหาเหตุการณ์เราตั้งเกณฑ์การค้นหาจากหน้าจอหนึ่งเติมในหน้าจออื่นจากนั้นผู้ใช้สามารถแก้ไขเกณฑ์การค้นหาจากหน้าจอที่ 3 และไปที่หน้าจอที่ 4

เพื่อให้บรรลุภารกิจข้างต้นฉันใช้วัตถุคงที่ซึ่งจำค่ารอบ ๆ แอปพลิเคชันและฉันไม่จำเป็นต้องทำอะไรเพิ่มเติม

แต่ฉันกลัวถ้าเกี่ยวกับวงจรชีวิตของวัตถุคงที่ใน Android หากหน่วยความจำต่ำพบว่า android ลบวัตถุคงที่ ???

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

คำตอบ:


239

เริ่มต้นด้วยพื้นหลังเล็กน้อย: จะเกิดอะไรขึ้นเมื่อคุณเริ่มแอปพลิเคชัน
ระบบปฏิบัติการเริ่มต้นกระบวนการและกำหนดรหัสกระบวนการที่ไม่ซ้ำกันและจัดสรรตารางกระบวนการกระบวนการเริ่มต้นอินสแตนซ์ของ DVM (Dalvik VM) แต่ละแอปพลิเคชันทำงานภายใน DVM
DVM จัดการการขนถ่ายคลาสวงจรชีวิตของอินสแตนซ์ GC เป็นต้น

อายุการใช้งานของตัวแปรแบบคงที่: ตัวแปรคงที่เกิดขึ้นเมื่อคลาสถูกโหลดโดย JVM และตายเมื่อคลาสถูกยกเลิกการโหลด

ดังนั้นหากคุณสร้างแอปพลิเคชัน Android และเริ่มต้นตัวแปรแบบคงที่มันจะยังคงอยู่ใน JVM จนกว่าจะเกิดเหตุการณ์ใดสิ่งหนึ่งต่อไปนี้:
1. คลาสถูกยกเลิกการโหลด
2. JVM ปิดตัวลง
3. กระบวนการตาย

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

คุณสามารถทดสอบได้โดยใช้โค้ดสองสามบรรทัด:

  1. พิมพ์แบบคงที่ที่ไม่ได้เริ่มต้นใน onCreate of your activity -> ควรพิมพ์ null
  2. เริ่มต้นคงที่ พิมพ์ -> ค่าจะไม่เป็นโมฆะ
  3. กดปุ่มย้อนกลับและไปที่หน้าจอหลัก หมายเหตุ: หน้าจอหลักเป็นกิจกรรมอื่น
  4. เปิดกิจกรรมของคุณอีกครั้ง -> ตัวแปรคงที่จะไม่เป็นค่าว่าง
  5. ฆ่าขั้นตอนการสมัครของคุณจาก DDMS (ปุ่มหยุดในหน้าต่างอุปกรณ์)
  6. รีสตาร์ทกิจกรรมของคุณ -> คงที่จะมีค่าว่าง

หวังว่าจะช่วยได้


1
ฉันต้องการทราบว่าเหตุใดฉันจึงสูญเสียค่าฟิลด์ในแอ็พพลิเคชันอ็อบเจ็กต์หากไม่คงที่เมื่อฉันเริ่มกิจกรรมใหม่เช่นฉันประกาศเพจปัจจุบันของตัวแปรในอ็อบเจ็กต์แอปพลิเคชันและค่าของมันจะกลับเป็นศูนย์เสมอเมื่อฉันเปิดกิจกรรมใหม่
Mohammed Subhi Sheikh Quroush

เมื่อฉันเรียก super.onRestoreInstanceState (saveInstanceState); ฉันสูญเสียตัวแปรแม้ว่าจะเป็นแบบคงที่ปัญหาคืออะไร?
Mohammed Subhi Sheikh Quroush

1
นี่เป็นคำอธิบายที่ดี (ไม่ใช่ -1) แต่มันไม่สำคัญเล็กน้อย: OP ถามอย่างชัดเจนเกี่ยวกับ "สถานการณ์หน่วยความจำต่ำ" (เหตุผลเดียวกับที่ฉันมาที่นี่) ซึ่งเท่าที่ฉันรู้ว่าระบบปฏิบัติการอาจฆ่า VM และ เริ่มต้นใหม่ในภายหลังด้วยพารามิเตอร์เดียวกันและกรณีนี้ ( ถ้าเป็นของจริง) จะไม่ครอบคลุมที่นี่ ...
Rick77

1
@suitianshi ฉันคิดว่าเราสามารถเริ่มต้นอินสแตนซ์แบบคงที่ใน Application.onCreate ได้เพราะแม้ว่าแอปของเราจะเข้าสู่พื้นหลังและกระบวนการจะถูกฆ่าทันทีที่เรากลับไปที่แอปของเราคลาสแอปพลิเคชันจะได้รับการสร้างอินสแตนซ์และเรียกมันว่าเป็นวิธีวงจรชีวิตที่สอดคล้องกัน อีกแล้ว! แม้ว่าฉันต้องการการยืนยันในเรื่องนี้ แต่ฉันสงสัยว่าอาจมีสถานการณ์ใดบ้างที่อินสแตนซ์แบบคงที่เริ่มต้นใน Application.onCreate สูญเสียมูลค่าหรือไม่
Sarthak Mittal

1
สิ่งที่ฉันขาดหายไปนี้คือคำอธิบายสำหรับ "1. ชั้นเรียนถูกยกเลิกการโหลด" - จะเกิดขึ้นเมื่อใด JVM จะยกเลิกการโหลดคลาสหรือไม่หากหน่วยความจำเหลือน้อย
stoefln

16

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

  • โดยใช้ Intent คุณสามารถส่งผ่านเกณฑ์การค้นหาของคุณจากกิจกรรมไปยังกิจกรรม (คล้ายกับคำขอ http ของเว็บ)
  • โดยใช้การตั้งค่าแอปพลิเคชันคุณสามารถบันทึกค่าและเรียกดูในกิจกรรมที่ต้องการได้
  • การใช้ฐานข้อมูล sqlite คุณสามารถคงอยู่ในตารางและเรียกดูได้ในภายหลัง
  • หากคุณต้องการเพียงแค่บันทึกสถานะกิจกรรมเพื่อให้ในการรีสตาร์ทฟิลด์จะเต็มไปด้วยค่าที่เลือกไว้ก่อนหน้านี้คุณสามารถใช้เมธอดกิจกรรม onSaveInstanceState () ได้ - โปรดทราบว่าไม่แนะนำให้ใช้ระหว่างกิจกรรมที่ยังคงอยู่ของสถานะ

คุณสามารถรับตัวอย่างโค้ดบางส่วนของการใช้ค่ากำหนดความตั้งใจและฐานข้อมูล sqlite ได้โดยดูที่โครงสร้างซอร์สโค้ด aegis-shieldในโค้ดของ Google หรือในแอปพลิเคชัน Android แบบโอเพนซอร์สอื่น ๆ


6

หลังจากการวิจัยบางส่วนปรากฎว่าการใช้แอปพลิเคชันเพื่อจัดเก็บเสื้อกล้ามไม่ใช่ความคิดที่ยอดเยี่ยมเว้นแต่คุณจะพร้อมที่จะสร้างขึ้นใหม่:

อย่าเก็บข้อมูลไว้ในวัตถุแอปพลิเคชัน

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

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


3

@ r1k0 อยู่ค่ะ การจัดเก็บข้อมูลในเขตข้อมูลคงที่ของคลาสจะไม่คงอยู่ในตัวเองในกระบวนการแอปพลิเคชันจะฆ่าและรีสตาร์ท Android มักฆ่ากระบวนการ (ที่เรียกใช้แอป) เมื่อต้องการหน่วยความจำ

ต่อ doc Android: กิจกรรมรัฐและออกจากหน่วยความจำ ,

ระบบจะไม่ฆ่ากิจกรรมโดยตรง แต่จะฆ่ากระบวนการที่กิจกรรมดำเนินไปโดยไม่เพียง แต่ทำลายกิจกรรมเท่านั้น แต่ยังทำลายทุกอย่างที่กำลังดำเนินอยู่ในกระบวนการด้วย

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

protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.