【问题标题】:Data Binding inflation is very slow数据绑定膨胀非常缓慢
【发布时间】:2019-06-25 03:29:28
【问题描述】:

我目前正在使用带有 RecyclerView 的 DataBinding,当列表首次加载时,我的延迟非常严重。但是,当我滚动浏览一个页面并且它停止创建新的视图时,一切都很好。

在创建过程中,我唯一要做的就是使用DataBindingUtils 填充布局,所以我想知道是否有可以改进的部分。

下面附上相关代码sn-ps。我目前正在使用一个库,FastAdapter,所以签名不会完全匹配

创建视图时,我会执行以下操作:


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
}

似乎对于我更复杂的布局,每个视图都需要大约 30-60 毫秒,从而导致明显的延迟。

绑定和解绑是这样的:

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)

基本上,我通常设置一个单一的数据模型,并且我自己实现每个视图的解除绑定。那里似乎没有问题。

阅读其他文章,似乎大多数开发人员都有与我相同的viewholder创建方法。 DataUtilBinding 不是要在创建时完成,还是我遗漏了什么?

作为补充,这是我的相关布局 xml:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="model"
            type="github.fragment.ShortRepoRowItem" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:windowBackground"
        android:foreground="?selectableItemBackground"
        android:paddingStart="@dimen/kau_activity_horizontal_margin"
        android:paddingTop="@dimen/kau_padding_small"
        android:paddingEnd="@dimen/kau_activity_horizontal_margin"
        android:paddingBottom="@dimen/kau_padding_small"
        tools:context=".activity.MainActivity">

        <TextView
            android:id="@+id/repo_name"
            style="@style/TextAppearance.AppCompat.Medium"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="@{model.name}"
            android:textColor="?android:textColorPrimary"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="@tools:sample/full_names" />

        <TextView
            android:id="@+id/repo_desc"
            style="@style/TextAppearance.AppCompat.Caption"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxLines="2"
            android:text="@{model.description}"
            android:textColor="?android:textColorSecondary"
            app:goneFlag="@{model.description}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/repo_name"
            tools:text="@tools:sample/lorem/random" />

        <com.google.android.material.chip.Chip
            android:id="@+id/repo_stars"
            style="@style/RepoChips"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:chipIcon="@drawable/ic_star_border"
            app:compactNumberText="@{model.stargazers.totalCount}"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/repo_desc"
            app:layout_constraintWidth_percent="0.12"
            tools:text="123" />

        <com.google.android.material.chip.Chip
            android:id="@+id/repo_forks"
            style="@style/RepoChips"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:chipIcon="@drawable/ic_fork"
            app:compactNumberText="@{model.forkCount}"
            app:layout_constraintStart_toEndOf="@id/repo_stars"
            app:layout_constraintTop_toBottomOf="@id/repo_desc"
            app:layout_constraintWidth_percent="0.12"
            tools:text="123" />

        <com.google.android.material.chip.Chip
            android:id="@+id/repo_issues"
            style="@style/RepoChips"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:chipIcon="@drawable/ic_issues"
            app:compactNumberText="@{model.issues.totalCount}"
            app:layout_constraintStart_toEndOf="@id/repo_forks"
            app:layout_constraintTop_toBottomOf="@id/repo_desc"
            app:layout_constraintWidth_percent="0.12"
            tools:text="1.5k" />

        <com.google.android.material.chip.Chip
            android:id="@+id/repo_prs"
            style="@style/RepoChips"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:chipIcon="@drawable/ic_pull_requests"
            app:compactNumberText="@{model.pullRequests.totalCount}"
            app:layout_constraintStart_toEndOf="@id/repo_issues"
            app:layout_constraintTop_toBottomOf="@id/repo_desc"
            app:layout_constraintWidth_percent="0.12"
            tools:text="123" />

        <com.google.android.material.chip.Chip
            android:id="@+id/repo_language"
            style="@style/RepoChips"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="@{model.primaryLanguage.name}"
            app:chipIcon="@drawable/ic_language"
            app:languageColor="@{model.primaryLanguage.color}"
            app:layout_constraintEnd_toStartOf="@id/repo_date"
            app:layout_constraintStart_toEndOf="@id/repo_prs"
            app:layout_constraintTop_toBottomOf="@id/repo_desc"
            app:layout_constraintWidth_percent="0.25"
            tools:text="JavaScript" />

        <com.google.android.material.chip.Chip
            android:id="@+id/repo_date"
            style="@style/RepoChips"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:chipIcon="@drawable/ic_time"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@id/repo_language"
            app:layout_constraintTop_toBottomOf="@id/repo_desc"
            app:relativeDateText="@{model.pushedAt}"
            app:textStartPadding="4dp"
            tools:text="@tools:sample/date/mmddyy" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

我试过用两个线性布局而不是 ConstraintLayout 做同样的事情,但它似乎没有太大的区别。


代码快照:https://github.com/AllanWang/GitDroid/tree/f802c991580d70470b422186fc43f46b9cfe2465

【问题讨论】:

  • 这里能不能展示一下viewholder的初始化,大部分时候,问题都出在那部分代码上。
  • createView 下。基本上,然后我通过传递返回的视图创建一个ViewHolder,并且库将附加一些侦听器(目前一个到itemView,绝对不是问题)。仅通过记录视图创建时间为 30-60 毫秒,所以问题似乎是正确的?
  • 您是否尝试过不使用同一个库进行数据绑定的情况?我还没有尝试过那个库,但它似乎会给你带来问题。
  • 我之前使用过这个库(并且已经为它做出了贡献),没有数据绑定并且没有任何问题,我最初在没有它的情况下编写了我的项目,然后仍然有问题。最初我认为这是因为约束布局,但我已经排除了这种情况,因为我尝试了没有它的布局。仅供参考,here 是我转换为 FastAdapter 之前的代码

标签: android kotlin android-recyclerview android-databinding


【解决方案1】:

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

从那里开始,问题还在于材料芯片的使用。 将 6 个材质芯片切换到 textviews 后,充气时间下降了 3 倍,达到 10-30ms 左右。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-12
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    相关资源
    最近更新 更多