วงจรของ Jetpack Compose ส่วนหนึ่งของ Android Jetpack
คอมโพเนนต์ที่รับรู้ถึงวงจรจะดำเนินการเพื่อตอบสนองต่อการเปลี่ยนแปลง
สถานะวงจรของกิจกรรมโฮสต์ อาร์ติแฟกต์
androidx.lifecycle.compose
มี API เฉพาะที่จะล้างข้อมูลทรัพยากรโดยอัตโนมัติเมื่อทรัพยากร
ออกจากหน้าจอหรือเมื่อแอปพลิเคชันเข้าสู่เบื้องหลัง
API หลักๆ มีดังนี้
- โฟลว์สำหรับ
Lifecycle.Stateปัจจุบัน LifecycleEffectsซึ่งช่วยให้คุณเรียกใช้บล็อกตามLifecycle.Eventที่เฉพาะเจาะจงได้
การผสานรวมเหล่านี้มีฮุกที่สะดวกในการจัดการวงจรภายในลำดับชั้น Compose เอกสารนี้จะอธิบายวิธีใช้ในแอป
รวบรวมสถานะวงจรของลูกค้าด้วยโฟลว์
Lifecycle แสดงพร็อพเพอร์ตี้ currentStateFlow ที่ให้Lifecycle.Stateปัจจุบันเป็น StateFlow ของ Kotlin คุณสามารถรวบรวม Flow นี้เป็นState ซึ่งจะช่วยให้แอปอ่านการเปลี่ยนแปลงในวงจรขององค์ประกอบระหว่างการเขียนได้
val lifecycleOwner = LocalLifecycleOwner.current
val stateFlow = lifecycleOwner.lifecycle.currentStateFlow
…
val currentLifecycleState by stateFlow.collectAsState()
ตัวอย่างก่อนหน้าสามารถเข้าถึงได้โดยใช้โมดูล lifecycle-common เมธอด
currentStateAsState()พร้อมใช้งานในโมดูล lifecycle-runtime-compose
ซึ่งช่วยให้คุณอ่านสถานะ Lifecycle ปัจจุบันได้อย่างสะดวกด้วยโค้ดเพียงบรรทัดเดียว ตัวอย่างต่อไปนี้แสดงให้เห็นถึงเรื่องนี้
val lifecycleOwner = LocalLifecycleOwner.current
val currentLifecycleState = lifecycleOwner.lifecycle.currentStateAsState()
เรียกใช้โค้ดในเหตุการณ์วงจร
แทนที่จะสร้างคลาสแยกต่างหากที่ใช้ DefaultLifecycleObserver และเพิ่มลงในวงจรด้วยตนเอง คุณสามารถประกาศตรรกะวงจรแบบอินไลน์โดยใช้เอฟเฟกต์ที่เฉพาะเจาะจงได้ LifecycleEffects ช่วยให้คุณเรียกใช้บล็อกเมื่อLifecycle.Event ที่เฉพาะเจาะจงเกิดขึ้นภายในคอมโพสิชันโดยตรง
LifecycleEventEffect
ใช้ LifecycleEventEffect เพื่อเรียกใช้บล็อกโค้ด
เมื่อเกิดเหตุการณ์ที่เฉพาะเจาะจง เหมาะที่สุดสำหรับเหตุการณ์แบบครั้งเดียว เช่น การบันทึกหรือการวิเคราะห์ ซึ่งไม่จำเป็นต้องมีผลลัพธ์ที่สำเร็จหรือผลลัพธ์ในทันที
@Composable
fun AnalyticsTracker(screenName: String) {
// Log an event when the app receives ON_RESUME (e.g. comes to foreground)
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
Analytics.logView(screenName)
}
}
LifecycleStartEffect
สำหรับการดำเนินการเริ่ม/หยุดที่จับคู่กันซึ่งต้องเรียกใช้ขณะที่แอปเริ่มต้น
(มองเห็นได้) และล้างข้อมูลเมื่อแอปหยุดทำงาน (ในเบื้องหลัง) ให้ใช้ LifecycleStartEffect
LifecycleStartEffect
ยอมรับคีย์เช่นเดียวกับเอฟเฟกต์ Compose อื่นๆ (เช่น LaunchedEffect) เมื่อคีย์มีการเปลี่ยนแปลง ระบบจะทริกเกอร์ให้บล็อกทำงานอีกครั้ง
เมื่อเกิดเหตุการณ์ Lifecycle.Event.ON_STOP หรือเอฟเฟกต์ออกจาก
คอมโพสิต ระบบจะเรียกใช้บล็อก onStopOrDispose เพื่อล้างข้อมูลใดๆ ที่
เป็นส่วนหนึ่งของบล็อกเริ่มต้น
@Composable
fun LocationMonitor(locationManager: LocationManager) {
// Starts monitoring when ON_START is dispatched
// Stops monitoring when ON_STOP is dispatched
// (or the composable leaves the screen)
LifecycleStartEffect(locationManager) {
val listener = LocationListener { location ->
/* update UI */
}
locationManager.requestLocationUpdates(listener)
// The cleanup block automatically runs on ON_STOP or on disposal
onStopOrDispose {
locationManager.removeUpdates(listener)
}
}
}
ดูข้อมูลเกี่ยวกับผลข้างเคียงประเภทอื่นๆ ได้ที่ผลข้างเคียงใน Compose
LifecycleResumeEffect
LifecycleResumeEffect ทำงานในลักษณะเดียวกับ LifecycleStartEffect
แต่จะเชื่อมโยงกับเหตุการณ์ Lifecycle.Event.ON_RESUME แทน นอกจากนี้ ยังมีonPauseOrDisposeบล็อกที่ทำการล้างข้อมูลเมื่อON_PAUSE ถูกส่ง หรือ Composable ออกจากหน้าจอ
API นี้มีประโยชน์สำหรับทรัพยากรที่ต้องใช้งานเมื่อผู้ใช้ โต้ตอบกับแอปเท่านั้น เช่น กล้องหรือภาพเคลื่อนไหว
@Composable
fun CameraPreview(cameraController: CameraController) {
LifecycleResumeEffect(cameraController) {
cameraController.startPreview()
onPauseOrDispose {
cameraController.stopPreview()
}
}
}
เข้าถึง LifecycleOwner
ใน Compose
LifecycleOwner จะ
พร้อมใช้งานโดยปริยายผ่าน CompositionLocal ที่ชื่อ LocalLifecycleOwner โดย
ค่าเริ่มต้น โฮสต์รูทของลำดับชั้นการเรียบเรียงจะระบุเจ้าของนี้
val lifecycleOwner = LocalLifecycleOwner.current
สำหรับแอปจำนวนมาก การตรวจสอบเจ้าของเริ่มต้นนี้หรือการส่งไปยังเอฟเฟกต์ที่รับรู้ถึงวงจร
ก็เพียงพอแล้ว อย่างไรก็ตาม สำหรับการนำทางที่กำหนดเองหรือเลย์เอาต์ที่ซับซ้อน คุณอาจต้องสร้าง LifecycleOwner ของตัวเองเพื่อกำหนดขอบเขตสถานะวงจรของ
ส่วนที่เฉพาะเจาะจงของ UI ตัวอย่างเช่น ไลบรารีการนำทาง (เช่น Navigation
3) จะดำเนินการนี้โดยอัตโนมัติเพื่อให้แต่ละหน้าจอมีวงจรของตัวเอง
สร้าง LifecycleOwner ที่กำหนดเอง
rememberLifecycleOwner() API ช่วยให้คุณสร้างและจดจำLifecycleOwnerที่กำหนดเองได้ ซึ่งมีประโยชน์อย่างยิ่งสำหรับคอมโพเนนต์อย่างเช่น HorizontalPager ซึ่งคุณต้องการให้เฉพาะหน้าที่มองเห็นและโหลดเสร็จแล้วเป็น RESUMED ขณะตั้งค่า maxState เป็น STARTED สำหรับหน้าที่อยู่ติดกันซึ่งอยู่นอกหน้าจอ
val pagerState = rememberPagerState(pageCount = { 10 })
HorizontalPager(state = pagerState) { pageNum ->
val pageLifecycleOwner = rememberLifecycleOwner(
maxState = if (pagerState.settledPage == pageNum) {
Lifecycle.State.RESUMED
} else {
Lifecycle.State.STARTED
}
)
CompositionLocalProvider(LocalLifecycleOwner provides pageLifecycleOwner) {
// Your pages here. Their lifecycle-aware components respect the
// custom maxState defined above.
}
}
ดูข้อมูลเพิ่มเติมเกี่ยวกับ CompositionLocal ได้ที่ข้อมูลที่กำหนดขอบเขตในเครื่องด้วย
CompositionLocal
แนวทางปฏิบัติแนะนำสำหรับคอมโพเนนต์ที่รับรู้ถึงวงจร
- ทำให้ตัวควบคุม UI มีขนาดเล็กที่สุด โดยไม่ควรพยายามรับข้อมูลของตนเอง แต่ให้ใช้
ViewModelเพื่อดำเนินการดังกล่าว และสังเกตออบเจ็กต์StateFlowเพื่อแสดงการเปลี่ยนแปลงกลับไปยัง UI - พยายามเขียน UI ที่อิงตามข้อมูลซึ่งความรับผิดชอบของตัวควบคุม UI คือการ
อัปเดต UI เมื่อข้อมูลเปลี่ยนแปลง หรือแจ้งการดำเนินการของผู้ใช้กลับไปยัง
ViewModel - วางตรรกะข้อมูลไว้ในคลาส
ViewModelViewModelควรทำหน้าที่เป็นตัวเชื่อมต่อระหว่างตัวควบคุม UI กับส่วนอื่นๆ ของแอป แต่โปรดระวังเนื่องจากViewModelไม่ได้มีหน้าที่ดึงข้อมูล (เช่น จากเครือข่าย) แต่ViewModelควรเรียกใช้คอมโพเนนต์ที่เหมาะสมเพื่อดึงข้อมูล แล้วส่งผลลัพธ์กลับไปยังตัวควบคุม UI - ใช้ Kotlin Coroutines เพื่อจัดการ งานที่ใช้เวลานานและดำเนินการอื่นๆ ที่ทำงานแบบไม่พร้อมกันได้
- เก็บตรรกะการเริ่ม/หยุดไว้ใน Composable ที่ต้องการจริงๆ วิธีนี้จะช่วยให้ระบบนำตรรกะออกโดยอัตโนมัติหากมีการนำองค์ประกอบ UI ที่เฉพาะเจาะจงนั้นออกจากหน้าจอ (เช่น ภายในกราฟการนำทางหรือเมื่อการมองเห็นเป็นแบบมีเงื่อนไข)
- ใช้
collectAsStateWithLifecycleสำหรับข้อมูล อย่าเริ่มหรือหยุดFlowการรวบรวมด้วยตนเองตามเหตุการณ์ในวงจร แต่ให้ใช้collectAsStateWithLifecycleเพื่อแปลงสตรีมเป็นสถานะ UI อย่างมีประสิทธิภาพแทน ซึ่งจะช่วยประหยัดแบตเตอรี่และทรัพยากรเนื่องจากระบบจะหยุดFlowชั่วคราวเมื่อแอปทำงานในเบื้องหลัง
ดูข้อมูลเพิ่มเติมเกี่ยวกับ Flow ได้ที่ประเภทสถานะอื่นๆ ที่รองรับ
กรณีการใช้งานสำหรับคอมโพเนนต์ที่รับรู้ถึงวงจร
คอมโพเนนต์ที่รับรู้ถึงวงจรช่วยให้คุณจัดการวงจรได้ง่ายขึ้นมาก ในหลายๆ กรณี ตัวอย่างเช่น
- การสลับระหว่างการอัปเดตตำแหน่งแบบหยาบและแบบละเอียด ใช้
LifecycleStartEffectเพื่อเปิดใช้การอัปเดตตำแหน่งแบบละเอียดขณะที่ แอปปรากฏอยู่ (ON_START) และล้างข้อมูล Listener โดยอัตโนมัติหรือ เปลี่ยนไปใช้การอัปเดตแบบหยาบเมื่อแอปทำงานในเบื้องหลัง (ON_STOP) - หยุดและเริ่มการบัฟเฟอร์วิดีโอ ใช้
LifecycleResumeEffectเพื่อเลื่อน การเล่นวิดีโอจริงจนกว่าแอปจะอยู่เบื้องหน้าอย่างเต็มรูปแบบและ โต้ตอบได้ (ON_RESUME) และเพื่อให้แน่ใจว่าการเล่นจะหยุดชั่วคราวและ ปล่อยทรัพยากรเมื่อแอปทำงานในเบื้องหลัง (ON_PAUSE) - การเริ่มและหยุดการสตรีมเครือข่าย ใช้
collectAsStateWithLifecycleเพื่อสังเกตสตรีมข้อมูลอย่างต่อเนื่อง (เช่น Kotlin Flow จากซ็อกเก็ตเครือข่าย ) ซึ่งจะช่วยให้คุณอัปเดตได้แบบเรียลไทม์ขณะที่แอปทำงานในเบื้องหน้า และยกเลิกการรวบรวมโดยอัตโนมัติเมื่อแอปทำงานในเบื้องหลัง - หยุดชั่วคราวและกลับมาทำงานหนักอีกครั้ง ใช้
LifecycleResumeEffectเพื่อจัดการ การหยุดการอัปเดตภาพที่ใช้ทรัพยากรมากชั่วคราวเมื่อแอปอยู่ในเบื้องหลัง และดำเนินการต่อ หลังจากที่แอปอยู่ในเบื้องหน้า
การจัดการเหตุการณ์ ON_STOP อย่างปลอดภัย
Compose ออกแบบมาเพื่อจัดการเหตุการณ์ ON_STOP อย่างปลอดภัย
- สถานะปลอดภัย: คุณอัปเดต
MutableState(เช่น ด้วยuiState.value = ...) ได้ทุกเมื่อ แม้ว่าแอปจะทำงานในเบื้องหลังก็ตาม Compose จะรอจนกว่าแอปจะแสดงให้เห็นเพื่อแสดงผลการเปลี่ยนแปลง - การล้างข้อมูลอัตโนมัติ: ด้วยเอฟเฟกต์อย่าง
LifecycleStartEffectบล็อกการล้างข้อมูล (onStopOrDispose) จะทำงานเมื่อวงจรชีวิตเปลี่ยนไปเป็นSTOPPEDซึ่งจะช่วยป้องกันไม่ให้คุณถือครองทรัพยากรที่มีน้ำหนักมาก (เช่น กล้องหรือ ตำแหน่ง) ขณะที่แอปทำงานในเบื้องหลัง
ดูข้อมูลเพิ่มเติมเกี่ยวกับ MutableState ได้ที่สถานะและ Jetpack Compose
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการวงจรด้วยคอมโพเนนต์ที่รับรู้ถึงวงจรได้จากแหล่งข้อมูลเพิ่มเติมต่อไปนี้
ดูเนื้อหา
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ภาพรวม LiveData
- ใช้โครูทีน Kotlin กับคอมโพเนนต์ที่รับรู้ถึงวงจร
- โมดูลสถานะที่บันทึกไว้สำหรับ ViewModel