การจัดการวงจรด้วยคอมโพเนนต์ที่รับรู้วงจร   เป็นส่วนหนึ่งของ Android Jetpack

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

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

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

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

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

KotlinJava
internal class MyLocationListener(
        private val context: Context,
        private val callback: (Location) -> Unit
) {

    fun start() {
        // connect to system location service
    }

    fun stop() {
        // disconnect from system location service
    }
}

class MyActivity : AppCompatActivity() {
    private lateinit var myLocationListener: MyLocationListener

    override fun onCreate(...) {
        myLocationListener = MyLocationListener(this) { location ->
            // update UI
        }
    }

    public override fun onStart() {
        super.onStart()
        myLocationListener.start()
        // manage other components that need to respond
        // to the activity lifecycle
    }

    public override fun onStop() {
        super.onStop()
        myLocationListener.stop()
        // manage other components that need to respond
        // to the activity lifecycle
    }
}
class MyLocationListener {
    public MyLocationListener(Context context, Callback callback) {
        // ...
    }

    void start() {
        // connect to system location service
    }

    void stop() {
        // disconnect from system location service
    }
}

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    @Override
    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, (location) -> {
            // update UI
        });
    }

    @Override
    public void onStart() {
        super.onStart();
        myLocationListener.start();
        // manage other components that need to respond
        // to the activity lifecycle
    }

    @Override
    public void onStop() {
        super.onStop();
        myLocationListener.stop();
        // manage other components that need to respond
        // to the activity lifecycle
    }
}

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

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

KotlinJava
class MyActivity : AppCompatActivity() {
    private lateinit var myLocationListener: MyLocationListener

    override fun onCreate(...) {
        myLocationListener = MyLocationListener(this) { location ->
            // update UI
        }
    }

    public override fun onStart() {
        super.onStart()
        Util.checkUserStatus { result ->
            // what if this callback is invoked AFTER activity is stopped?
            if (result) {
                myLocationListener.start()
            }
        }
    }

    public override fun onStop() {
        super.onStop()
        myLocationListener.stop()
    }

}
class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, location -> {
            // update UI
        });
    }

    @Override
    public void onStart() {
        super.onStart();
        Util.checkUserStatus(result -> {
            // what if this callback is invoked AFTER activity is stopped?
            if (result) {
                myLocationListener.start();
            }
        });
    }

    @Override
    public void onStop() {
        super.onStop();
        myLocationListener.stop();
    }
}

แพ็กเกจ androidx.lifecycle มีคลาสและอินเทอร์เฟซที่ช่วยให้คุณจัดการปัญหาเหล่านี้ได้อย่างยืดหยุ่นและแยกส่วน

วงจร

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

Lifecycle ใช้การแจกแจงหลัก 2 รายการเพื่อติดตามสถานะวงจรของลูกค้าสําหรับคอมโพเนนต์ที่เกี่ยวข้อง ดังนี้

กิจกรรม
เหตุการณ์ในวงจรที่ส่งมาจากเฟรมเวิร์กและคลาส Lifecycle เหตุการณ์เหล่านี้จะแมปกับเหตุการณ์ Callback ในกิจกรรมและข้อมูลโค้ด
รัฐ
สถานะปัจจุบันของคอมโพเนนต์ที่ออบเจ็กต์ Lifecycle ติดตาม
รูปที่ 1 สถานะและเหตุการณ์ของวงจรชีวิตของกิจกรรม Android

ให้คิดว่าสถานะเป็นโหนดของกราฟ และเหตุการณ์เป็นขอบระหว่างโหนดเหล่านี้

คลาสสามารถตรวจสอบสถานะวงจรชีวิตของคอมโพเนนต์ได้โดยการใช้ DefaultLifecycleObserver และลบล้างเมธอดที่เกี่ยวข้อง เช่น onCreate, onStart เป็นต้น จากนั้นคุณสามารถเพิ่มผู้สังเกตการณ์ได้โดยเรียกใช้เมธอด addObserver() ของคลาส Lifecycle และส่งอินสแตนซ์ของผู้สังเกตการณ์ ดังที่แสดงในตัวอย่างต่อไปนี้

KotlinJava
class MyObserver : DefaultLifecycleObserver {
    override fun onResume(owner: LifecycleOwner) {
        connect()
    }

    override fun onPause(owner: LifecycleOwner) {
        disconnect()
    }
}

