[안드로이드] 수명주기 인식 컴포넌트

0

Android

목록 보기
3/16

💙 수명주기-인식 컴포넌트


지금껏 안드로이드의 액티비티나 프래그먼트에서 생명주기 함수를 이용하여 생명 주기 상태 변화를 처리했습니다.
이 방법을 사용하면 UI 컨트롤러에 부담을 주게 됩니다.

이 문제를 해결하기 위해 안드로이드에서는 관찰자 패턴을 이용하여 다른 구성 요소 객체의 수명 주기를 관찰할 수 있는 Lifecycle 클래스를 만들었습니다.

수명 주기 인식의 필요성

Android 프레임워크에 정의된 대부분의 앱 구성요소에는 수명 주기가 연결되어 있습니다. 이는 Android 작동 방식의 핵심으로, 애플리케이션은 수명 주기를 고려해야 하며, 그렇게 하지 않으면 메모리 누수 또는 애플리케이션 비정상 종료가 발생할 수 있습니다.

기존의 문제점

  • callback을 오버라이드 하여 사용한다면 UI 컨트롤러의 코드량이 비대해질 수 있습니다..
  • 만약 백그라운드 쓰레드를 이용해서 작업을 한다면, 컨트롤러 작업이 중지(onStop) 되더라도 필요 이상으로 작업을 오랫동안 유지하거나 메모리 누수가 발생할 수 있습니다.

자세한 내용은 아래 링크를 참고해 주시기 바랍니다.

https://developer.android.com/topic/libraries/architecture/lifecycle?hl=ko

LifecycleOwner

LifecycleOwner은 클래스에 Lifecycle이 있음을 나타내는 단일 메서드 인터페이스입니다. 수명주기-인식 컴포넌트는 lifecycleOwner 객체의 상태만 관찰할 수 있습니다.

생명주기 소유자는 LifecycleOwner 인터페이스를 구현하며, 짝을 이루는 Lifecycle 객체에 지정됩니다. 그리고 Lifecycle객체는 컴포넌트의 현재 상태를 저장하며, 생명주기를 관찰하는 LifecycleObserver에게 상태정보를 제공하는 책임을 갖습니다.

다음 코드는 LifecycleOwner 인터페이스를 이용하여 작성한 커스텀 클래스입니다.

class SampleOwner: LifecycleOwner {
	// 스스로 생명주기 상태 변화를 일으키기 위한 클래스
    private val lifecycleRegistry: LifecycleRegistry
    
    init {
    	lifecycleRegistry = LifecycleRegistry(this)
        lifecycle.addObserver(DemoObserver())
    }
    // 현재 상태 전달
    override fun getLifecycle(): Lifecycle {
    	return lifecycleRegistry
    }
}

생명주기 소유자가 다른 생명주기-인식 컴포넌트의 서브 클래스가 아니라면, 해당 생명주기 소유자 클래스는 LifecycleRegistry 클래스의 함수를 호출하여 스스로 생명주기 상태 변화를 일으켜야 합니다. 이때 다음 코드와같이 markState() 함수를 호출하여 수명주기 상태 변화를 유발할 수 있습니다.

fun resuning() {
	lifecycleRegistry.markState(Lifecycle.State.RESUMED)
}

발생시킬 생명주기 이벤트를 인자로 전달하여 LifecycleRegistryhandleLifecycleEvert() 함수를 호출할 수도 있습니다. (이 함수는 생명주기의 상태 변화도 초래합니다.)

lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)

생명주기 옵저버

수명주기 - 인식 컴포넌트가 수명주기 소유자의 상태를 관찰하려면 LifecycleObserver 인터페이스를 구현하고 관찰할 필요가 있는 생명주기 상태를 처리하는 이벤트 리스너 핸들러를 포함해야 합니다.

class DemoObserver: LifecycleObserver {
    private val LOG_TAG = "DemoObserver"

    // 애노테이션을 사용하여 함수와 생명주기 이벤트를 연관시킨다.
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume() {
        Log.i(LOG_TAG, "onResume")
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        Log.i(LOG_TAG, "onPause")
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate() {
        Log.i(LOG_TAG, "onCreate")
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onAny(owner: LifecycleOwner, event: Lifecycle.Event) {
        Log.i(LOG_TAG, owner.lifecycle.currentState.name) // 현재 상태를 로깅
        // var eventName = event.name
    }
	// 이하 생략..

}

여기서 ON_ANY 이벤트에 지정된 함수는 생명 주기 소유자와 이벤트 객체의 참조를 인자로 받아 현재 상태와 이벤트 타입을 알아내는데 사용할 수 있습니다.

그 다음 옵저버 클래스의 인스턴스를 생성하고 Lifecycle 객체가 유지하는 옵저버 리스트에 추가합니다. 다음 코드는 프래그먼트의 상태주기를 관찰하기 위한 옵저버를 추가하는 코드입니다.

class MainFragment : Fragment() {

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

        lifecycle.addObserver(DemoObserver())

    }

}

그 다음 앱을 실행하면 다음과 같은 로그가 뜨게 됩니다.

onCreate
CREATED <- onAny 함수가 동작하여 현재 상태를 보여준다. 
onStart
STARTED
onResume
RESUMED

References

안드로이드 스튜디오 Arctic Fox & 프로그래밍 - 닐 스미스
수명 주기 인식 구성요소로 수명 주기 처리 | Android 개발자 공식 문서

0개의 댓글