这有点疯狂,但是观察者停止进行配置更改。奇怪的是,观察者在onActivityCreated中执行时可以完美地工作,但是如果我在另一部分中执行观察者,它将停止进行配置更改。
这是我的代码,第一个代码效果很好,但是第二个代码是问题。调用视图模型的方式是相同的,所以我不太了解哪个是真正的问题。
从已创建活动的服务器中获取数据
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.user_fragment, container, false)
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel::class.java)
binding.viewModel = userViewModel
userViewModel.loadData().observe(
viewLifecycleOwner,
Observer<Resource<Response<UserModel>>> {this.handleResponse(it)}
)
}
private fun handleResponse(response: Resource<Response<UserModel>>?) {
when (response.estado) {
State.ERROR -> {
hideProgressBar()
}
State.LOADING -> {
showProgressBar()
}
State.SUCCESS -> {
hideProgressBar()
// Display data
}
}
}
虽然我正在从服务器中获取数据并且设备已旋转,但观察者仍处于活动状态并继续获取数据。问题出在哪里?这里没有问题。继续阅读:
现在我有了数据,我已经进行了一些修改,我想调用我的API。所以:
binding.btSubmit.setOnClickListener {
userViewModel.saveUser().observe(
viewLifecycleOwner,
Observer<Resource<Response<SuccessModel>>> {this.handleSaveResponse(it)}
)
}
private fun handleSaveResponse(response: Resource<Response<SuccessModel>>?) {
when (response.estado) {
State.ERROR -> {
hideProgressBar()
}
State.LOADING -> {
showProgressBar()
}
State.SUCCESS -> {
hideProgressBar()
// Call another fragment
}
}
}
这是问题所在!当我保存数据并旋转设备时,观察者停止工作(进度消失,并且从未调用State.SUCCESS)
我不会粘贴与存储库或视图模型有关的信息,因为使用相同的存储库和相同的Viewmodel,一个观察者可以工作,而另一个则不行。所以我认为与此无关。
谢谢!
编辑
UserViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.project.db.entity.*
import com.project.repository.ApplicationRepository
import javax.inject.Inject
class UserViewModel @Inject constructor(repository: ApplicationRepository)
: ViewModel() {
var userModel: MutableLiveData<UserModel> = MutableLiveData()
init {
userModel.value = UserModel()
}
val data = repository.getData()
fun saveUser(): LiveData<Resource<Response<SuccessModel>>> {
return repository.saveUser(userModel.value!!)
}
}
ApplicationRepository
import androidx.lifecycle.LiveData
import com.project.repository.util.ApiResponse
import com.project.repository.util.AppExecutors
import com.project.repository.util.NetworkOnlyBoundResource
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class ApplicationRepository @Inject
internal constructor(
val mAppExecutors: AppExecutors){
fun saveUser(userModel: UserModel): LiveData<Response<Response<SuccessModel>>> {
return object : NetworkOnlyBoundResource<Response<SuccessModel>>(mAppExecutors) {
override fun saveResponse(item: Response<SuccessModel>) {
userDao.saveUser(item.model!!)
}
override fun crearLlamada(): LiveData<ApiResponse<Response<SuccessModel>>> {
return userService.saveUser(userModel)
}
}.asLiveData()
}
}
编辑2 这就是我称呼另一个片段的方式:
fragmentManager.beginTransaction()
.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
.replace(containerId, fragment)
.setReorderingAllowed(true)
.addToBackStack(fragment.javaClass.simpleName)
.commitAllowingStateLoss()
答案 0 :(得分:0)
旋转设备onStop
时,将删除所有观察者服务器。由于onActivityCreated
在生命周期路径上,因此将重新观察实时数据。但是,由于您的onClick观察是事件驱动的,因此不会自动重新观察。另一个问题是,由于实时数据是在saveUser
调用中生成的,由于引用丢失,您将无法重新观察它。
编辑:
这是一个潜在的解决方案。
class UserViewModel @Inject constructor(repository: ApplicationRepository)
: ViewModel() {
private val userModel: MutableLiveData<UserModel> = MutableLiveData()
val data = repository.sincronizarExpedienteDos() // You only need to load this once calling loadData every onCreate wastes the livedata.
private val saveTrigger = MutableLiveData<Boolean>()
val saveStateLiveData = Transformations.switchMap(savetrigger) {
val userValue = userModel.value
return@switchMap if (it == null || userValue == null) {
MutableLiveData().apply {
value = null
}
else {
repository.saveUser(userValue)
}
}
init {
userModel.value = UserModel()
}
fun saveUser() {
saveTrigger.value = true
}
fun resetSaveTrigger() {
saveTrigger.value = null
}
}
然后在您的片段中:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel::class.java)
binding.viewModel = userViewModel
binding.btSubmit.setOnClickListener {
userViewModel.saveUser()
}
userViewModel.data.observe(
viewLifecycleOwner,
Observer<Resource<Response<UserModel>>> {this.handleResponse(it)}
)
userViewModel.saveStateLiveData.observe(
viewLifecycleOwner,
Observer<Resource<Response<SuccessModel>>> {this.handleSaveResponse(it)}
)
}
private fun handleResponse(response: Resource<Response<UserModel>>?) {
when (response.estado) {
State.ERROR -> {
hideProgressBar()
}
State.LOADING -> {
showProgressBar()
}
State.SUCCESS -> {
hideProgressBar()
// Display data
viewModel.resetSaveTrigger()
}
}
}
private fun handleSaveResponse(response: Resource<Response<SuccessModel>>?) {
when (response.estado) {
State.ERROR -> {
hideProgressBar()
}
State.LOADING -> {
showProgressBar()
}
State.SUCCESS -> {
hideProgressBar()
// Call another fragment
}
}
}
这种方法可以重新观察实时数据,而无需生成其他数据。