การบันทึกสถานะด้วยส่วนย่อย

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

ตารางต่อไปนี้จะสรุปการดำเนินการที่ทำให้ส่วนย่อยของคุณสูญหาย รวมทั้งสถานะประเภทต่างๆ จะคงอยู่ผ่านสถานะ การเปลี่ยนแปลง ประเภทรัฐที่ระบุในตารางมีดังนี้

  • ตัวแปร: ตัวแปรภายในส่วนย่อย
  • สถานะข้อมูลพร็อพเพอร์ตี้: ข้อมูลที่เป็นเจ้าของโดยข้อมูลพร็อพเพอร์ตี้อย่างน้อย 1 รายการในส่วนย่อย
  • SaveState: ข้อมูลที่มีอยู่ในอินสแตนซ์ Fragment นี้ที่ควรบันทึก ใน onSaveInstanceState()
  • NonConfig: ข้อมูลที่ดึงมาจากแหล่งที่มาภายนอก เช่น เซิร์ฟเวอร์หรือในเครื่อง ของที่เก็บ หรือข้อมูลที่สร้างโดยผู้ใช้ซึ่งส่งไปยังเซิร์ฟเวอร์เมื่อคอมมิตแล้ว

บ่อยครั้งที่ตัวแปรจะได้รับการดำเนินการเหมือนกับ SavedState แต่ ตารางต่อไปนี้จะแยกความแตกต่างระหว่างทั้ง 2 ตารางเพื่อแสดงผลกระทบ ของการดำเนินการต่างๆ ในแต่ละรายการ

การดำเนินการ ตัวแปร สถานะข้อมูลพร็อพเพอร์ตี้ สถานะที่บันทึกไว้ ไม่มีการกำหนดค่า
เพิ่มไปยังแบ็กสแต็กแล้ว x
เปลี่ยนการกำหนดค่า x
การเสียชีวิตจากกระบวนการ/สันทนาการ x ✓*
นำออกแล้วไม่ได้เพิ่มในกองหลัง x x x x
โฮสต์เสร็จสิ้นแล้ว x x x x

* สามารถเก็บรักษาสถานะ NonConfig ไว้ตลอดกระบวนการทำงานได้โดยใช้ โมดูลสถานะที่บันทึกไว้สำหรับ ViewModel

ตาราง 1: การดำเนินการทำลายส่วนย่อยต่างๆ และผลกระทบ ที่มีต่อรัฐประเภทต่างๆ

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

วันที่ แอปสร้างข้อความแบบสุ่มที่สาธิต
            ประเภทรัฐ
รูปที่ 1 แอปสร้างข้อความแบบสุ่มที่สาธิต ของรัฐประเภทต่างๆ

สำหรับตัวอย่างนี้ สมมติว่าเมื่อผู้ใช้กดปุ่มแก้ไข แอปจะแสดงมุมมอง 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

เส้นนำ