[안드로이드 공식문서 파헤치기] LiveData의 모든 것! - 2편(lifecycle AAC)

dada·2022년 8월 23일
2
post-thumbnail

참고 자료
Android Developer 도큐먼트 - 수명 주기 인식 구성요소로 수명 주기 처리
Android Developer 도큐먼트 - LifecycleObserver
Android Developer 도큐먼트 - LiveData
Android Developer 도큐먼트 - LifecycleOwner

✅공부배경

  • LiveData와 같이 수명주기를 인식해서 수명주기가 onStart(),onResume()일때 Observe객체를 트리거하는 AAC들은 어떻게 UI Controller(Activity, Fragment)의 LifeCycle을 관찰할 수 있는 것일까요?

  • 이는 수명주기 인식 구성요소를 사용함으로써 가능합니다. 이번 포스팅은 LifeCycle과 수명주기 인식 구성요소를 공부해보겠습니다

✅수명주기 인식 구성요소

  • 수명주기 인식 구성요소란 액티비티와 프래그먼트와 같은 다른 컴포넌트의 생명주기 상태 변화에 대응하여 수행되는 컴포넌트입니다.

  • 수명주기 인식 구성요소는 말그대로 UI Controller의 수명주기를 인식합니다. 여기서 이야기하는 수명주기은 UI Controller의 onCreate~onDestroy를 하나하나 이야기 하는 것이 아니라 지금 수명주기 상태가 onStart()이다, onResume()이 되었다처럼, View의 현재 수명주기 상태(states)와 어떤 이벤트(events)로 인해 해당 수명주기 상태가 되었는지를 알리는 것입니다.

  • 수명주기 인식 구성요소를 사용하면 코드를 더 가볍게 만들 수 있고 유지보수하기가 쉬워집니다. 즉 액티비티나 프래그먼트의 생명주기와 관련된 코드를 이 컴포넌트안에 작성하여 코드를 더 깔끔하게 작성할 수 있습니다.

  • 예를 들어 어떤 액티비티가 생성되면서 위치 추적이 시작되고 소멸되면서 위치 추적이 멈추어야 한다면 이를 액티비티 내에서 작성할 수 있지만, 액티비티에는 위치 추척 이외에도 다른 작업을 하는 코드가 많습니다. 특정업무(위치 추적)가 생명주기와 밀접한 작업이라면 이 업무만을 추상화 하자는 개념입니다.(수명주기 인식 구성요소들을 사용해서)

✅lifecycle AAC

  • 수명주기 인식 구성요소을 얻기 위해서는 안드로이드 Jetpack에서 제공하는 lifecycle AAC를 사용해야합니다. androidx.lifecycle 패키지는 수명 주기 인식 구성요소를 빌드할 수 있는 클래스 및 인터페이스를 제공하기 때문입니다

  • lifecycle AAC의 구성요소는 3가지가 있습니다

    • Owner : 생명주기 처리가 필요한 액티비티 또는 프래그먼트를 의미합니다.

    • Observer: 액티비티 또는 프래그먼트의 생명주기가 변하면, 변화에 대한 이벤트를 받기 위한 클래스입니다. LifeCycleObserver인터페이스를 구현해서 얻을 수 있습니다. ex) activity 상태가 onStart()가 되면 추적을 시작하라는 이벤트가 등록되어있음

    • Lifecycle: UI Controller의 수명 주기 상태 관련 정보를 포함하며 다른 객체(앞선 Observe인터페이스 구현체)가 이 상태를 관찰할 수 있게 하는 클래스입니다. ex)activity의 수명주기상태를 담고있음

  • 기본적인 구조는 LifeCycle 객체에 Observer를 등록해 놓으면 액티비티나 프래그먼트 등의 생명주기 변경 시 LifeCycle 객체가 등록된 Observer를 실행하는 구조입니다.

