Android Mastery by Dan Tech
Android Mastery by Dan Tech

Android Lifecycle: Kiến thức cần biết

Sau khi bạn đã nắm được các thành phần trụ cột của một ứng dụng Android – Android Fundamentals. Bước tiếp theo hãy tìm hiểu về Lifecycle nhé, đây sẽ là nền tảng giúp bạn quản lý tài nguyên ứng dụng một cách hiệu quả!

Tất cả mọi Object trong 1 chương trình đều có Lifecycle. Một vài Object đặc biệt có lifecycle cần phải lưu ý trong quá trình xây dựng phần mềm.

Application Lifecycle

Trong mỗi ứng dụng Android sẽ được đại diện bởi 1 class Application. Tuy nhiên ở trạng thái mặc định của 1 dự án Android, bạn không thấy sự hiện diện của class này trong Project.

Tạo 1 Kotlin Class đặt tên là MyApplication kế thừa Application

Chạy ứng dụng và xem các Log.

Chạy ứng dụng để xem log thứ tự các hàm trong Application lifecycle – Android Mastery by Dan Tech

Activity Lifecycle

Vòng đời của một Activity trong ứng dụng Android
class StandardActivity : AppCompatActivity() {
    private var viewBinding: ActivityStandardBinding? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewBinding = ActivityStandardBinding.inflate(layoutInflater)
        setContentView(viewBinding!!.root)        
        Log.d("StandardActivity", "onCreate")
    }
    override fun onStart() {
        super.onStart()
        Log.d("StandardActivity", "onStart")
    }
    override fun onResume() {
        super.onResume()
        Log.d("StandardActivity", "onResume")
    }
    override fun onPause() {
        super.onPause()
        Log.d("StandardActivity", "onPause")
    }
    override fun onStop() {
        super.onStop()
        Log.d("StandardActivity", "onStop")
    }
    override fun onDestroy() {
        super.onDestroy()
        Log.d("StandardActivity", "onDestroy")
    }
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        Log.d("StandardActivity", "onSaveInstanceState")
    }
    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
        super.onRestoreInstanceState(savedInstanceState)
        Log.d("StandardActivity", "onRestoreInstanceState")
    }
    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        Log.d("StandardActivity", "onAttachedToWindow")
    }
    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        Log.d("StandardActivity", "onDetachedFromWindow")
    }
    override fun attachBaseContext(newBase: Context?) {
        super.attachBaseContext(newBase)
        Log.d("StandardActivity", "attachBaseContext")
    }
}

Bạn hãy thêm các Log này vào Activity của mình và quan sát Log của chúng – Android Mastery by Dan Tech

Fragment Lifecycle

Fragment là một phạm trù phức tạp trong Lập trình Android. Có thể nói việc quản lý Fragment trong Android rất khó khăn với những người mới, thậm chí là người đã có kinh nghiệm lâu năm trong nghề. Ngày nay với sự hỗ trợ của Jetpack Navigation, hoặc Compose. Sự khó khăn của Fragment đã được giảm đi đáng kể, tuy nhiên việc hiểu và nắm kiến thức về Fragment vẫn luôn luôn là cần thiết cho một Android Engineer. Để trở thành một người giỏi hơn, bạn buộc phải nắm những kiến thức mà không ai muốn hiểu.

Để hệ thống lại kiến thức Fragment, cũng như đưa ra một lộ trình tiếp thu thật hợp lý các bạn hãy học thật kỹ kiến thức dưới đây nhé!

Khái niệm Fragment

Fragment là đơn vị nhỏ hơn Activity, nhưng lớn hơn LayoutView trong một Lập trình Android. Mỗi Activity có thể chứa 1 hoặc nhiều Fragment cùng lúc, và trong mỗi Fragment cũng có thể chứa nhiều Fragment bên trong chúng. Điều này vô tình làm gia tăng độ phức tạp của ứng dụng Android cho trường hợp chúng ta thiết kế tính năng có quá nhiều Fragment lồng vào nhau.

