emit
はdata
クラスを受け入れますが、emitSource
は_LiveData<T>
_を受け入れます(T-> data
)。次の例を考えてみます:-私には2種類の呼び出しがあります:-
_suspend fun getData(): Data // returns directly data
_
もう1つ;
_suspend fun getData(): LiveData<Data> // returns live data instead
_
最初のケースでは私が使うことができます:-
_liveData {
emit(LOADING)
emit(getData())
}
_
私の質問:上記の方法を使用すると問題が解決します[〜#〜] why [〜#〜]とにかくemitSource(liveData)
が必要ですか?
emitSource
メソッドを使用するための良いユースケースは、それを明確にするでしょう!
私は、本番環境で何度も使用してきたemitSource
よりもemit
を使用した実際のユースケースを見つけました。 :Dユースケース:
いくつかのUser
から返されたいくつかのユーザーデータ(userId
、userName
などのいくつかのフィールドを持つApiService
)があるとします。
User
モデル:
_data class User(var userId: String, var userName: String)
_
userName
は、UIをペイントするためにビュー/アクティビティで必要です。そして、userId
は、UserData
、profileImage
のようなemailId
を返すanother API呼び出しを行うために使用されます。
UserData
モデル:
_data class UserData(var profileImage: String, var emailId: String)
_
これは、内部でemitSource
を使用して実現できます2つのliveDataを接続することによりViewModel
のように:
User
liveData-
_val userLiveData: LiveData<User> = liveData {
emit(service.getUser())
}
_
UserData
liveData-
_val userDataLiveData: LiveData<UserData> = liveData {
emitSource(userLiveData.switchMap {
liveData {
emit(service.getUserData(it.userId))
}
})
}
_
したがって、アクティビティ/ビューでは[〜#〜] only [〜#〜] call getUser()
とすると、getUserData(userId)
は自動的にトリガーされます内部でswitchMap
を介して。
Idを渡してgetUserData(id)
を呼び出す必要はありません手動で。
これは単純な例ですが、依存するタスクのチェーンが次々に実行される必要があると想像してください。それぞれがアクティビティで観察されます。
emitSource
はhandy
に入っています
emitSource()を使用すると、単一の値を出力できるだけでなく、LiveDataを別のLiveDataにアタッチして、そこからの出力を開始できます。とにかく、emit()またはemitSource()を呼び出すたびに、以前に追加されたソースが削除されます。
var someData = liveData {
val cachedData = dataRepository.getCachedData()
emit(cachedData)
val actualData = dataRepository.getData()
emitSource(actualData)
}
SomeDataオブジェクトを監視するアクティビティは、デバイス上のキャッシュデータをすばやく受信し、UIを更新します。次に、LiveData自体がネットワーク要求を行い、キャッシュされたデータを新しいライブストリームのデータに置き換えます。これにより、最終的にアクティビティオブザーバーがトリガーされ、更新された情報でUIが更新されます。