Data Binding inflation is very slow

All*_*n W 6 android kotlin android-recyclerview android-databinding

I'm currently using DataBinding with a RecyclerView, and I'm getting pretty severe lag when a list first loads. However, after I scroll past a page and it stops creating new viewholders, everything is fine.

During creation, the only thing I'm doing is inflating a layout using DataBindingUtils, so I'm wondering if there are parts that can be improved.

Attached below are relevant code snippets. I'm currently using a library, FastAdapter, so the signatures will not match exactly

When creating a viewholder, I do the following:


override fun createView(ctx: Context, parent: ViewGroup?): View {
    val start = System.nanoTime()
    val binding: ViewDataBinding = DataBindingUtil.inflate(
        LayoutInflater.from(ctx),
        layoutRes, parent,
        false,
        null
    )
    L.d { "Create view ${(System.nanoTime() - start) / 1000000}" }
    return binding.root
}
Run Code Online (Sandbox Code Playgroud)

It appears that for my more complex layout, viewholders take around 30-60 ms each, resulting in notable lag.

Binding and unbinding are like so:

final override fun bindView(holder: ViewHolder, payloads: MutableList<Any>) {
    super.bindView(holder, payloads)
    val binding = DataBindingUtil.getBinding<Binding>(holder.itemView) ?: return
    binding.bindView(holder, payloads)
    binding.executePendingBindings()
}

open fun Binding.bindView(holder: ViewHolder, payloads: MutableList<Any>) {
    setVariable(BR.model, data)
}

final override fun unbindView(holder: ViewHolder) {
    super.unbindView(holder)
    val binding = DataBindingUtil.getBinding<Binding>(holder.itemView) ?: return
    binding.unbindView(holder)
    binding.unbind()
}

open fun Binding.unbindView(holder: ViewHolder) {}

final override fun getViewHolder(v: View): ViewHolder = ViewHolder(v, layoutRes)
Run Code Online (Sandbox Code Playgroud)

Basically, I usually have a single data model that I set, and I implement unbinding myself per viewholder. There doesn't seem to be a problem there.

Reading other articles, it appears that most developers have the same viewholder creation method as I do. Is DataUtilBinding not meant to be done upon creation, or is there something I'm missing?

As an addition, here is my relevant layout xml:


override fun createView(ctx: Context, parent: ViewGroup?): View {
    val start = System.nanoTime()
    val binding: ViewDataBinding = DataBindingUtil.inflate(
        LayoutInflater.from(ctx),
        layoutRes, parent,
        false,
        null
    )
    L.d { "Create view ${(System.nanoTime() - start) / 1000000}" }
    return binding.root
}
Run Code Online (Sandbox Code Playgroud)

I've tried doing the same thing with two linear layouts instead of ConstraintLayout, but it doesn't seem to make much of a difference.


Code snapshot: https://github.com/AllanWang/GitDroid/tree/f802c991580d70470b422186fc43f46b9cfe2465

All*_*n W 6

我做了一些更多的测量,发现罪魁祸首实际上是布局膨胀(即 60 毫秒),而不仅仅是绑定(即 3 毫秒)。要验证,DataBindingUtilbind在没有 的情况下按原样膨胀视图,然后调用该视图。

从那里,问题也出在 MaterialChip 的使用上。将 6 个材料芯片切换到文本视图后,充气时间下降了 3 倍,大约为 10-30 毫秒。