Android Developer에서 설명하는 LiveData란 관찰기능한(Observable) 데이터 홀더 클래스입니다. 간단히 설명하면 Activity나 Fragment, service의 life cycle을 따르는데, LiveData는 현재 활성화된 생명주기에 있는 앱 컴포넌트 옵저버만 업데이트하도록 보장합니다.
즉, life cycle이 STARTED이거나 RESUMED 일 때, 옵저버가 활성상태 인것으로 간주, 이 활성화 중인 옵저버들에게만 LiveData 업데이트에 대한 알림을 줍니다. (비활성화 상태 STARTED이거나 RESUMED가 아닌 상태는 알림을 받지 않습니다.)
그리고 DESTROYED일 때는 옵저버가 삭제 될 수 있도록 할 수 있기 때문에 메모리 릭에 대한 우려도 없습니다.
이런 LiveData의 장점은 다음과 같습니다.
1. UI를 데이터 상태와 일치시킬 수 있다.
2 메모리 릭의 요소를 없앨 수 있다.
3. 정지된 엑티비티들 때문에 Crash날 일이 없다.
4. 직접 생명주기를 핸들링할 필요가 없다
5. 항상 최신 데이터를 유지한다.
6. 구성(Configuration)이 변경되었을 대 적절하게 대응한다.
7. 자원공유
그럼 간단한 사용 예제를 보겠습니다.
Android Studio에서
File->Project -> New Project를 선택하시고 Fragment+ViewModel을 선택합니다.
그럼 자동으로 Activity, Fragment, ViewModel이 생성 됩니다.
그 후 생성된 MainViewModel을 다음과 같이 coding 합니다.
class MainViewModel : ViewModel() {
private val text = MutableLiveData<String>()
val post: LiveData<String>
get() = text
fun changeData(str : String){
if(post.value.isNullOrEmpty()){
text.postValue(str)
}else{
text.value = str
}
}
}
그리고 Fragment와 xml을 다음과 같이 coding 합니다.
class MainFragment : Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.main_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
viewModel.post.observe(activity!!, Observer {
for( t in it){
Log.d("TEST", "t: $t")
}
message.text = it.toString()
})
btn_input.setOnClickListener {
val str = et_input.text.toString()
if(str == null || str.isEmpty()){
return@setOnClickListener
}
viewModel.changeData(str)
}
}
}
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainFragment">
<EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="@+id/btn_input"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="입력"
app:layout_constraintTop_toBottomOf="@+id/et_input"/>
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MainFragment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
이렇게 하고 실행하면
이런 결과가 나오는데 위의 EditText에 문자를 입력하고 입력 버튼을 누르면 가운데 MainFragment라고 적힌 부분이 변경 됩니다.
Fragment의 Code를 보면 버튼 클릭시 (btn_input.setOnClickListener) viewModel의 changeData Method를 호출 하고 changeData Method는 LiveData를 변경합니다.
LiveData가 변경이 되면 Fragment에 있는 viewModel.post.observe(activity!!, Observer { ... })에 Observer가 동작하고 그 안에서 text를 변경합니다.
또한, LiveData를 확장자로 사용할 수 도 있습니다.
class ExtendLiveData : LiveData<String>() {
override fun onActive() {
super.onActive()
}
override fun onInactive() {
super.onInactive()
}
fun onChangeData(str : String){
value = str
}
override fun setValue(value: String?) {
Log.d("TEST", "setValue value: $value")
super.setValue(value)
}
}
이렇게 LiveData를 확장자로 가지는 class를 만들고 적용하면
class MainFragment : Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.main_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val mExtendLiveData = ExtendLiveData()
mExtendLiveData.observe(activity!!, Observer {
message.text = it.toString()
})
btn_input.setOnClickListener {
val str = et_input.text.toString()
if(str == null || str.isEmpty()){
return@setOnClickListener
}
mExtendLiveData.onChangeData(str)
}
}
}
위의 결과와 동일한 결과를 확인 할 수 있습니다.
더 자세한 내용은 Android Developer LiveData 페이지에서 확인하실 수 있습니다.
'2023년 이전 > Android' 카테고리의 다른 글
Android - WorkManager (2) WorkRequest (0) | 2019.10.16 |
---|---|
Android - WorkManager(1) (1) | 2019.10.16 |
Android - ViewModel (0) | 2019.10.15 |
custom 숫자 키 입력 - 보안 숫자 keyboard (0) | 2019.09.06 |
Android - Kotlin을 사용하여 Listener 등록 (0) | 2019.08.29 |