1 Fragment có thể có độ lớn tùy ý theo khả năng lập trình của Software Engineer. Tuy nhiên để dễ dàng bảo trì và tốt cho hiệu năng ứng dụng – mình khuyên tất cả các Lập trình viên Android khi làm việc với Fragment hãy để Fragment đó là 1 Fullscreen Fragment, và cố gắng giảm tối đa các trường hợp nhiều Fragment con bên trong 1 Fragment.

Cách tạo và sử dụng Fragment trong Activity

Launch một Fragment từ một Activity – Android Mastery by Dan Tech
Cách Launch một Fragment từ một Fragment – Android Mastery by Dan Tech

Fragment Lifecycle

Cũng giống như Application hay Activity thì Fragment cũng có Lifecycle riêng của nó. Vì Fragment được quản lý bởi Activity nên mỗi Lifecycle của Fragment sẽ được liên quan chặt chẽ đến Activity chứa nó.

Mô phỏng Lifecycle (Vòng đời) của một Fragment trong Android – Android Mastery by Dan Tech

Danh sách những callback Lifecycle trong Android Fragment

class SimpleFragment : Fragment() {
    override fun onAttach(context: Context) {
        super.onAttach(context)
        Log.d("SimpleFragment", "onAttach")
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("SimpleFragment", "onCreate")
    }
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        Log.d("SimpleFragment", "onCreateView")
        binding = FragmentSimpleBinding.inflate(inflater, container, false)
        return binding?.root
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)        
        Log.d("SimpleFragment", "onViewCreated")
    }
    override fun onViewStateRestored(savedInstanceState: Bundle?) {
        super.onViewStateRestored(savedInstanceState)
        Log.d("SimpleFragment", "onViewStateRestored")
    }
    override fun onStart() {
        super.onStart()
        Log.d("SimpleFragment", "onStart")
    }
    override fun onResume() {
        super.onResume()
        Log.d("SimpleFragment", "onResume")
    }
    override fun onPause() {
        super.onPause()
        Log.d("SimpleFragment", "onPause")
    }
    override fun onStop() {
        super.onStop()
        Log.d("SimpleFragment", "onStop")
    }
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        Log.d("SimpleFragment", "onSaveInstanceState")
    }
    override fun onDestroyView() {
        super.onDestroyView()
        Log.d("SimpleFragment", "onDestroyView")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("SimpleFragment", "onDestroy")
    }
    override fun onDetach() {
        super.onDetach()
        Log.d("SimpleFragment", "onDetach")
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        Log.d("SimpleFragment", "onConfigurationChanged")
    }
}

OnConfigurationChanged

Configuration là tập hợp những tham số tổng quát được dùng trong 1 ứng dụng Android đang chạy có thể liệt kê ra: Kích thước màn hình (screenSize), chiều xoay màn hình (orientation), Bàn phím ẩn hiện (keyboardHidden), Ngôn ngữ (locale) ..

Mỗi khi có một tham số nào của Configuration này thay đổi. Tự động Activity sẽ được re-create, kéo theo sự re-create của các Fragment bên trong đó. Đồng thời callback cũng được trả về Application.onConfigurationChanged

Để chủ động xử lý các thay đổi bên trong Configuration mà không làm Activity re-create Lập trình viên có thể thêm thuộc tính vào trường android:configChanges trong khai báo Activity ở AndroidManifest

android:configChanges="orientation|screenSize"

Cần phải nói thêm, hướng tiếp cận xử lý Configuration Changes một cách thủ công như đây là 1 hướng tiếp cận khó và phức tạp. Việc học nó có thể phí phạm thời gian cho người mới vì họ đang thiếu rất nhiều kiến thức về lập trình Android.

Ở mảng kiến thức này Danh sẽ dừng lại ở việc cung cấp kiến thức mà không đi quá sâu vào ví dụ để tránh làm các bạn nản lòng.

Source code tham khảo bạn vui lòng ghé thăm GitHub của mình tại đây