Home LiveData
Post
Cancel

LiveData

LiveData

  • LiveData는 액티비티나 프래그먼트의 Lifecycle을 고려한 옵저버 패턴을 이용해 구현된 데이터 홀더 클래스이다.

  • 액티비티나 프래그먼트의 생명주기인 STARTED, RESUMED 상태에서만 데이터의 변경사항을 관찰자에게 알려주며, 그 외의 상태에서는 변경사항을 알리지 않는다.
    • 즉, Active 상태에서만 변경사항을 관찰자에게 알려준다.
  • 액티비티나 프래그먼트에서 LiveDataobserve 메소드를 이용해 관찰한다.

  • 대체로 LiveData는 ViewModel에서 자주 사용된다.
    • 화면 회전과 같은 변경사항이 발생했을 경우 액티비티는 Destory 됐다가 다시 Create되는데 이때 UI를 다시 그리게 되어 이전에 작성된 사항들이 사라지기 때문에 ViewModel 객체에서 UI의 데이터(텍스트 뷰 내용 등)를 관리한다.
    • 액티비티나 프래그먼트에서 LiveData를 observe하고 있고 비활성 상태(홈버튼을 눌러 화면을 나갔을 때 등)에서 활성 상태로 변경될 때 LiveData의 최신 데이터값을 가져와 UI에 표현한다.
  • 액티비티나 프래그먼트의 생명주기를 따르므로 화면이 Destory될 때 LiveData를 관찰하는 관찰자를 제거해주게 되어 메모리 누수에 대한 부작용을 제거할 수 있다.

예제 1

  • class를 이용한 LiveData 예제
activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?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">

    <EditText
        android:id="@+id/username_edittext"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="가나다" />

    <Button
        android:id="@+id/add_user_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="추가"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/username_edittext" />

</androidx.constraintlayout.widget.ConstraintLayout>


MainActivity.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer

const val TAG = "MainActivity"

class MainActivity : AppCompatActivity() {

    private lateinit var usernameEditText: EditText
    private lateinit var addUserButton: Button
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val userList = UserList()
        usernameEditText = findViewById(R.id.username_edittext)
        addUserButton = findViewById<Button?>(R.id.add_user_button).apply {
            setOnClickListener {
                userList.addUser(usernameEditText.text.toString())
            }
        }

        userList.userList.observe(this, Observer { users ->
            Log.d(TAG, "================================")
            users.forEach { user ->
                Log.d(TAG, "user info : $user")
            }
            Log.d(TAG, "================================")
        })
    }
}

data class User(val username: String)

class UserList {
    private val totalUserList = mutableListOf<User>()
    private var _userList = MutableLiveData<List<User>>()
    val userList: LiveData<List<User>>
        get() = _userList

    fun addUser(username: String) {
        totalUserList.add(User(username))
        _userList.value = totalUserList
    }
}

예제 2

  • ViewModel과 LiveData를 이용한 예제
  • 예제 1과 동일한 xml
UserListViewModel.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class UserListViewModel : ViewModel() {
    private val totalUserList = mutableListOf<User>()
    private var _userList = MutableLiveData<List<User>>()
    val userList: LiveData<List<User>>
        get() = _userList

    fun addUser(username: String) {
        totalUserList.add(User(username))
        _userList.value = totalUserList
    }
}

data class User(val username: String)


MainActivity.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider

const val TAG = "MainActivity"

class MainActivity : AppCompatActivity() {

    private lateinit var usernameEditText: EditText
    private lateinit var addUserButton: Button
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val userListViewModel = ViewModelProvider(this).get(UserListViewModel::class.java)
        usernameEditText = findViewById(R.id.username_edittext)
        addUserButton = findViewById<Button>(R.id.add_user_button).apply {
            setOnClickListener {
                userListViewModel.addUser(usernameEditText.text.toString())
            }
        }

        userListViewModel.userList.observe(this, Observer { users ->
            Log.d(TAG, "================================")
            users.forEach { user ->
                Log.d(TAG, "user info : $user")
            }
            Log.d(TAG, "================================")
        })
    }
}

This post is licensed under CC BY 4.0 by the author.

ViewModel

[프로그래머스] 완주하지 못한 선수

Comments powered by Disqus.