👉 Observer

  • 먼저 수명주기 상태가 변경되면 변경에 따라 처리할 이벤트를 정의해놓을 Observer가 필요합니다. 이를 위해선 LifeCycleObserver인터페이스를 구현하면 됩니다.

  • 하지만 LifeCycleObserver를 직접 구현해서는 안되고, 이를 구현하여 작성된 인터페이스인 DefaultLifeCycleObserver 또는 LifecycleEventObserver를 사용하라고 되어있습니다.

DefaultLifecycleObserver

  • LifeCycleOwner 상태 변경를 관찰하는 콜백 인터페이스입니다. 만약 LifecycleEventObserverDefaultLifeCycleObserver를 모두 구현하였다면 DefaultLifecycleObserver의 메서드들이 먼저 호출되고 난 후, LifecycleEventObserver.onStateChanged(LifecycleOwner, Lifecycle.Event)의 호출이 따라옵니다. DefaultLifeCycleObserver의 메서드는 생명주기가 변할 시 각각의 메서드를 사용하여 호출하는 구조입니다.

LifecycleEventObserver

  • 생명주기의 변화를 수신하여 receiver에게 보낼 수 있는 클래스입니다. LifecycleEventObserver의 메서드는 한 개 존재하고 생명주기가 변할 시 Event가 넘어오고 그를 분기하여 필요한 코드를 호출하는 구조입니다.

✔ DefaultLifecycleObserver 구현

// DefaultLifecycleObserver 인터페이스 구현
class MyLifecycleObserver: DefaultLifecycleObserver {
    // 필요한 메서드를 구현
    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        Log.d(owner.toString(), "onCreate")
    }

    override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)
        Log.d(owner.toString(), "onResume")
    }

    override fun onStart(owner: LifecycleOwner) {
        super.onStart(owner)
        Log.d(owner.toString(), "onStart")
    }
}
  • DefaultLifecycleObserver를 구현하고 onCreate, onStart 등과 같은 메서드를 오버라이드하여 컴포넌트의 생명주기 상태를 모니터링할 수 있습니다. 만약 이 Observer를 액티비티에 연결하면 액티비티의 Lifecycle객체를 얻어서 MyLifecycleObserver 객체와 연결하여 액티비티의 수명주기 변화에 따른 이벤트를 처리할 수 있는 것입니다.

👉 Lifecycle

✔ Lifecycle의 역할, 구조

  • Observer가 준비되었다면 Observer에게 UI Controller의 수명주기를 알려줄 Lifecycle객체가 필요합니다. 이 객체가 액티비티나 프래그먼트의 생명주기 변화를 감지하는 역할을 수행합니다. 그리고 생명주기의 변화가 발생하면 등록된 Observer를 실행해주는 역할을 합니다.

  • Lifecycle은 관련된 컴포넌트의 생명주기를 추적하기 위해서 두 개의 주요 Enum을 사용합니다.

    • Event
      Lifecycle event는 프레임워크 및 Lifecycle 클래스에게 보내지는 생명주기 이벤트입니다. 이러한 event는 액티비티나 프래그먼트의 콜백 이벤트로 매핑됩니다.

    • State
      Lifecycle 객체에 의해 추적되어지는 컴포넌트의 현재 상태입니다.

  • 위의 그림에서 States를 그래프의 노드라 생각하고 Event를 그러한 노드를 잇는 간선이라고 생각하면 됩니다. 만약 States가 CREATED에서 STARTED가 된다면 ON_START라는 event가 발생하는 것이고 STARTED에서 RESUMED가 되면 ON_RESUME라는 event가 발생하는 구조입니다.

