在 Android 中,在一个 api 调用中列出 api 调用
In Android, Make a list of api call inside one api call
在我的一个 android 应用程序中,起初我想调用一个 api,它将 return 一个项目列表,并且该项目将显示在 RecyclerView 中.我还需要为 RecyclerView 的每个项目调用另一个 api 以获取该项目的描述并根据它们的 id 显示对每个项目的描述。我该如何解决这种情况。
Subject.kt
data class Subject(
val subject: String,
val subjectCode:String,
val subjectIcon: String,
val progress: Double = 0.0,
)
SubjectRepository.kt
interface SubjectRepository {
fun getAllSubject(): Observable<List<Subject>>
fun getProgressAnalysisOf(subjectCode: String): Observable<Double>
}
SubjectViewModel.kt
class HomeViewModel @Inject constructor(
private val subjectRepository: SubjectRepository,
) : BaseViewModel() {
val subjectList = MutableLiveData<List<Subject>>()
val progress = MutableLiveData<Double>
fun getAllSubject() {
compositeDisposable += subjectRepository.getAllSubject()
.performOnBackgroundOutputOnMain()
.doOnSubscribe { loader.value = true }
.doAfterTerminate { loader.value = false }
.subscribe({
subjectList.value = it
}, {
handleException(it)
})
}
fun getProgressAnalysisOf(subjectCode: String) {
compositeDisposable += subjectRepository. getProgressAnalysisOf(subjectCode)
.performOnBackgroundOutputOnMain()
.doOnSubscribe { loader.value = true }
.doAfterTerminate { loader.value = false }
.subscribe({
progress.value = it
}, {
handleException(it)
})
}
}
首先,我需要调用 getAllSubject(),它将 return 一个主题列表,然后我在 RecyclerView 中显示该列表。对于回收站视图的每个主题,我必须调用 getProgressAnalysisOf(subjectCode) 并更新该回收站视图的项目。
终于找到解决办法了。我使用 ConnectableObservable 来解决这个问题。
- 您可以注意到使用了 replay() 运算符 (getAllSubject().replay())
使 Observable 发出新订阅的数据而无需
再次重新执行逻辑。
- 在我的例子中,主题列表将在不进行
再次调用 HTTP。如果没有 replay 方法,您会注意到
getAllSubject() HTTP 调用被执行多次。
- 第一次订阅时,直接添加主题列表
Adapter class 和 RecyclerView 直接渲染而不用
主题的进度值。
- 在第二次订阅中,flatMap()用于转换列表
受个别主题发射的影响。
- 在同一个Observable上,链接了另一个flatMap来执行
每个主题发射的 getProgressAnalysisOf() 方法
获取进度值。
- 收到进度信息后,特定的行项目
在 RecyclerView 中更新。
HomeViewModel.kt
class HomeViewModel @Inject constructor(
private val subjectRepository: SubjectRepository,
) : BaseViewModel() {
val subjectList = MutableLiveData<List<Subject>>()
val progress = MutableLiveData<Double>
var subjectsObservable: ConnectableObservable<List<Subject>> = subjectRepository.getAllSubject().replay()
fun getAllSubject() {
compositeDisposable += subjectsObservable
.performOnBackgroundOutputOnMain()
.doOnSubscribe { loader.value = true }
.doAfterTerminate { loader.value = false }
.subscribe({
subjectList.value = it
}, {
handleException(it)
})
}
fun getProgressAnalysisOf() {
compositeDisposable += subjectsObservable
.performOnBackgroundOutputOnMain()
.flatMap { Observable.fromIterable(it) }
.flatMap { subjectRepository.getProgressAnalysisOf(it.code) }
.subscribe({
analysisData.postValue(it)
}, {
handleException(it)
})
}
HomeActivity.kt
class HomeFragment : BaseFragment<HomeViewModel>() {
private val subjectAdapter: SubjectAdapter by lazy {
SubjectAdapter {
}
}
override fun onResume() {
super.onResume()
viewModel.getAllSubject()
viewModel.getPerformanceAnalysisOf()
viewModel.subjectsObservable.connect()
}
override fun observeLiveData() {
observe(viewModel.subjectList) {
subjectAdapter.submitList(it)
}
observe(viewModel.analysisData) {
// update the analysis value for each item
}
}
}
在我的一个 android 应用程序中,起初我想调用一个 api,它将 return 一个项目列表,并且该项目将显示在 RecyclerView 中.我还需要为 RecyclerView 的每个项目调用另一个 api 以获取该项目的描述并根据它们的 id 显示对每个项目的描述。我该如何解决这种情况。
Subject.kt
data class Subject(
val subject: String,
val subjectCode:String,
val subjectIcon: String,
val progress: Double = 0.0,
)
SubjectRepository.kt
interface SubjectRepository {
fun getAllSubject(): Observable<List<Subject>>
fun getProgressAnalysisOf(subjectCode: String): Observable<Double>
}
SubjectViewModel.kt
class HomeViewModel @Inject constructor(
private val subjectRepository: SubjectRepository,
) : BaseViewModel() {
val subjectList = MutableLiveData<List<Subject>>()
val progress = MutableLiveData<Double>
fun getAllSubject() {
compositeDisposable += subjectRepository.getAllSubject()
.performOnBackgroundOutputOnMain()
.doOnSubscribe { loader.value = true }
.doAfterTerminate { loader.value = false }
.subscribe({
subjectList.value = it
}, {
handleException(it)
})
}
fun getProgressAnalysisOf(subjectCode: String) {
compositeDisposable += subjectRepository. getProgressAnalysisOf(subjectCode)
.performOnBackgroundOutputOnMain()
.doOnSubscribe { loader.value = true }
.doAfterTerminate { loader.value = false }
.subscribe({
progress.value = it
}, {
handleException(it)
})
}
}
首先,我需要调用 getAllSubject(),它将 return 一个主题列表,然后我在 RecyclerView 中显示该列表。对于回收站视图的每个主题,我必须调用 getProgressAnalysisOf(subjectCode) 并更新该回收站视图的项目。
终于找到解决办法了。我使用 ConnectableObservable 来解决这个问题。
- 您可以注意到使用了 replay() 运算符 (getAllSubject().replay()) 使 Observable 发出新订阅的数据而无需 再次重新执行逻辑。
- 在我的例子中,主题列表将在不进行 再次调用 HTTP。如果没有 replay 方法,您会注意到 getAllSubject() HTTP 调用被执行多次。
- 第一次订阅时,直接添加主题列表 Adapter class 和 RecyclerView 直接渲染而不用 主题的进度值。
- 在第二次订阅中,flatMap()用于转换列表 受个别主题发射的影响。
- 在同一个Observable上,链接了另一个flatMap来执行 每个主题发射的 getProgressAnalysisOf() 方法 获取进度值。
- 收到进度信息后,特定的行项目 在 RecyclerView 中更新。
HomeViewModel.kt
class HomeViewModel @Inject constructor(
private val subjectRepository: SubjectRepository,
) : BaseViewModel() {
val subjectList = MutableLiveData<List<Subject>>()
val progress = MutableLiveData<Double>
var subjectsObservable: ConnectableObservable<List<Subject>> = subjectRepository.getAllSubject().replay()
fun getAllSubject() {
compositeDisposable += subjectsObservable
.performOnBackgroundOutputOnMain()
.doOnSubscribe { loader.value = true }
.doAfterTerminate { loader.value = false }
.subscribe({
subjectList.value = it
}, {
handleException(it)
})
}
fun getProgressAnalysisOf() {
compositeDisposable += subjectsObservable
.performOnBackgroundOutputOnMain()
.flatMap { Observable.fromIterable(it) }
.flatMap { subjectRepository.getProgressAnalysisOf(it.code) }
.subscribe({
analysisData.postValue(it)
}, {
handleException(it)
})
}
HomeActivity.kt
class HomeFragment : BaseFragment<HomeViewModel>() {
private val subjectAdapter: SubjectAdapter by lazy {
SubjectAdapter {
}
}
override fun onResume() {
super.onResume()
viewModel.getAllSubject()
viewModel.getPerformanceAnalysisOf()
viewModel.subjectsObservable.connect()
}
override fun observeLiveData() {
observe(viewModel.subjectList) {
subjectAdapter.submitList(it)
}
observe(viewModel.analysisData) {
// update the analysis value for each item
}
}
}