Live Data에 대한 몇 가지 오해가 있습니다.
LiveData란 무엇입니까?
Android Architecture Components은'라이프 사이클에 따라 자동으로 구독을 취소하는 알림 속성'입니다.
현대(이미 유행이 지났어?)사용자 인터페이스 모드에서 사용자 인터페이스에서 데이터의 변경을 감지하고 자신을 고칩니다.
즉, UI 측은'구독 데이터'코드를 써야 하지만,'구독 정지'코드를 고려해야 한다.그러나 Android의 Activity와 Fragment는 생명주기가 복잡하고 구독 관리도 힘들어 문제의 온상이 되기 쉽다.
LiveData는 AAC에 포함된 Lifecycle과 깊은 관계를 가지고 있으며 거의 자동으로 이'구독 취소'를 진행할 수 있습니다.
시도된 응용 프로그램
도대체 몇 명이 몇 번을 만들었는지를 보여주는 GitHub의 메모리 리스트다.
LiveData
주요 요소는 다음과 같습니다.
callbackExecutor
.Live Data가 오해한 것
그렇다면 Live Data를 실제로 사용할 때 "진짜야..."라고 생각하는 부분이 몇 가지 있습니다. 제가 들어볼게요.
"변경 알림" 이 아니라 "처짐" 입니다
제가 기대하는 것은'DataBinding의 Observable Field처럼 사용할 수 있고 구독 관리가 쉽다'는 것입니다. 하지만 여기와 Observable Field는 결정적인 차이가 있습니다.
값이 변경되면 ObservableField에서 알림을 보냅니다.
값이 변경되지 않은 경우에도 LiveData는 설정 후 알림을 보냅니다.
val observableFld = ObservableField<Int>()
observableFld.set(5)
observableFld.set(5)
observableFld.set(5) // 最初の1回しか通知されない(=onChangedは呼ばれない)
val liveData = MutableLiveData<Int>()
liveData.postValue(5)
liveData.postValue(5)
liveData.postValue(5)// 3回とも通知される(=onChangedが呼ばれる)
값이 변경되면 ViewModel에 있는 속성을 알려 주고 View 측면에서 해당 속성을 감지하고 업데이트합니다.상식이야, LiveData도 꼭 그렇게 될 거야, 그렇지만, 달라(on
Changed
...).이 일을 모르면 다음과 같은 위험이 있다.
"고려할 필요 없음"은 다음과 같이 화면의 EditText 및 ViewModel LiveData 의 TwoWay 바인딩을 실현합니다.
// viewModel.user の TwoWay バインド
// EditText -> LiveData
editUserName.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
val userName = editUserName.text;
viewModel.user.postValue(userName.toString())
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { }
override fun afterTextChanged(p0: Editable?) { }
})
// LiveData -> EditText
viewModel.user.observe(this, Observer { userName ->
editUserName.setTextKeepState(userName ?: "")
})
editUserName.setTextKeepState(viewModel.user?.value ?: "")
이 코드는 처음editUserName.setTextKeepState
을 터치로 TextWatcher를 진행합니다.onTextChanged 및 LiveData.observe 무한 반복.이번에는 Text Watcher입니다.onTextChanged에서 등가 검사를 하고 회피했지만 의외의 고장이 발생할 수 있습니다.
setValue는 UI 스레드에서 호출되어야 합니다(postValue 사용).
실제 LiveData 값을 설정할 수 있는 클래스
MutableLiveData<T>
: setValue()
및 postValue()
에는 두 가지 값 업데이트 방법이 있습니다.처음에는
setValue()
만 알고 사용했지만 비 UI 스레드에서 (Retrofit의 리셋 스레드에서) setValue()
사용하면 Illegal은 드디어 Exception이 나온 셈이다.LiveData 코드를 추적할 때 다음 그림과 같이 UI 스레드가 맞는지 확인하고 예외를 발생합니다.
음, Live Data의 set Value, 주 스레드에서 호출하지 않으면 잘못된 건가요?그것은 Observe 측(즉 View-Binding 측)에서 관리하는 것이다.ReactiveProperty. - 아미@ 하이델라 기다리기(@amay077)pic.twitter.com/jSkXT4LK8w
하지만 그 뒤에도 2017년 11월 2일 씨도
postValue()
있어요!가르침을 청하다p>
Mutable LiveData #postValue 안 되나요?p>— Keita Kagurazaka (@kkagurazaka) @kkagurazaka
2017年11月3日는 UI 스레드에서 값을 업데이트하고 알림하는 방법입니다.p>
모델 측면의 처리는 일반적으로 비동기식 즉 비UI 스레드를 전제로 하기 때문에 postVata
실제로는 사용할 수 없다p>
그리고 LiveData는 UI 스레드에 강하게 의존하므로 ViewModel에서 반대편까지 사용하지 말아야 합니다.p>
반대setValue
의LiveData
는UI 스레드에서진행이 보장되므로특별히observe
등을할 필요가 없습니다.p>
ObservableField と併用不可?
그렇다면 DataBinding은 runOnUiThread
의 기본 클래스 또는 BaseObservale
을 필요로 합니다.가령 AAC=ObservavleField
를 기류로 사용하는 경우가 많기 때문에 전자는 실제로 사망한다.DataBinding을 사용하려면 ObservableField만 사용할 수 있습니다.하지만 ObservableField와 LiveData는 현재 아무런 관계가 없는 반이기 때문에
- DataBinding을 원한다면 ObservableField
- Lifecycle aware 코드를 쓰고 싶다면 LiveData
를 구분해서 사용해야 합니다.비록 목적은 다르지만 늘 미묘하게 느껴진다p>
2017/12/21 追記
LiveData가 DataBinding을 지원합니다.즉, ViewModel
필요 없는 아이가 될 가능성p>
You can now use a LiveData object as an observable field in data binding expressions.(계속)
변경 알림이 아니라'값만 내려준다'는 LiveData가 데이터 귀속을 할 수 있는데 어떻게 될지 흥미롭습니다.계속 보도하도록 하겠습니다.p>
Solutions?
불평만으로는 해결할 수 없으니 현상황을 타개할 수 있는 방법을 모색해 보자.
Kotlin이라면 확장 방법을 사용할 수 있으니 편리한 확장 방법을 만들어서 사용하면 되지 않을까요?p>
「値が変わった時だけ」通知を行う LiveData の拡張メソッドを作る
먼저, "LiveData는 값 변경과 무관하게 통지됨"에 관하여 값이 변경되었는지 확인하고, 변경되었을 때만 통지하는 확장 방법을 만들었습니다.p>
fun <T> LiveData<T>.observeOnChanged(owner: LifecycleOwner, observer: Observer<T>) : Unit {
var prev : T? = null
this.observe(owner, Observer<T> {
if (!(prev?.equals(it) ?: false)) {
observer.onChanged(it)
}
prev = it
})
}
// 使う方
val liveData = MutableLiveData<Int>()
liveData.observeOnChanged(owner, Observer {
Log.d(TAG, "$it")
});
liveData.postValue(5)
liveData.postValue(5)
liveData.postValue(5)// 最初の1回しか onChanged は呼ばれない
やっぱり Observable がイイ!
LiveData의 구독 관리가 수월해지는 것은 좋지만
map
과switchMap(flatMap かな)
등 최소한의 합성법만 있다는 점과 DataBinding의 병용이 번거로워 보인다는 점은 미묘하다p>ViewModel의 반대편(Usecase층과 Repository층)의 I/F는Observable<T>
이거나 서로 변환하고 싶은 물건이라면 ViewModel도 사용하고 싶다Observable<T>
p>
그래서 저는 ObservableField, LiveData, RxJava를 좋은 느낌으로 함께 사용할 수 있는 방법을 생각해 봤습니다. 그래서 내일의 "Android Studio Release Updates: Android Studio 3.1 Canary 6 is now available에 적었습니다.p>
Reference
이 문제에 관하여(Live Data에 대한 몇 가지 오해가 있습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/amay077/items/6e1c94305420a41ff7ed텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)