In my application, I load data from the local database and it's very slow. I tried to find what is slow and I found that this occurs because of LiveData.
I created a sample application to test LiveData speed here you are my test code: 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()
}
}
If I run this fragment I got these in the LogCat:
2019-05-15 13:23:07.405 8632-8632/livedatatest D/FirstFragment: onCreateView called
2019-05-15 13:23:07.406 8632-8632/livedatatest D/FirstFragment: dataLoaded callback
2019-05-15 13:23:07.438 8632-8632/livedatatest D/FirstFragment: dataLoaded event
2019-05-15 13:23:07.439 8632-8632/livedatatest D/FirstFragment: dataLoaded2 event
You can see that dataLoadedEvent.postValue(null)
take at least 30ms, but the simple callback is called immediately.
Is there any solution to speed up LiveData events?
You can see that dataLoadedEvent.postValue(null) take at least 30ms
postValue()
is for when you want to update the MutableLiveData
from a background thread. Under the covers, it uses a Handler
to route your event to the main application thread. Therefore, there will be some delay, as other main application thread work queue events get processed.
It also illustrates that your benchmark is flawed ("comparing apples to oranges"). Either:
Use Handler
instead of a callback (or some other "run this code on the main application thread" approach), or
Use setValue()
(or value=
since you are in Kotlin) instead of postValue()
, to update the MutableLiveData
content directly on the main application thread
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With