在我的应用程序中,我从本地数据库加载数据,这非常慢。我试图找出缓慢的原因,并且发现这是由于LiveData引起的。
我创建了一个示例应用程序来测试LiveData的速度,这里是我的测试代码:
FirstFragment:
class FirstFragment : Fragment(), FirstFragmentCallback {
private val TAG = FirstFragment::class.java.simpleName
private var mViewModel: FirstFragmentViewModel? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mViewModel = ActivityUtils.obtainViewModel(requireActivity(), FirstFragmentViewModel::class.java)
(mViewModel as FirstFragmentViewModel).callback = this
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val v = inflater.inflate(R.layout.first_fragment, container, false)
Log.d(TAG, "onCreateView called")
registerObservables()
mViewModel?.loadData()
return v
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val secondFragmentButton = view.findViewById<Button>(R.id.second)
secondFragmentButton.setOnClickListener {
ActivityUtils.replaceFragmentInActivity(requireFragmentManager(), SecondFragment(), R.id.container, false)
}
}
private fun registerObservables(){
mViewModel?.dataLoadedEvent?.observe(this, Observer {
Log.d(TAG, "dataLoaded event")
})
mViewModel?.dataLoaded2Event?.observe(this, Observer {
Log.d(TAG, "dataLoaded2 event")
})
}
override fun dataLoaded() {
Log.d(TAG, "dataLoaded callback")
}
}
FirstFragmentViewModel:class FirstFragmentViewModel(val mAppliction: Application): AndroidViewModel(mAppliction) {
val dataLoadedEvent: SingleLiveEvent<Void> = SingleLiveEvent()
val dataLoaded2Event: MutableLiveData<Void> = MutableLiveData()
var callback: FirstFragmentCallback? = null
fun loadData(){
dataLoadedEvent.postValue(null)
dataLoaded2Event.postValue(null)
callback?.dataLoaded()
}
}
如果我运行此片段,则会在LogCat中得到它们:您可以看到
dataLoadedEvent.postValue(null)
至少需要30毫秒,但是简单的回调会立即被调用。有什么解决方案可以加快LiveData事件的速度吗?
最佳答案
postValue()
用于您要从后台线程更新MutableLiveData
的情况。在幕后,它使用Handler
将您的事件路由到主应用程序线程。因此,随着其他主应用程序线程工作队列事件得到处理,将存在一些延迟。
它还说明您的基准测试存在缺陷(“将苹果与橙子进行比较”)。要么:
Handler
代替回调(或其他一些“在主应用程序线程上运行此代码”方法)或setValue()
(或者因为您在Kotlin就是value=
)而不是postValue()
来直接在主应用程序线程MutableLiveData
内容