问题描述
我正在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,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中没有数据(例如,容器活动可能被OS杀死)。我的猜测是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());
}
完整的源代码位于:https://github.com/Ali-Rezaei/Contacts/blob/master/app/src/main/java/com/sample/android/contact/ui/ContactsFragment.java
解决方法
我意识到这是由于系统启动的进程死亡。结果,我在ViewModel的init方法中添加了以下代码来解决此问题:
class ContactsViewModel(repository: ContactsRepository) : ViewModel() {
private val _liveData = repository.liveData
val liveData: LiveData<Resource<List<Contact>>>
get() = _liveData
init {
// Reload contacts in case of system initiated process death
if(liveData.value == null) {
repository.loadContacts()
}
}
}