myLifecycleOwner.getLifecycle().addObserver(MyObserver())
public class MyObserver implements DefaultLifecycleObserver {
    @Override
    public void onResume(LifecycleOwner owner) {
        connect()
    }

    @Override
    public void onPause(LifecycleOwner owner) {
        disconnect()
    }
}

myLifecycleOwner.getLifecycle().addObserver(new MyObserver());

ในตัวอย่างข้างต้น ออบเจ็กต์ myLifecycleOwner ใช้อินเทอร์เฟซ LifecycleOwner ซึ่งอธิบายไว้ในส่วนถัดไป

LifecycleOwner

LifecycleOwner เป็นอินเทอร์เฟซเมธอดเดียวที่ระบุว่าคลาสมี Lifecycle โดยจะมีเมธอดเดียว getLifecycle() ซึ่งคลาสต้องนำมาใช้งาน หากต้องการจัดการวงจรของกระบวนการแอปพลิเคชันทั้งหมดแทน โปรดดูProcessLifecycleOwner

อินเทอร์เฟซนี้จะแยกการเป็นเจ้าของ Lifecycle ออกจากคลาสแต่ละคลาส เช่น Fragment และ AppCompatActivity และอนุญาตให้เขียนคอมโพเนนต์ที่ทำงานร่วมกับคลาสเหล่านั้นได้ คลาสแอปพลิเคชันที่กำหนดเองใดๆ สามารถใช้อินเทอร์เฟซ LifecycleOwner ได้

คอมโพเนนต์ที่ใช้ DefaultLifecycleObserver จะทํางานร่วมกับคอมโพเนนต์ที่ใช้ LifecycleOwner ได้อย่างราบรื่น เนื่องจากเจ้าของสามารถระบุวงจรชีวิตของคอมโพเนนต์ ซึ่งผู้สังเกตการณ์สามารถลงทะเบียนเพื่อดูได้

สําหรับตัวอย่างการติดตามตําแหน่ง เราสามารถสร้างคลาส MyLocationListener ให้ใช้งาน DefaultLifecycleObserver แล้วเริ่มต้นด้วย Lifecycle ของกิจกรรมในเมธอด onCreate() วิธีนี้ช่วยให้คลาส MyLocationListener ทำงานได้ด้วยตัวเอง ซึ่งหมายความว่าจะมีการประกาศตรรกะในการตอบสนองต่อการเปลี่ยนแปลงสถานะวงจรใน MyLocationListener แทนกิจกรรม การที่คอมโพเนนต์แต่ละรายการจัดเก็บตรรกะของตนเองจะช่วยให้จัดการตรรกะของกิจกรรมและข้อมูลโค้ดได้ง่ายขึ้น

KotlinJava
class MyActivity : AppCompatActivity() {
    private lateinit var myLocationListener: MyLocationListener

    override fun onCreate(...) {
        myLocationListener = MyLocationListener(this, lifecycle) { location ->
            // update UI
        }
        Util.checkUserStatus { result ->
            if (result) {
                myLocationListener.enable()
            }
        }
    }
}
class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
            // update UI
        });
        Util.checkUserStatus(result -> {
            if (result) {
                myLocationListener.enable();
            }
        });
  }
}

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

คลาส Lifecycle ช่วยให้ออบเจ็กต์อื่นๆ ค้นหาสถานะปัจจุบันได้ เพื่อให้กรณีการใช้งานนี้ง่ายขึ้น

KotlinJava
internal class MyLocationListener(
        private val context: Context,
        private val lifecycle: Lifecycle,
        private val callback: (Location) -> Unit
): DefaultLifecycleObserver {

    private var enabled = false

    override fun onStart(owner: LifecycleOwner) {
        if (enabled) {
            // connect
        }
    }

    fun enable() {
        enabled = true
        if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
            // connect if not connected
        }
    }

    override fun onStop(owner: LifecycleOwner) {
        // disconnect if connected
    }
}
class MyLocationListener implements DefaultLifecycleObserver {
    private boolean enabled = false;
    public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
       ...
    }

    @Override
    public void onStart(LifecycleOwner owner) {
        if (enabled) {
           // connect
        }
    }

    public void enable() {
        enabled = true;
        if (lifecycle.getCurrentState().isAtLeast(STARTED)) {
            // connect if not connected
        }
    }

    @Override
    public void onStop(LifecycleOwner owner) {
        // disconnect if connected
    }
}

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

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

การใช้ LifecycleOwner ที่กําหนดเอง