✔ Lifecycle얻기

  • Lifecycle을 얻기 위해서는 LifeCycleOwner 인터페이스에 정의되어 있는 getLifeCycle()메서드를 사용해야 합니다.

  • LifecycleOwner생명주기를 가지고 있음을 나타내는 단일 메서드 인터페이스입니다. getLifecycle()라는 메서드는 LifeCycle 객체를 리턴합니다.

  • Activity와 Framgment의 LifeCycle 객체를 얻기 위해선 Activity와 Framgment가 LifeCycleOwner 인터페이스를 구현하고 있어야 합니다. 실제로 확인해보면 Activity를 만들기 위해 상속받았던 AppCompatActivity 가 상속하는 ComponentActivity에서 LifecycleOwner을 구현하고 있을을 확인할 수 있습니다

  • 그런데, getLifecycle()의 리턴 객체가 mLifecycleRegisty 라는 값입니다.

  • LifecycleRegisty class는 LifeCycle class를 상속받아 일부 메서드를 오버라이딩한 클래스입니다. 여기서 오버라이딩한 주요 메서드가 addObserver, removeObserver옵저버 객체를 관리하기 위한 것들입니다. 또한 LifeCycle의 state를 지정하거나 변경할 수 있는 메서드들도 오버라이딩합니다. 즉 LifeCycleRegistry class를 이용하여 LifeCycleOwner를 커스텀하거나 옵져버들을 관리할 수 있는 기능을 제공하도록 해줍니다.

  • 따라서 Activity에서 구현하고 있는 getLifeCycle()LifeCycleRegistry를 리턴함으로써 외부의 Observer 객체들을 리스트에 저장하고 LifeCycle state에 따라 관리 할 수 있는 기능을 사용할 수 있게 됩니다

class ExampeActivity: Activity(), LifecycleOwner {
    private lateinit var lifecycleRegistry: LifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycleRegistry = LifecycleRegistry(this)

        lifecycleRegistry.addObserver(MyLifecycleObserver())
    }

    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }
}
  • (위 코드 참고)만약, AppCompatActivity를 구현하지 않고 Activity를 상속받아 작성하고 싶다면 직접 LifecycleOwner를 구현해주어야 수명주기 인식 구성 요소를 사용할 수 있습니다.

✅ LiveData의 observe()의 수명주기 인식 구성 요소

  • 이제 LiveData와 같이 수명주기를 인식해서 수명주기가 onStart(),onResume()일때 Observe객체를 트리거하는 AAC들이 어떻게 UI Controller(Activity, Fragment)의 LifeCycle을 관찰하고, 이벤트를 전달하는 지 알 수 있게됐습니다!

  • LiveDataobserve()를 보면 observe()의 첫번째 인자가 바로 LifeCycleOwner 구현체, 두번째 인자가 Observer 객체입니다. 수명주기 인식 구성요소의 기본적인 구조는 LifeCycle 객체에 Observer를 등록해 놓으면 액티비티나 프래그먼트 등의 생명주기 변경 시 LifeCycle 객체가 등록된 Observer를 실행하는 구조라고 설명한 바 있습니다. 맨 아래 코드를 보시면, owner.getLifecycle()를 통해 Lifecycle 객체를 얻고 이 객체에 addObserver()를 호출해 Observer를 등록하고 있습니다

  • 여기서 중요한건 owner.getLifecycle().addObserver(wrapper)입니다. owner의 getLifeCycle()LifeCycleRegistry class의 인스턴스를 리턴하기 때문에 LifeCycleRegistry가 정의하고 있는 addObserver()을 사용할 수 있는 것입니다

  • 그리고 if(ower.getLifecycle().getCurrentState()==DESTROYED) 구문을 통해 Lifecycle의 state가 DESTROYED라면 return 하기 때문에 LiveData는 내부적으로 활성 상태일 때만 이벤트를 전달한다는 것을 알 수 있습니다

LiveData의 observe는 인자로 LifecycleOwner을 구현한 객체와 Observe객체를 전달받습니다. 이때 LifeCycle의 서브 클래스인 LifeCycleRegistry 클래스는 addObserve, removeObserve 등 Lifecycle state에 따라 관리 할 수 있는 기능을 제공하는 메서드를 정의합니다. 개발자는 LifeCycleRegistry 객체를 외부에서 사용할 수 있도록 구현해놓은 LifeCycleOwner 를 통해 LiveData와 Observer를 안전하고 편리하게 동작시킬 수 있습니다

profile
'왜?'라는 물음을 해결하며 마지막 개념까지 공부합니다✍

0개의 댓글