LiveData에 대해 알아보자| Android Study

hoya·2021년 12월 15일
0

Android Study

목록 보기
9/19
post-thumbnail

🤔 LiveData?

LiveData는 관찰 가능한 데이터 홀더 클래스입니다. 관찰 가능한 일반 클래스와 달리 LiveData는 생명 주기를 인식합니다. 즉, 액티비티, 프래그먼트, 서비스 등 다른 앱 구성요소의 생명 주기를 고려합니다. 수명 주기 인식을 통해 LiveData는 활동 수명 주기 상태에 있는 앱 구성요소 관찰자만 업데이트합니다.

라고 공식 문서에 적혀있는데, 말이 조금 난해하다. 쉽게 이해해보도록 하자.

Data Holder Class : 동작을 거의 하지 않고, 데이터만 가지고 있는 클래스

LiveData 는 기본적으로 자신이 옵저버의 역할을 수행한다. 변경이 감지되면 자신에게 붙은 구독자들에게 변경이 되었습니다! 하고 알림을 주고, 구독자들은 이에 따라 여러 행동을 할 수 있게 된다.

(이해가 되지 않는다면, 리액티브 프로그래밍의 기초인 옵저버 패턴을 참고하자.)

그런데, LiveData는 기본적인 옵저버 기능말고도 안드로이드에 특화된 기능을 제공한다. 바로 안드로이드의 생명주기를 인식하는 것인데, 생명주기를 인식하면 어떤 이 점을 갖게되는 걸까?

간단하게 생각해보자. 화면이 사용자의 휴대폰에 띄워져 있지 않은데도 데이터가 필요할까? 당연히 필요하지 않을 것이다. 그럼에도 불구하고 데이터를 계속해서 전달하고 있다면, 메모리 누수가 발생하여 성능 저하가 발생할 것이다. LiveData는 이러한 단점을 보완하고, 메모리 누수 발생을 방지한다.

🧐 어떻게 생명주기를 인식하는거야?

LifeCycleOwner 가 안드로이드의 생명 주기를 인식한다. 이 인터페이스는 Activity, Fragment에 기본적으로 구현되어 있으며, getLifeCycle() 메소드를 통해 LifeCycle 객체를 가져온다.

추가적으로, 구글에서 이야기하는 LiveData 사용의 장점은 다음과 같다.

  1. UI와 데이터 상태의 일치를 보장한다.
  2. 생명주기를 인식하므로 메모리 누수가 없다.
  3. 생명주기가 비활성화 되었다가 돌아와도 최신 데이터를 유지한다.
  4. 기기 회전이 일어나도 최신 데이터를 유지한다.
  5. 사용자가 원하는대로 LiveData 객체 확장이 가능하다.

🙃 실습

우선 위와 같은 형태의 XML 파일을 만들어준다. 우리는 여기서 EditText 에 값을 넣고, Edit 버튼을 클릭하면 위의 TextView 가 실시간으로 변하는 코드를 넣을 것이다.

class EditUserProfileActivity : AppCompatActivity() {
    
    var userLiveData = MutableLiveData<User>() // LiveData 선언

    private val binding : ActivityEditUserProfileBinding by lazy {
        ActivityEditUserProfileBinding.inflate(layoutInflater)
    } // View Binding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        userLiveData.observe(this) { // LiveData 변화 감지시 움직임
            binding.tvNickname.text = it.nickname
            binding.tvName.text = it.name
            Toast.makeText(this, "변경이 감지되었습니다.", Toast.LENGTH_LONG).show();
        }

        binding.btnEdit.setOnClickListener {
            var userData = userLiveData.value
            val setNickName = binding.edtNickname.text.toString()
            val setName = binding.edtName.text.toString()

            userData = User(setNickName, setName)
            userLiveData.postValue(userData) // LiveData로 값 전송
        }
    }
}

코드 자체는 매우 간단하다.

        userLiveData.observe(this) { // LiveData 변화 감지시 움직임
            binding.tvNickname.text = it.nickname
            binding.tvName.text = it.name
            Toast.makeText(this, "변경이 감지되었습니다.", Toast.LENGTH_LONG).show();
        }

이 부분이 LiveData 의 핵심인 부분이다. observe 메소드에 인자로 주어진 this 가 위에서 이야기한 LifeCycleOwner 로, 이 녀석을 통해 컴포넌트의 생명주기를 인식하는 것이다.

두 번째 인자로 Observer 객체를 넘겨주고, 변화가 일어났을 때 할 행동을 설정한다. 위의 코드에서는 TextView의 값을 바꿔주는 것으로 코드를 작성하였다.


📌 MutableLiveData? LiveData?

Mutable : 변경 가능한

즉, MutableLiveData 는 변경 가능한 LiveData 를 의미한다. 쉽게 이야기해 LiveData 계의 var 라고 보면 된다. MutableLiveData 의 값을 변경하는 방법은 두 가지가 있고, 두 방법을 사용하지 않으면 값의 변경을 감지하지 못하니 꼭 이 방법을 사용하도록 하자.

  • setValue() : Main Thread에서 작업이 일어나며, 동기적으로 처리된다.
  • postValue() : Background Thread에서 작업이 일어나며, 비동기적으로 처리된다.
비동기적으로 처리될 때 순서 보장이 안된다는 것은 다들 아시죠? 😉
😯 왜 이렇게 둘을 나눠놓았을까? 

이는 ViewModel, View의 역할을 분리하기 위함이다. 
이에 관한 자세한 내용은 나중에 ViewModel에 관한 포스팅을 작성할 때 담도록 한다.

참고 및 출처

Android LiveData의 사용법과 내부 코드를 통한 UI 처리, 중복 처리 등 살펴보기
안드로이드 공식 문서

profile
즐겁게 하자 🤭

0개의 댓글