ส่วนต่างๆ และกิจกรรมใน Support Library 26.1.0 ขึ้นไปใช้อินเทอร์เฟซ LifecycleOwner อยู่แล้ว

หากมีคลาสที่กำหนดเองที่ต้องการสร้าง LifecycleOwner คุณสามารถใช้คลาส LifecycleRegistry แต่ต้องส่งต่อเหตุการณ์ไปยังคลาสนั้น ดังที่แสดงในตัวอย่างโค้ดต่อไปนี้

KotlinJava
class MyActivity : Activity(), LifecycleOwner {

    private lateinit var lifecycleRegistry: LifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleRegistry = LifecycleRegistry(this)
        lifecycleRegistry.markState(Lifecycle.State.CREATED)
    }

    public override fun onStart() {
        super.onStart()
        lifecycleRegistry.markState(Lifecycle.State.STARTED)
    }

    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }
}
public class MyActivity extends Activity implements LifecycleOwner {
    private LifecycleRegistry lifecycleRegistry;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        lifecycleRegistry = new LifecycleRegistry(this);
        lifecycleRegistry.markState(Lifecycle.State.CREATED);
    }

    @Override
    public void onStart() {
        super.onStart();
        lifecycleRegistry.markState(Lifecycle.State.STARTED);
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return lifecycleRegistry;
    }
}

แนวทางปฏิบัติแนะนำสำหรับคอมโพเนนต์ที่รับรู้วงจรของลูกค้า

  • ควบคุม UI (กิจกรรมและส่วนต่างๆ) ให้น้อยที่สุดเท่าที่เป็นไปได้ โดยไม่ควรพยายามรวบรวมข้อมูลของตนเอง แต่ให้ใช้ ViewModel แทน และสังเกตออบเจ็กต์ LiveData เพื่อแสดงการเปลี่ยนแปลงในมุมมอง
  • ลองเขียน UI ที่ขับเคลื่อนโดยข้อมูลโดยที่ความรับผิดชอบของเครื่องมือควบคุม UI คืออัปเดตมุมมองเมื่อข้อมูลมีการเปลี่ยนแปลง หรือแจ้งการดําเนินการของผู้ใช้กลับไปยัง ViewModel
  • ใส่ตรรกะข้อมูลในคลาส ViewModel ViewModel ควรทำหน้าที่เป็นเครื่องมือเชื่อมต่อระหว่างตัวควบคุม UI กับส่วนที่เหลือของแอป แต่โปรดทราบว่า ViewModel ไม่ได้มีหน้าที่ดึงข้อมูล (เช่น จากเครือข่าย) แต่ViewModel ควรเรียกใช้คอมโพเนนต์ที่เหมาะสมเพื่อดึงข้อมูล แล้วส่งผลลัพธ์กลับไปยังตัวควบคุม UI
  • ใช้การเชื่อมโยงข้อมูลเพื่อรักษาอินเทอร์เฟซที่เรียบร้อยระหว่างมุมมองกับตัวควบคุม UI ซึ่งช่วยให้คุณทำให้มุมมองเป็นแบบประกาศมากขึ้นและลดโค้ดการอัปเดตที่ต้องเขียนในกิจกรรมและข้อมูลโค้ดได้ หากต้องการดำเนินการนี้ในภาษาโปรแกรม Java ให้ใช้ไลบรารีอย่าง Butter Knife เพื่อหลีกเลี่ยงโค้ดที่ซ้ำกันและมีการสร้างแบบนามธรรมที่ดียิ่งขึ้น
  • หาก UI มีความซับซ้อน ให้พิจารณาสร้างคลาส presenter เพื่อจัดการการแก้ไข UI งานนี้อาจทําได้ยาก แต่จะช่วยให้ทดสอบคอมโพเนนต์ UI ได้ง่ายขึ้น
  • หลีกเลี่ยงการอ้างอิงบริบท View หรือ Activity ใน ViewModel หาก ViewModel มีอายุมากกว่ากิจกรรม (ในกรณีที่มีการเปลี่ยนแปลงการกําหนดค่า) กิจกรรมจะรั่วไหลและระบบเก็บขยะจะไม่จัดการอย่างถูกต้อง
  • ใช้ Kotlin coroutine เพื่อจัดการงานที่ทำงานต่อเนื่องเป็นเวลานานและการดำเนินการอื่นๆ ที่ทำงานแบบไม่พร้อมกันได้

Use Case สําหรับคอมโพเนนต์ที่ทราบวงจร

