每次调用 Activity 的 onCreate() 时都会调用存储库中的刷新(不在屏幕旋转中)
Refresh in Repository get called every time onCreate() of Activity called ( not in screen rotation )
我在 Github 中有以下项目:https://github.com/AliRezaeiii/TVMaze
我已经开始在示例应用程序中使用 Koin 作为依赖注入框架:
class TVMazeApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
androidContext(this@TVMazeApplication)
modules(networkModule)
modules(persistenceModule)
modules(repositoryModule)
modules(viewModelModule)
}
}
}
这是我的存储库 class :
class ShowRepository(
private val dao: ShowDao,
private val api: TVMazeService,
private val context: Context
) {
/**
* A list of shows that can be shown on the screen.
*/
val shows = resultLiveData(
databaseQuery = {
Transformations.map(dao.getShows()) {
it.asDomainModel()
}
},
networkCall = { refreshShows() })
/**
* Refresh the shows stored in the offline cache.
*/
private suspend fun refreshShows(): Result<List<Show>> =
try {
if (isNetworkAvailable(context)) {
val shows = api.fetchShowList().await()
dao.insertAll(*shows.asDatabaseModel())
Result.success(shows)
} else {
Result.error(context.getString(R.string.failed_internet_msg))
}
} catch (err: HttpException) {
Result.error(context.getString(R.string.failed_loading_msg))
}
}
还有我的 ViewModel:
class MainViewModel(
repository: ShowRepository
) : ViewModel() {
private val _shows = repository.shows
val shows: LiveData<Result<List<Show>>>
get() = _shows
}
我在我的 Activity 中观察 LiveData :
viewModel.shows.observe(this, Observer { result ->
when (result.status) {
Result.Status.SUCCESS -> {
binding.loadingSpinner.hide()
viewModelAdapter.submitList(result.data)
}
Result.Status.LOADING -> binding.loadingSpinner.show()
Result.Status.ERROR -> {
binding.loadingSpinner.hide()
Snackbar.make(binding.root, result.message!!, Snackbar.LENGTH_LONG).show()
}
}
})
当我点击“后退”按钮时,Activity 被销毁(但应用程序实例仍然存在,因为我可以从最近的应用程序访问它)。当我再次启动应用程序时,我期望调用 refreshShows() 方法,但它永远不会被调用。
但是当我通过清除最近的应用程序并启动应用程序来销毁应用程序实例时,会调用 refreshShows()。
每次调用 Activity 的 onCreate()
回调时,我应该如何调用 refreshShows()?
fun <T, A> resultLiveData(databaseQuery: () -> LiveData<T>,
networkCall: suspend () -> Result<A>): LiveData<Result<T>> =
liveData(Dispatchers.IO) {
emit(Result.loading<T>())
val source = databaseQuery.invoke().map { Result.success(it) }
emitSource(source)
val result = networkCall.invoke()
if (result.status == Result.Status.ERROR) {
emit(Result.error<T>(result.message!!))
emitSource(source)
}
}
您存储库中的 refreshShows() 仅在完成新的网络请求时才会被调用。您的 livedata 的想法是在重新创建其 fragment/activity 时提供最新结果,因此当您的屏幕旋转或您恢复 activity 它不会触发另一个请求,因为 livedata 已经具有最新结果并且您与您的网络没有状态连接 database/server(如果您正在观察来自 Room 的数据,它会收到最新的更改)。
我发现 "fix" 最简单的方法就是让你的视图模型 val 显示 很有趣,就像这样:
class MainViewModel(
repository: ShowRepository
) : ViewModel() {
private val _shows = repository.shows()
val shows: LiveData<Result<List<Show>>>
get() = _shows
}
但是这样使用,每次屏幕旋转时都会进行新的网络调用,从而调用您的 refreshShows()
我在 Github 中有以下项目:https://github.com/AliRezaeiii/TVMaze
我已经开始在示例应用程序中使用 Koin 作为依赖注入框架:
class TVMazeApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
androidContext(this@TVMazeApplication)
modules(networkModule)
modules(persistenceModule)
modules(repositoryModule)
modules(viewModelModule)
}
}
}
这是我的存储库 class :
class ShowRepository(
private val dao: ShowDao,
private val api: TVMazeService,
private val context: Context
) {
/**
* A list of shows that can be shown on the screen.
*/
val shows = resultLiveData(
databaseQuery = {
Transformations.map(dao.getShows()) {
it.asDomainModel()
}
},
networkCall = { refreshShows() })
/**
* Refresh the shows stored in the offline cache.
*/
private suspend fun refreshShows(): Result<List<Show>> =
try {
if (isNetworkAvailable(context)) {
val shows = api.fetchShowList().await()
dao.insertAll(*shows.asDatabaseModel())
Result.success(shows)
} else {
Result.error(context.getString(R.string.failed_internet_msg))
}
} catch (err: HttpException) {
Result.error(context.getString(R.string.failed_loading_msg))
}
}
还有我的 ViewModel:
class MainViewModel(
repository: ShowRepository
) : ViewModel() {
private val _shows = repository.shows
val shows: LiveData<Result<List<Show>>>
get() = _shows
}
我在我的 Activity 中观察 LiveData :
viewModel.shows.observe(this, Observer { result ->
when (result.status) {
Result.Status.SUCCESS -> {
binding.loadingSpinner.hide()
viewModelAdapter.submitList(result.data)
}
Result.Status.LOADING -> binding.loadingSpinner.show()
Result.Status.ERROR -> {
binding.loadingSpinner.hide()
Snackbar.make(binding.root, result.message!!, Snackbar.LENGTH_LONG).show()
}
}
})
当我点击“后退”按钮时,Activity 被销毁(但应用程序实例仍然存在,因为我可以从最近的应用程序访问它)。当我再次启动应用程序时,我期望调用 refreshShows() 方法,但它永远不会被调用。
但是当我通过清除最近的应用程序并启动应用程序来销毁应用程序实例时,会调用 refreshShows()。
每次调用 Activity 的 onCreate()
回调时,我应该如何调用 refreshShows()?
fun <T, A> resultLiveData(databaseQuery: () -> LiveData<T>,
networkCall: suspend () -> Result<A>): LiveData<Result<T>> =
liveData(Dispatchers.IO) {
emit(Result.loading<T>())
val source = databaseQuery.invoke().map { Result.success(it) }
emitSource(source)
val result = networkCall.invoke()
if (result.status == Result.Status.ERROR) {
emit(Result.error<T>(result.message!!))
emitSource(source)
}
}
您存储库中的 refreshShows() 仅在完成新的网络请求时才会被调用。您的 livedata 的想法是在重新创建其 fragment/activity 时提供最新结果,因此当您的屏幕旋转或您恢复 activity 它不会触发另一个请求,因为 livedata 已经具有最新结果并且您与您的网络没有状态连接 database/server(如果您正在观察来自 Room 的数据,它会收到最新的更改)。
我发现 "fix" 最简单的方法就是让你的视图模型 val 显示 很有趣,就像这样:
class MainViewModel(
repository: ShowRepository
) : ViewModel() {
private val _shows = repository.shows()
val shows: LiveData<Result<List<Show>>>
get() = _shows
}
但是这样使用,每次屏幕旋转时都会进行新的网络调用,从而调用您的 refreshShows()