Инфляция привязки данных очень медленная - PullRequest
0 голосов
/ 25 июня 2019

В настоящее время я использую DataBinding с RecyclerView, и у меня довольно серьезное отставание при первой загрузке списка. Однако после того, как я прокручиваю страницу и она перестает создавать новые видоискатели, все в порядке.

Во время создания единственное, что я делаю, это надуваю макет с помощью DataBindingUtils, поэтому мне интересно, есть ли части, которые можно улучшить.

Ниже приведены соответствующие фрагменты кода. В настоящее время я использую библиотеку, 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)

По сути, у меня обычно есть одна модель данных, которую я устанавливаю, и я реализую привязку самостоятельно для каждого владельца. Кажется, там нет проблем.

Читая другие статьи, кажется, что большинство разработчиков используют тот же метод создания виджетов, что и я. Разве 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

1 Ответ

0 голосов
/ 26 июня 2019

Я сделал еще несколько измерений и обнаружил, что виновником на самом деле была инфляция макета (т.е. 60 мс) вместо просто привязки (то есть 3 мс). Чтобы проверить, надуйте представление как есть без DataBindingUtil, затем вызовите bind в представлении.

Оттуда проблема заключалась также в использовании MaterialChips. После переключения 6 текстовых фишек на текстовые просмотры время инфляции уменьшилось в 3 раза до 10-30 мс.

...