首页 > 解决方案 > 为什么 LiveData 很慢

问题描述

在我的应用程序中,我从本地数据库加载数据,速度非常慢。我试图找出慢的地方,我发现这是因为 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 中得到这些:

2019-05-15 13:23:07.405 8632-8632/livedatatest D/FirstFragment: onCreateView 调用

2019-05-15 13:23:07.406 8632-8632/livedatatest D/FirstFragment: dataLoaded 回调

2019-05-15 13:23:07.438 8632-8632/livedatatest D/FirstFragment: dataLoaded 事件

2019-05-15 13:23:07.439 8632-8632/livedatatest D/FirstFragment: dataLoaded2 事件

您可以看到这dataLoadedEvent.postValue(null)至少需要 30 毫秒,但是会立即调用简单的回调。

有什么解决方案可以加快 LiveData 事件的速度吗?

标签: androidkotlinandroid-livedata

解决方案


您可以看到 dataLoadedEvent.postValue(null) 至少需要 30ms

postValue()当您想MutableLiveData从后台线程更新时。在幕后,它使用 aHandler将您的事件路由到主应用程序线程。因此,当其他主应用程序线程工作队列事件得到处理时,会有一些延迟。

它还说明您的基准测试存在缺陷(“将苹果与橙子进行比较”)。任何一个:

  • 使用Handler而不是回调(或其他一些“在主应用程序线程上运行此代码”方法),或

  • 使用setValue()(或者value=因为您在 Kotlin 中)而不是,直接在主应用程序线程上postValue()更新内容MutableLiveData


推荐阅读