【发布时间】:2020-08-15 19:31:23
【问题描述】:
我正在 SplashActivity 中加载联系人:
private fun startMainActivity() {
repository.loadContacts()
handler.postDelayed({
val intent =Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}, SPLASH_DELAY.toLong())
这是我的存储库类:
@Singleton
class ContactsRepository @Inject constructor(
private val context: Context,
private val schedulerProvider: BaseSchedulerProvider) {
private val compositeDisposable = CompositeDisposable()
private val _liveData = MutableLiveData<Resource<List<Contact>>>()
val liveData: LiveData<Resource<List<Contact>>>
get() = _liveData
fun loadContacts() {
_liveData.value = Resource.Loading()
val cursor = context.contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
PROJECTION,
null,
null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE UNICODE ASC")
Observable.create(ObservableOnSubscribe<List<Contact>>
{ emitter -> emitter.onNext(ContactUtil.getContacts(cursor, context)) })
.subscribeOn(schedulerProvider.io())
.doOnComplete { cursor?.close() }
.doFinally { compositeDisposable.clear() }
.subscribe {
_liveData.postValue(Resource.Success(it))
}.also { compositeDisposable.add(it) }
}
}
在我的 MainFragment onCreateView 中,我在 viewModel 中观察 LiveData :
// Create the observer which updates the UI.
final Observer<Resource<List<Contact>>> contactsObserver = resource -> {
if (resource instanceof Resource.Success) {
mContacts = ((Resource.Success<List<Contact>>) resource).getData();
mAdapter.setItems(mContacts, true);
}
};
// Observe the LiveData, passing in this fragment as the LifecycleOwner and the observer.
viewModel.getLiveData().observe(this, contactsObserver);
}
这是我的 ViewModel 类:
class ContactsViewModel(repository: ContactsRepository) : ViewModel() {
private val _liveData = repository.liveData
val liveData: LiveData<Resource<List<Contact>>>
get() = _liveData
/**
* Factory for constructing ContactsViewModel with parameter
*/
class Factory @Inject constructor(
private val repository: ContactsRepository
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(ContactsViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return ContactsViewModel(repository) as T
}
throw IllegalArgumentException("Unable to construct viewmodel")
}
}
}
有时当我在很长一段时间后恢复 MainFragment 时,我会在 RecyclerView 中看到一个没有数据的空屏幕(例如,可能容器活动被操作系统杀死)。我的猜测是 repository.liveData.value 返回 null。这可能是任何其他问题。感谢您的建议。
附录:
@Inject
ContactsViewModel.Factory mFactory;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ContactsViewModel viewModel = new ViewModelProvider(this, mFactory).get(ContactsViewModel.class);
ViewDataBinding binding = FragmentContactsBinding.bind(root);
binding.setVariable(BR.vm, viewModel);
binding.setLifecycleOwner(getViewLifecycleOwner());
}
【问题讨论】:
-
看起来进程已终止,UI 已从保存的实例状态恢复。 ViewModel 将在配置更改后继续存在,但在进程死亡后不会恢复(如 Options for preserving UI state 中所述) Fragment 如何“获取” ViewModel?
-
谢谢@BömachtBlau 我已将 ViewModel 初始化添加到问题的附录部分。
标签: android android-livedata android-viewmodel