본문 바로가기
개발/Android

안드로이드 LiveData란?

by 남트로 2023. 5. 9.

오늘은 안드로이드 AAC JetPack 라이브러리 중 하나인 LiveData에 대해서 알아볼 것이다.

 

LiveData의 경우 장점도 굉장히 많고 다른 라이브러리(DataBinding, ViewModel 등)들과 함께 사용할 경우 훨씬 더 유용하다.

 

MVVM 패턴에 필수적인 LiveData의 개념과 사용법에 대해서 알아보자

 

 

 

LiveData란?


LiveData는 데이터의 변경을 관찰할 수 있는 Data Holder 클래스이다.

 

관찰이라고 하면 Observable이 생각날텐데 일반적인 Observable과는 다르게 LiveData는 안드로이드의 LifeCycle, 즉 생명주기를 알고있다.

 

Activity, Fragment, Service 등과 같은 안드로이드 컴포넌트의 생명주기를 인식하며 그에 따라 LiveData는 사용자에게 보여지는 활성상태일때만 데이터를 업데이트 한다.

 

이때 활성상태는 Started, Resume 상태를 말하며 생명주기가 Destroyed가 되면 관찰자를 삭제할 수 있다.

 

또한 LiveData 객체는 Observer 객체와 함께 사용되고 LiveData가 가지고 있는 데이터에 어떠한 변화가 일어날 경우

 

LiveData는 등록된 Observer 객체에 변화를 알려주며 Observer의 onChanged() 메서드가 실행되게 된다.



LiveData가 생명주기를 인식하는 법


안드로이드의 생명주기를 알고 있는 LifeCycleOwner를 통해 인식할 수 있다.

 

LifeCycleOwner는 메서드가 getLifeCycle() 뿐인 단일 메서드 인터페이스 클래스이며 Activity나 Fragment에서 이를 상속하고 있다.

 

즉 LiveData의 Observer 메소드의 LifeCycleOwner를 Activity나 Fragment를 변수로써 사용한다면 각 화면 별 생명주기에 따라 LiveData는 자신의 임무를 수행한다.



LiveData의 장점


1. UI 데이터 상태의 일치 보장

앱 데이터 및 라이프 사이클이 변경될 때 마다 observer을 통해 데이터를 변경할 수 있다.

2. 메모리 누출 없음

연결된 수명 주기가 끝나면 자동으로 삭제된다.

3. 중지된 활동으로 인한 비정상 종료 없음

관찰자의 수명 주기가 비활성화 상태이면 관찰자는 어떤 Live Data 이벤트도 받지 않는다.

4. 수명주기를 수동으로 처리하지 않음

수명 주기의 변경을 자동으로 인식함으로 수동으로 처리하지 않는다.

그러므로 UI 컴포넌트는 그저 관련 있는 데이터를 관찰하기만 하면 된다.

5. 최신 데이터 유지

수명 주기가 비활성화 일 경우 다시 활성화가 될 때 새로운 데이터를 받는다.

디바이스가 세로에서 가로로 변경되는 경우에도 LiveData는 회전하기 전의 최신 상태를 즉시 받아온다.

-> 예전과 같이 데이터를 유지하기 위해 SharedPreference를 사용하지 않아도 됨

6. 자원 공유 가능

LiveData를 상속하여 자신만의 LiveData클래스를 구현할 수 있고 싱글톤 패턴을 이용하여 시스템 서비스를 둘러싸면(Wrap) 앱 어디에서나 자원을 공유 할 수 있다.



LiveData 사용시 주의할 점


Generic을 사용해 관찰하고자 하는 데이터의 타입(Type)을 갖는 LiveData 인스턴스를 생성한다.

LiveData 클래스의 observe() 메소드를 사용해 Observer 객체를 LiveData 객체에 "결합" 한다. 이때 observe() 메소드는 LifecycleOwner 객체를 필요로 하며 보통은 Activity를 전달한다.

LiveData에 저장된 데이터에 어떠한 변화가 일어난 경우 결합된 LifecycleOwner에 의해서 상태가 active(활성)인 한 모든 데이터에 대해 Trigger가 발생한다.

Observer 객체를 생성한다. 생성시 LiveData가 들고있는 데이터가 변화가 일어났을 때 수행해야 할 로직이 들어있는 onChanged() 메서드를 정의해야 한다.

보통은 액티비티나 프래그먼트 같은 UI Controller 내에서 해당 메서드를 생성한다.

observeForever(Observer)를 통해 LifeCycleOwner 없이 Observer를 생성하여 등록할 순 있지만, 이 경우에는 Observer는 항상 active(활성) 상태이므로 데이터 변화를 항상 전달 받는다. 단, removeObserver(Observer) 메소드를 통해 Observer를 제거 할 수 있다.



LiveData 기본 사용법


먼저 build.gradle에서 종속성을 확인해준다.

implementation 'androidx.appcompat:apcompat:1.3.0'
 

그다음 LiveData를 사용할 곳에서 LiveData를 정의해준다.

private var liveText: MutableLiveData<String> = MutableLiveData()
 

LiveData는 abstract class이기에 LiveData Class를 상속받은 MutableLiveData를 사용한다.

LiveData : get만 가능

MutableLiveData : set/get 가능

그 후 LiveData에 Observer를 달아준다.

// LiveData value의 변경을 감지하고 호출
liveText.observe(this, Observer {
    // it로 넘어오는 param은 LiveData의 value
})
 

여기서 첫 번째 매개변수 this는 LifeCycleOwner인 MainActivity이다.

두 번째 매개변수 Observer Callback은 LiveData(liveText)의 value의 변경을 감지하고 호출되는 부분이다.

actovity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/text_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/btn_change"
        app:layout_constraintVertical_chainStyle="packed"/>

    <Button
        android:id="@+id/btn_change"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ADD 1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/text_test"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
 

MainActivty.kt

class MainActivity : AppCompatActivity() {

    private var liveText: MutableLiveData<String> = MutableLiveData()
    private var count = 0 // button을 누르면 증가 될 숫자

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // LiveData의 value의 변경을 감지하고 호출
        liveText.observe(this, Observer {
            // it로 넘어오는 param은 LiveData의 value
            text_test.text = it
        })

        btn_change.setOnClickListener {
            // liveText의 value를 변경
            // liveText 자체를 변경시키면 안됨
            liveText.value = "Hello World! ${++count}"
        }
    }
}
 

위와 같이 코드를 작성하고 실행을 하게 되면 버튼을 누를때마다 Text값의 숫자가 늘어나게 된다.

댓글