คอมโพเนนต์ที่รับรู้วงจรช่วยให้คุณจัดการวงจรได้ง่ายขึ้นอย่างมากในหลายกรณี ตัวอย่างบางส่วนมีดังนี้

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

การจัดการเหตุการณ์หยุด

เมื่อ Lifecycle เป็นของ AppCompatActivity หรือ Fragment สถานะของ Lifecycle จะเปลี่ยนเป็น CREATED และระบบจะส่งเหตุการณ์ ON_STOP เมื่อมีการเรียก onSaveInstanceState() ของ AppCompatActivity หรือ Fragment

เมื่อบันทึกสถานะของ Fragment หรือ AppCompatActivity ผ่าน onSaveInstanceState() ระบบจะถือว่า UI ของ Fragment หรือ AppCompatActivity นั้นเปลี่ยนแปลงไม่ได้จนกว่าจะเรียกใช้ ON_START การพยายามแก้ไข UI หลังจากบันทึกสถานะแล้วมีแนวโน้มที่จะทําให้สถานะการนําทางของแอปพลิเคชันไม่สอดคล้องกัน ด้วยเหตุนี้ FragmentManager จึงแสดงข้อยกเว้นหากแอปเรียกใช้ FragmentTransaction หลังจากบันทึกสถานะแล้ว ดูรายละเอียดได้ที่ commit()

LiveData ป้องกันกรณีขอบเขตนี้ตั้งแต่เริ่มต้นโดยงดเรียกใช้ผู้สังเกตการณ์หาก Lifecycle ที่เชื่อมโยงของผู้สังเกตการณ์มีค่าไม่น้อยกว่า STARTED เบื้องหลังคือมีการเรียกใช้ isAtLeast() ก่อนตัดสินใจเรียกใช้ผู้สังเกตการณ์

ขออภัย วิธีการ onStop() ของ AppCompatActivity เรียกว่า after onSaveInstanceState() ซึ่งทำให้เกิดช่องว่างที่ไม่อนุญาตให้มีการเปลี่ยนแปลงสถานะของ UI แต่ Lifecycle ยังไม่ได้ย้ายไปยังสถานะ CREATED

เพื่อป้องกันปัญหานี้ คลาส Lifecycle ในเวอร์ชัน beta2 และต่ำกว่าจะทําเครื่องหมายสถานะเป็น CREATED โดยไม่มีการส่งเหตุการณ์เพื่อให้โค้ดที่ตรวจสอบสถานะปัจจุบันได้รับค่าจริง แม้ว่าระบบจะไม่ส่งเหตุการณ์จนกว่าจะมีการเรียกใช้ onStop()

แต่วิธีนี้มีปัญหาสำคัญ 2 ข้อ ได้แก่

  • ใน API ระดับ 23 และต่ำกว่า ระบบ Android จะบันทึกสถานะของกิจกรรมแม้ว่ากิจกรรมนั้นจะได้รับบางส่วนจากกิจกรรมอื่นก็ตาม กล่าวคือ ระบบ Android จะเรียก onSaveInstanceState() แต่ไม่จำเป็นต้องเรียก onStop() ซึ่งอาจทำให้เกิดช่วงเวลาที่นานที่ผู้สังเกตการณ์ยังคงคิดว่าวงจรยังมีการใช้งานอยู่ แม้ว่าจะไม่สามารถแก้ไขสถานะ UI ของวงจรได้ก็ตาม
  • คลาสที่ต้องการแสดงลักษณะการทำงานที่คล้ายกับคลาส LiveData ต้องใช้วิธีแก้ปัญหาที่ระบุโดย Lifecycle เวอร์ชัน beta 2 และต่ำกว่า

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการวงจรด้วยคอมโพเนนต์ที่รับรู้วงจรได้จากแหล่งข้อมูลเพิ่มเติมต่อไปนี้

ตัวอย่าง

  • Sunflower เป็นแอปสาธิตที่แสดงแนวทางปฏิบัติแนะนำเกี่ยวกับคอมโพเนนต์สถาปัตยกรรม

Codelabs

บล็อก

ใช้ LiveData เพื่อจัดการข้อมูลตามวงจรชีวิต

อัปเดตแล้ว Dec 22, 2024

Discover the latest app development tools, platform updates, training, and documentation for developers across every Android device.

อัปเดตแล้ว Aug 23, 2024

โมดูลสำหรับการจัดการสถานะที่บันทึกไว้ในออบเจ็กต์ ViewModel

อัปเดตแล้ว Feb 4, 2025