[안드로이드] JetPack의 LiveData란?

Lee Jun Hyeong·2023년 5월 10일
0

Android 톺아보기 😇

목록 보기
17/17
post-thumbnail

LiveData 란?

LiveData는 Data의 변경을 관찰할 수 있는 Data Holder 클래스이다.
LiveData는 안드로이드 생명주기(LifeCycle)을 알고 있다.
즉, Activity, Fragment, Service 등과 같은 안드로이드 컴포넌트의 생명주기(Lifecycle)를 인식하며 그에 따라 LiveData는 활성 상태일 때만 데이터를 업데이트 한다. 활성 상태란 Started 또는 Resumed를 의미한다. 비활동 상태일 땐, LiveData는 데이터의 변화를 알리지 않다. Destroyed 된 상태의 lifecycle 에서는 LiveData 객체를 Observe하지 않는다.

LiveData 객체는 Observer 객체와 함께 사용된다. LiveData가 가지고 있는 데이터에 변화가 일어날 경우, LiveData는 등록된 Observer 객체에 변화를 알려주고, Observer의 onChanged()메소드가 실행되게 된다.

LiveData가 생명주기를 어떻게 알까?

LifeCycleOwner가 안드로이드 생명주기(Android LifeCycle)을 알고 있는 클래스다.
LifeCycleOwnergetLifeCycle() 메서드만 가지고 있는 단일 인터페이스 클래스이며 Activity나 Fragment에서 상속하고 있다.
즉, LiveData의 Observer 메서드의 LifeCycleOwner를 Activity나 Fragment의 변수로 사용한다면 각 화면의 생명주기에 따라 데이터를 처리한다.

장점

UI와 Data의 상태 일치

Ensures your UI matches your data state

LiveData는 Observer 패턴을 따른다.
LiveData는 안드로이드 생명주기에 데이터 변경이 일어날 때마다 Observer 객체에 알려준다.
즉, Observer 객체를 사용하면 데이터의 변화가 일어나는 곳마다 매번 UI를 업데이트하는 코드를 작성할 필요 없이 통합적이고 확실하게 데이터의 상태와 UI를 일치시킬 수 있습니다.

예를 들어,

메모장 예제.
메모장에 메모 리스트를 볼 수 있다.

사용자가 자신의 메모장 제목을 수정하게 된다면,
1. DB에서 해당 메모의 제목을 새로 갱신한다.
2. DB에서 데이터를 받은 메모 리스트를 다시 화면에 뿌려줘야 한다.

LiveData는 DB의 데이터를 새로 갱신하면 데이터의 변화(Observer 객체의 데이터 변화)를 감지하고 자동으로 list의 글 제목을 갱신해주기 때문에 2번 과정을 생략한다.

마찬가지로 메모를 삭제하거나 추가했을 때, 메모 제목을 조회하여 list에 새롭게 뿌려주는 코드를 쓰지 않아도 되기 때문에 전체 코드가 간결해지고 유지 보수할 때, 신경쓸 부분이 줄어든다.

메모리 누수 방지

No memory leaks

Observer 객체는 안드로이드 생명주기 객체와 결합되어 있기 때문에 컴포넌트가 Destroy 될 경우 메모리상에서 스스로 해제한다.
즉, Activity 나 Fragment 의 lifecylce이 Destroyed 되면 Observers가 clean up 되기 때문에 메모리 낭비를 방지하는 데 효과적이다.

멈춘 액티비티와 충돌 방지

No crashes due to stopped activities

Lifecycle 중에 inactive (onStop, onDestroy) 된 activity 가 있다면 LiveData는 어떤 이벤트도 받지 않는다.
즉, 액티비티가 Back Stack에 있는 것처럼 Observer의 생명주기가 inactive(비활성화) 일 경우, Observer는 LiveData의 어떤 이벤트도 수신하지 않는다.

생명주기에 대한 추가적인 handling을 하지 않아도 된다.

No more manual lifecycle handling

LiveData는 생명주기별로 자동으로 <UI component가 데이터의 변화를 인지하고 갱신하는 것>을 관리하기 때문에 직접 생명주기를 관리하지 않아도 된다.

최신 데이터 유지

화면 구성이 변경되어도 데이터를 유지한다.
예를 들어, 디바이스를 회전하여 세로에서 가로로 화면이 변경될 경우에도 LiveData는 회전하기 전의 최신 상태를 즉시 받아온다.

자원(Resource) 공유

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

사용시 주의할 점

다음에 작성 예정

예제 코드

버튼을 눌러 숫자를 증가하는 앱 예제

MainActivity.kt

class MainActivity : AppCompatActivity() {

	// 전역 변수로 ViewModel lateinit 세팅
    private lateinit var viewModel : MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
		
        // ViewModel을 가져온다
        viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

        findViewById<Button>(R.id.btnArea).setOnClickListener {
        	// 카운트 증가
            viewModel.plusLiveDataValue()
        }

		// LiveData를 Observer를 이용해 관찰하고
        // 현재 Activity 및 Observer를 LifecycleOwner로 전달한다.
        viewModel.testMutableLiveData.observe(this, Observer {
        	// 변화가 있을 때 UI(여기선 TextView)를 업데이트 시켜준다.
            findViewById<TextView>(R.id.textArea).text = viewModel.testMutableLiveData.value.toString()
        })

    }
}

MainViewModel.kt

class MainViewModel : ViewModel() {

	// LiveData의 값을 0으로 초기화
    var testMutableLiveData = MutableLiveData(0)

    fun plusLiveDataValue(){
    	// LiveData의 값 1 증가
        testMutableLiveData.value = testMutableLiveData.value!!.plus(1)
    }

}

activity_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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/textArea"
            android:textSize="60dp"
            android:text="0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <Button
            android:id="@+id/btnArea"
            android:text="btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>


    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

참고
https://velog.io/@jojo_devstory/Android-LiveData...%EB%84%8C-%EB%88%84%EA%B5%AC%EB%83%90
https://velog.io/@shin_stealer/LiveData-%EB%9E%80
https://developer.android.com/topic/libraries/architecture/livedata?authuser=1
profile
"왜" 사용하며, "어떻게" 사용하는지에 대해

0개의 댓글