RxJava를 사용하여 라이프 사이클 소유자와 의사 소통
LiveData
- 관찰할 수 있는 수명 주기 감지 데이터 소유자입니다.전형적인 용례는 ViewModel
을 속성으로 공개하는 LiveData
을 가지고 있으며, 당신의 생명주기 소유자인 Fragment
또는 Activity
에서 관찰하는 것입니다.일반적인 사용 방법은 다음과 같습니다.
data class MyState(val value: String)
class MyViewModel : ViewModel {
private val _state = MutableLiveData<MyState>()
val state: LiveData<MyState>
get() = _state
}
class MyFragment : Fragment {
val viewModel by viewModels<MyViewModel>()
override fun onViewCreated() {
viewModel.state.observe(this, Observer(::handleState))
}
private fun handleState(state: MySate): Unit = TODO()
}
LiveData
을 사용하면 다음과 같은 이점이 있습니다.실시간 데이터 및 이벤트
Snackbar
/대화 상자가 표시되거나 다른 Activity/Fragment
으로 이동할 경우 ViewModel
에 LifecycleOwner
을 알려야 합니다.일반적인 낡은 LiveData
은 마지막 항목을 캐시하기 때문에 여기에 작용하지 않는다.일종의 해결 방법으로 정부의 안드로이드 구조 예시에서 SingleLiveEvent
의 LiveData
이 실현되었다.데이터 계층
그런데 응용 프로그램의 다른 부분은요?데이터 계층에서
LiveData
을 사용할 수 있으며 실제로는 Jetpack의 지속성 라이브러리이며 로컬에서는 LiveData
을 반환 유형으로 지원합니다.그러나 응용 프로그램의 모든 층에서 LiveData
을 사용할 수 있지만 이것은 이상적이지 않다.이러한 조작은 항상 주 라인에서 실행되며, RxJava
또는 Flow
에 비해 변환 함수 수량이 제한되어 있다.이 문제를 해결하기 위해 KotlinX Coroutines는
LiveData
과 RxJava
에 어댑터를 제공했다.이는 개발자가 데이터 층에서 Flow
또는 RxJava
을 사용하고 Flow
에서 LiveData
으로 전환하여 생명주기 의식에 이익을 얻을 수 있음을 의미한다.State 및 RxJava
지난주에 Marvel API를 사용하여 예시 프로그램을 개발하고 있습니다. 당신은 Github에서 전체 코드를 볼 수 있습니다.RxJava가 지원하는 전체 반응 아키텍처를 사용합니다.나의 최초의 방법은
ViewModel
을 이용하여 LiveData
->ViewModel
통신을 하는 것이다.그러나 저도 Fragment
의 우수한 테스트 지원에서 이익을 얻고 싶어서 RxJava
을 사용하여 LiveData
이 한 일을 해보기로 했습니다.상태를 관찰하기 위해 Rxjava는
RxJava
을 제공했다. 이것은 BehaviorSubject
으로 관찰한 마지막 값을 캐시하고 구독자마다 Subject
에 보낸다.그것은 마지막 값을 캐시하고 변경 사항을 관찰합니다.메인 나사에서 관찰하면 Observer
이 있다.라이프 사이클 부분은요?이 문제를 해결하기 위해 저는 utility class을 창설하여 RxAndroid
에 구축하여 정확한 생명주기 리셋에서 구독을 처리할 수 있도록 했습니다.class LifecycleDisposable(
private val disposable: Disposable
) : DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
disposable.dispose()
super.onDestroy(owner)
}
}
다음 명령의 코드를 사용합니다.class RxViewModel : ViewModel() {
private val _state = BehaviorSubject.create<MyState>()
val state: Observable<MyState>
get() = _state
}
class RxFragment : Fragment() {
val viewModel by viewModels<MyViewModel>()
fun onViewCreated() {
viewModel.state
.subscribe(::handleState)
.autoDispose() // extension function, check the Github link
}
private fun handleState(state: MySate) = TODO()
}
LifecycleOwner
과 달리 LiveData
부터 관찰하고 onViewCreated
에서 구독을 취소한다.코드는 onDestroyView
에서 구독하고 onStart
에서 관찰을 멈추는 것과 유사하지만 제 경험에 의하면 보기가 활성화되지 않았을 때 보기 상태를 업데이트하는 것은 저에게 문제가 되지 않았습니다.이벤트 및 RxJava
사건과 상태가 좀 다르다.주요 요구는 한 번만 교부해야 한다(소모 가능).또 다른 중요한 요구는 보기가 활동 상태(
onStop
과 onStart
사이)에 있을 때만 교부하는 것이다.나의 첫 번째 시도는 onStop
을 사용하는 것이다.A Subject that queues up events until a single Observer subscribes to it, replays those events to it until the Observer catches up and then switches to relaying events live to this single Observer until this UnicastSubject terminates or the Observer unsubscribes.
그러나 결과는 이상적이지 않다.관찰자가 없는 상황에서 사건의 줄을 서는 것은 매우 효과적이다.가입 후 모든 활동이 제공됩니다.구독 서버가 있을 때 이벤트가 전달되고 있습니다.문제는 구독자가 구독을 취소하고 신규 구독자가 구독을 시도할 때(
UnicastSubject
과 onStart
은 여러 번 터치할 수 있다)다.onStop
에서 UnicastWorkSubject으로 업그레이드했습니다.A Subject variant that buffers items and allows one Observer to consume it at a time, but unlike UnicastSubject, once the previous Observer disposes, a new Observer can subscribe and resume consuming the items.
이것이 바로 내가 필요로 하는 것이다.라이프 사이클 섹션의 경우 다시
RxJavaExtensions
으로 이동하여 다음을 만듭니다.class EffectsObserver<E>(
private val effects: Observable<E>,
private val executeEffect: (E) -> Unit
) : DefaultLifecycleObserver {
private var disposable: Disposable? = null
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
disposable = effects.flatMap {
Observable.fromCallable { executeEffect(it) }
}.subscribe()
}
override fun onStop(owner: LifecycleOwner) {
disposable!!.dispose()
super.onStop(owner)
}
}
사용법은 다음과 같습니다.override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(EffectsObserver(viewModel.effects) { effect ->
when (effect) {
is NavigateToDetails -> TODO("Navigate")
}
})
}
이것은 내비게이션과 표시 LifecycleObserver
등 이벤트가 프로그램이 백엔드에 있을 때 줄을 서고 프로그램이 백엔드에 있을 때만 발생하도록 확보할 것이다.그것은 무서운 java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState을 피하는 데 도움이 된다.주의:
Snackbar
을 사용할 때, 중요한 것은 Fragment
에 그것을 등록하는 것이지, onCreate
에 등록하는 것이 아니다. (백엔드에서 세션을 여러 번 호출할 수 있다.)결론
onViewCreated
을 LiveData
->ViewModel
과 LifecycleOwner
의 통신 방식을 시뮬레이션할 수 있습니다.그러나, RxJava
이 활성 상태일 때만 사건을 교부하는 등 정확한 조작을 위해 가장자리 상황을 고려해야 합니다.만약 다른 생각이 있다면 아래에 메시지를 남겨 주세요.즐거운 코딩!
Reference
이 문제에 관하여(RxJava를 사용하여 라이프 사이클 소유자와 의사 소통), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/s_anastasov/communicating-with-your-lifecycle-owner-using-rxjava-48e5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)