การทำงานต่างๆ ของระบบ Android อาจส่งผลต่อสถานะของส่วนย่อยได้ เฟรมเวิร์ก Android โดยอัตโนมัติเพื่อให้แน่ใจว่าระบบจะบันทึกสถานะของผู้ใช้ บันทึกและกู้คืนส่วนย่อยและแบ็กสแต็ก คุณจึงต้อง เพื่อให้แน่ใจว่าได้บันทึกและคืนค่าข้อมูลในส่วนนั้นแล้ว
ตารางต่อไปนี้จะสรุปการดำเนินการที่ทำให้ส่วนย่อยของคุณสูญหาย รวมทั้งสถานะประเภทต่างๆ จะคงอยู่ผ่านสถานะ การเปลี่ยนแปลง ประเภทรัฐที่ระบุในตารางมีดังนี้
- ตัวแปร: ตัวแปรภายในส่วนย่อย
- สถานะข้อมูลพร็อพเพอร์ตี้: ข้อมูลที่เป็นเจ้าของโดยข้อมูลพร็อพเพอร์ตี้อย่างน้อย 1 รายการในส่วนย่อย
- SaveState: ข้อมูลที่มีอยู่ในอินสแตนซ์ Fragment นี้ที่ควรบันทึก
ใน
onSaveInstanceState()
- NonConfig: ข้อมูลที่ดึงมาจากแหล่งที่มาภายนอก เช่น เซิร์ฟเวอร์หรือในเครื่อง ของที่เก็บ หรือข้อมูลที่สร้างโดยผู้ใช้ซึ่งส่งไปยังเซิร์ฟเวอร์เมื่อคอมมิตแล้ว
บ่อยครั้งที่ตัวแปรจะได้รับการดำเนินการเหมือนกับ SavedState แต่ ตารางต่อไปนี้จะแยกความแตกต่างระหว่างทั้ง 2 ตารางเพื่อแสดงผลกระทบ ของการดำเนินการต่างๆ ในแต่ละรายการ
การดำเนินการ | ตัวแปร | สถานะข้อมูลพร็อพเพอร์ตี้ | สถานะที่บันทึกไว้ | ไม่มีการกำหนดค่า |
---|---|---|---|---|
เพิ่มไปยังแบ็กสแต็กแล้ว | ✓ | ✓ | x | ✓ |
เปลี่ยนการกำหนดค่า | x | ✓ | ✓ | ✓ |
การเสียชีวิตจากกระบวนการ/สันทนาการ | x | ✓ | ✓ | ✓* |
นำออกแล้วไม่ได้เพิ่มในกองหลัง | x | x | x | x |
โฮสต์เสร็จสิ้นแล้ว | x | x | x | x |
* สามารถเก็บรักษาสถานะ NonConfig ไว้ตลอดกระบวนการทำงานได้โดยใช้ โมดูลสถานะที่บันทึกไว้สำหรับ ViewModel
ตาราง 1: การดำเนินการทำลายส่วนย่อยต่างๆ และผลกระทบ ที่มีต่อรัฐประเภทต่างๆ
เรามาดูตัวอย่างที่เจาะจงกัน ลองพิจารณาหน้าจอที่สร้าง
สตริงแบบสุ่ม แสดงใน TextView
และมีตัวเลือกในการแก้ไข
ก่อนส่งให้เพื่อน:
สำหรับตัวอย่างนี้ สมมติว่าเมื่อผู้ใช้กดปุ่มแก้ไข
แอปจะแสดงมุมมอง EditText
ซึ่งผู้ใช้สามารถแก้ไขข้อความได้ หาก
ผู้ใช้คลิกยกเลิก ระบบจะล้างข้อมูลพร็อพเพอร์ตี้ EditText
และ
ตั้งค่าระดับการเข้าถึงเป็น View.GONE
เช่น
หน้าจออาจจำเป็นต้องจัดการข้อมูล 4 ส่วนเพื่อให้
:
ข้อมูล | ประเภท | ประเภทรัฐ | คำอธิบาย |
---|---|---|---|
seed |
Long |
ไม่มีการกำหนดค่า | เมล็ดที่ใช้สำหรับการสุ่มสร้างการกระทำดีใหม่ สร้างขึ้นเมื่อ
สร้าง ViewModel แล้ว |
randomGoodDeed |
String |
SaveState + ตัวแปร | สร้างขึ้นเมื่อสร้างส่วนย่อยเป็นครั้งแรก
ระบบจะบันทึก randomGoodDeed ไว้เพื่อให้ผู้ใช้เห็น
การกระทำดีซ้ำๆ เดิมๆ แม้จะเสียชีวิตไปแล้ว และ
นันทนาการ |
isEditing |
Boolean |
SaveState + ตัวแปร | ตั้งค่าแฟล็กบูลีนเป็น true เมื่อผู้ใช้เริ่มแก้ไข
isEditing ได้รับการบันทึกเพื่อให้แน่ใจว่าส่วนการแก้ไขของ
หน้าจอจะยังมองเห็นได้เมื่อสร้างส่วนย่อยใหม่ |
ข้อความที่แก้ไข | Editable |
สถานะข้อมูลพร็อพเพอร์ตี้ (เป็นเจ้าของโดย EditText ) |
ข้อความที่แก้ไขในมุมมอง EditText
มุมมอง EditText จะบันทึกข้อความนี้เพื่อให้ข้อความ
การเปลี่ยนแปลงที่อยู่ระหว่างดำเนินการจะไม่สูญหาย |
ตารางที่ 2: ระบุว่าแอปสร้างข้อความแบบสุ่มต้องจัดการ
ส่วนต่อไปนี้จะอธิบายวิธีจัดการสถานะข้อมูลอย่างเหมาะสม ผ่านการดำเนินการทำลายล้าง
ดูสถานะ
ยอดดูจะรับผิดชอบในการจัดการสถานะของตนเอง ตัวอย่างเช่น เมื่อ
มุมมองยอมรับข้อมูลจากผู้ใช้ มุมมองนี้จะมีหน้าที่รับผิดชอบในการบันทึกและคืนค่า
อินพุตดังกล่าวเพื่อจัดการกับการเปลี่ยนแปลงการกำหนดค่า จากเฟรมเวิร์กของ Android ทั้งหมด
มีการใช้ onSaveInstanceState()
และ
onRestoreInstanceState()
คุณจึงไม่ต้องจัดการสถานะการดูภายใน
ส่วนย่อยของคุณ
ตัวอย่างเช่น ในสถานการณ์ก่อนหน้านี้ สตริงที่แก้ไขจะถูกเก็บไว้ใน
EditText
EditText
รู้
ค่าของข้อความที่แสดง รวมถึงรายละเอียดอื่นๆ เช่น
จุดเริ่มต้นและจุดสิ้นสุดของข้อความที่เลือก
ข้อมูลพร็อพเพอร์ตี้จำเป็นต้องมีรหัสเพื่อคงสถานะไว้ รหัสนี้ต้องไม่ซ้ำกันภายใน และลำดับชั้นของมุมมอง ข้อมูลพร็อพเพอร์ตี้ที่ไม่มีรหัสไม่สามารถเก็บข้อมูลได้ ถึงรัฐนั้น
<EditText android:id="@+id/good_deed_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" />
ดังที่ได้กล่าวไว้ในตาราง 1 การดูบันทึกและคืนค่า ViewState
ผ่าน
การดำเนินการทั้งหมดที่ไม่นำส่วนย่อยออกหรือทำลายโฮสต์
SavedState
ส่วนย่อยของคุณมีหน้าที่จัดการสถานะแบบไดนามิกจำนวนเล็กน้อย
ที่เป็นส่วนประกอบสำคัญในการทำงานของส่วนย่อย คุณสามารถเก็บรักษา
ข้อมูลที่จัดเรียงได้ง่ายโดยใช้
Fragment.onSaveInstanceState(Bundle)
คล้ายกับ
Activity.onSaveInstanceState(Bundle)
ระบบจะเก็บรักษาข้อมูลที่คุณใส่ไว้ในแพ็กเกจผ่านการเปลี่ยนแปลงการกำหนดค่า
และการประมวลการเสียชีวิตและการนันทนาการ และมีอยู่ใน
onCreate(Bundle)
,
onCreateView(LayoutInflater, ViewGroup, Bundle)
,
และ
onViewCreated(View, Bundle)
ต่อจากตัวอย่างก่อนหน้านี้ randomGoodDeed
คือหนังสือสำคัญที่
แสดงแก่ผู้ใช้ และ isEditing
คือธงเพื่อระบุว่า
ส่วนย่อยจะแสดงหรือซ่อน EditText
สถานะที่บันทึกไว้นี้ควรเป็น
ยังคงใช้ onSaveInstanceState(Bundle)
ดังที่แสดงใน
ตัวอย่าง:
Kotlin
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putBoolean(IS_EDITING_KEY, isEditing) outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed) }
Java
@Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(IS_EDITING_KEY, isEditing); outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed); }
หากต้องการคืนค่าสถานะใน onCreate(Bundle)
ให้เรียกค่าที่จัดเก็บไว้จาก
แพ็กเกจนั้น:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) isEditing = savedInstanceState?.getBoolean(IS_EDITING_KEY, false) randomGoodDeed = savedInstanceState?.getString(RANDOM_GOOD_DEED_KEY) ?: viewModel.generateRandomGoodDeed() }
Java
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { isEditing = savedInstanceState.getBoolean(IS_EDITING_KEY, false); randomGoodDeed = savedInstanceState.getString(RANDOM_GOOD_DEED_KEY); } else { randomGoodDeed = viewModel.generateRandomGoodDeed(); } }
ดังที่กล่าวไว้ในตาราง 1 โปรดทราบว่าระบบจะเก็บรักษาตัวแปรไว้เมื่อ จะวางอยู่บนแบ็กสแต็ก การจัดการเป็นสถานะที่บันทึกไว้ช่วยให้มั่นใจได้ว่า มันจะคงอยู่ตลอดไปในขั้นตอนการทำลายล้าง
ไม่มีการกำหนดค่า
ข้อมูล NonConfig ควรวางไว้นอกส่วนย่อยของคุณ เช่น
ViewModel
ก่อนหน้านี้
ตัวอย่างข้างต้น seed
(สถานะ NonConfig) จะสร้างขึ้นใน ViewModel
ตรรกะในการรักษาสถานะเป็นของ ViewModel
Kotlin
public class RandomGoodDeedViewModel : ViewModel() { private val seed = ... // Generate the seed private fun generateRandomGoodDeed(): String { val goodDeed = ... // Generate a random good deed using the seed return goodDeed } }
Java
public class RandomGoodDeedViewModel extends ViewModel { private Long seed = ... // Generate the seed private String generateRandomGoodDeed() { String goodDeed = ... // Generate a random good deed using the seed return goodDeed; } }
คลาส ViewModel
อนุญาตให้ข้อมูลผ่านการกำหนดค่าโดยปกติ
เช่น การหมุนหน้าจอ และยังคงอยู่ในหน่วยความจำเมื่อ
แฟรกเมนต์จะอยู่บนสแต็กด้านหลัง หลังกระบวนการเสียชีวิตและนันทนาการ
ระบบจะสร้าง ViewModel
ขึ้นใหม่ และจะสร้าง seed
ใหม่ การเพิ่ม
โมดูล SavedState
ลงใน ViewModel
จะอนุญาตให้ ViewModel
เก็บสถานะแบบง่ายผ่าน
กระบวนการตายและสันทนาการ
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการสถานะส่วนย่อยได้ที่ แหล่งข้อมูลเพิ่มเติม
Codelab
- Codelab ของคอมโพเนนต์ Context-Aware