(1) UI와 데이터 상태의 동기화
(2) 메모리 누수 방지
(3) 액티비티가 갑작스럽게 종료되어도 안전하다
(4) 생명 주기에 대한 고민 X
(5) 최신의 데이터를 유지한다
(6) 구성 변경에 대응한다
(7) 자원 공유
classs MainActivity: AppCompatActivity() {
var liveString = MutableLiveData<String>()
override fun onCreate(saveInstanceState: Bundle?) {
super.onCreate(saveInstanceState)
liveString.postValue("Hello Minha") //데이터 쓰기
liveString.value = "Hello World" //데이터 쓰기
liveString.observe(this) {
// 어떤 값이 먼저 들어올까?
}
}
}
class InitMutableLiveData<T>(initValue: T) : MutableLiveData<T>() {
init {
value = initValue
}
}
class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
private val stockManager = StockManager(symbol)
private val listener = { price: BigDecimal ->
value = price
}
override fun onActive() {
stockManager.requestPriceUpdates(listener)
}
override fun onInactive() {
stockManager.removeUpdates(listener)
}
}
public class MyFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val myPriceListener: LiveData<BigDecimal> = ...
myPriceListener.observe(viewLifecycleOwner, Observer<BigDecimal> { price: BigDecimal? ->
// UI를 갱신
})
}
}
class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
private val stockManager: StockManager = StockManager(symbol)
private val listener = { price: BigDecimal ->
value = price
}
override fun onActive() {
stockManager.requestPriceUpdates(listener)
}
override fun onInactive() {
stockManager.removeUpdates(listener)
}
companion object {
private lateinit var sInstance: StockLiveData
@MainThread
fun get(symbol: String): StockLiveData {
sInstance = if (::sInstance.isInitialized) sInstance else StockLiveData(symbol)
return sInstance
}
}
}
class MyFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
StockLiveData.get(symbol).observe(viewLifecycleOwner, Observer<BigDecimal> { price: BigDecimal? ->
// UI 갱신
})
}
var liveData1: LiveData = ...
var liveData2: LiveData = ...
val liveDataMerger: MediatorLiveData<*> = MediatorLiveData<Any>()
liveDataMerger.addSource(liveData1) { value: Any? -> liveDataMerger.setValue(value)}
liveDataMerger.addSource(liveData2) { value: Any? -> liveDataMerger.setValue(value)}
liveDataMerger.addSource(liveData1, object : Observer() {
private var count = 1
fun onChanged(@Nullable s: Int?) {
count++
liveDataMerger.setValue(s)
if (count > 10) {
liveDataMerger.removeSource(liveData1)
}
}
})
val userLiveData: LiveData<User> = UserLiveData()
val userName: LiveData<String> = Transformations.map(userLiveData) {
user -> "${user.name} ${user.lastName}"
}
private fun getUser(id: String): LiveData<User> {
...
}
val userId: LiveData<String> = ...
val user = Transformations.switchMap(userId) { id -> getUser(id) }
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = ...
binding.setLifecyclerOwner(this)
}
}
<!-- LiveData 사용 전 -->
<data>
<variable
name="name"
type="androidx.databinding.ObservableField<String>" />
</data>
...
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{name}" />
<!-- LiveData 사용 후 -->
<data>
<variable
name="name"
type="androidx.lifecycle.LiveData<String>" />
</data>
...
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{name}" />
app:userAge="@{safeUnbox(viewModel.age)}"
class UserViewModel : BaseObservable() {
val name = MutableLiveData<String>()
fun setName(name: String) {
this.name.value = name
}
}
<data>
<variable
name="viewModel"
type="com.example.UserViewModel" />
</data>
...
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{viewModel.name}" />