相对较小的自定义布局(旋转器)存在巨大的性能问题

发布于 2025-01-11 05:47:43 字数 6506 浏览 0 评论 0原文

我已经发布了关于此主题的问题,并了解了如何改进,但遗憾的是性能仍然很差。

问题
我有以下布局,用作自定义微调器。我还计算了其通货膨胀的时间,如下所示。问题是通货膨胀至少需要100ms。大多数时候,在我的小米 9 lite 测试设备上,它要高得多(例如 150 毫秒)或以上。想象一下显示三个旋转器。充气时间将为半秒(实际上在某些屏幕上)。

如何大幅缩短充气时间?如果您查看另一篇文章,您会发现我正在为自定义 EditText 使用非常相似的布局,优化后现在“仅”需要大约 25 毫秒。我不明白为什么旋转器需要这么多时间。

非常感谢任何帮助。这将是日志行的示例 D/[Stopwatch]: CustomSpinner [Inflation]: 0 s, 195 ms

public CustomSpinner(@NonNull Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    Stopwatch sw = Stopwatch.createStarted("CustomSpinner");
    b = CustomSpinnerBinding.inflate(LayoutInflater.from(context), this);
    setClipToPadding(false);
    setClipChildren(false);
    int pxPadding = GuiUtils.dpToPx(getContext(), 8);
    setPadding(pxPadding, 0, pxPadding, 0);
    sw.logRound("Inflation");
}

以及布局(用于 Shadow 的 CardView,用于 Spinner 文本的 TextView - TextInputLayout 之一)将位于前面图标上方,因此我需要添加另一个 TextView 来接管):

<merge 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"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:clipChildren="false"
   android:clipToPadding="false"
   android:paddingStart="8dp"
   android:paddingEnd="8dp"
   tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">

<androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/tv_label"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="14dp"
    android:textSize="15sp"
    app:fontFamily="@font/nunito2"
    app:layout_constraintEnd_toEndOf="@id/cardView"
    app:layout_constraintStart_toStartOf="@id/cardView"
    app:layout_constraintTop_toTopOf="parent"
    tools:text="Label" />

<androidx.cardview.widget.CardView
    android:id="@+id/cardView"
    android:layout_width="0dp"
    android:layout_height="48dp"
    android:layout_marginTop="7dp"
    app:cardCornerRadius="12dp"
    app:cardElevation="3dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/tv_label"
    app:layout_goneMarginTop="9dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/til_spinner"
            style="@style/App.ExposedDropdownMenu"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            app:boxStrokeWidth="0dp"
            app:boxStrokeWidthFocused="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <AutoCompleteTextView
                android:id="@+id/actv_spinner"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@null"
                android:backgroundTint="@android:color/transparent"
                android:inputType="none" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.imageview.ShapeableImageView
            android:id="@+id/iv_start_icon"
            android:layout_width="20dp"
            android:layout_height="0dp"
            android:layout_marginStart="19dp"
            android:layout_marginTop="15dp"
            android:layout_marginBottom="15dp"
            android:adjustViewBounds="true"
            android:visibility="gone"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:srcCompat="@drawable/icon_other"
            tools:tint="?attr/colorPrimary"
            tools:visibility="visible"/>

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/tv_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="13dp"
            android:layout_marginEnd="45dp"
            android:textSize="13sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0"
            app:layout_constraintStart_toEndOf="@id/iv_start_icon"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_goneMarginStart="19dp"
            tools:text="Item" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

<androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/tv_helper"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="14dp"
    android:layout_marginTop="7dp"
    android:alpha="0.44"
    android:textSize="9sp"
    android:visibility="invisible"
    app:layout_constraintEnd_toEndOf="@id/cardView"
    app:layout_constraintStart_toStartOf="@id/cardView"
    app:layout_constraintTop_toBottomOf="@id/cardView"
    tools:ignore="SmallSp"
    tools:text="Helper"
    tools:visibility="visible" />

</merge>

Profiler Update 我无法使用 Profiler 解决问题,因为问题是 Android 本机代码造成的。您可以在图片中看到的 TextInputLayout 的 Inflation 需要 126.27 毫秒。但如果我使用 TextInputLayout 而不使用 CustomLayout,它就可以正常工作。所以这里有一些严重错误

在此处输入图像描述

在此处输入图像描述

GIT MWE
请演示我将所有重要文件复制到新项目中的问题。看看这个 git

在我的小米 Mi9 Lite 上运行此命令会产生以下输出:
CustomSpinner [通货膨胀]:0 秒,295 毫秒
CustomSpinner [通货膨胀]:0 秒,101 毫秒
CustomSpinner [通货膨胀]:0 秒,96 毫秒
CustomSpinner [通货膨胀]:0 秒,104 毫秒
CustomSpinner [通货膨胀]:0 秒,134 毫秒

I already posted a question on this topic and got ideas how to improve but sadly the performance still ist pretty bad.

Problem
I have the following layout which I use as a custom spinner. Also I timed its inflation as you can see below. The problem is that the inflation takes at least 100ms. Most of the times it is way higher (like 150ms) and above on my xiaomi mi 9 lite testing device. Imagine having three spinners displayed. Inflation time would be half a second (and actually is on some screens).

How to reduce inflation time significantly? If you have a look at the other post you will see that I am using a very similar layout for a custom EditText which 'only' takes around 25ms now after optimizing. I do not understand why the spinner needs so much more time.

Any help is highly appreciated. This would be an example of a logline D/[Stopwatch]: CustomSpinner [Inflation]: 0 s, 195 ms

public CustomSpinner(@NonNull Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    Stopwatch sw = Stopwatch.createStarted("CustomSpinner");
    b = CustomSpinnerBinding.inflate(LayoutInflater.from(context), this);
    setClipToPadding(false);
    setClipChildren(false);
    int pxPadding = GuiUtils.dpToPx(getContext(), 8);
    setPadding(pxPadding, 0, pxPadding, 0);
    sw.logRound("Inflation");
}

And the layout (CardView for Shadow, TextView for the Spinner text - The one of the TextInputLayout would be above the front icon so I needed to add another TextView that takes over):

<merge 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"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:clipChildren="false"
   android:clipToPadding="false"
   android:paddingStart="8dp"
   android:paddingEnd="8dp"
   tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">

<androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/tv_label"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="14dp"
    android:textSize="15sp"
    app:fontFamily="@font/nunito2"
    app:layout_constraintEnd_toEndOf="@id/cardView"
    app:layout_constraintStart_toStartOf="@id/cardView"
    app:layout_constraintTop_toTopOf="parent"
    tools:text="Label" />

<androidx.cardview.widget.CardView
    android:id="@+id/cardView"
    android:layout_width="0dp"
    android:layout_height="48dp"
    android:layout_marginTop="7dp"
    app:cardCornerRadius="12dp"
    app:cardElevation="3dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/tv_label"
    app:layout_goneMarginTop="9dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/til_spinner"
            style="@style/App.ExposedDropdownMenu"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            app:boxStrokeWidth="0dp"
            app:boxStrokeWidthFocused="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <AutoCompleteTextView
                android:id="@+id/actv_spinner"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@null"
                android:backgroundTint="@android:color/transparent"
                android:inputType="none" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.imageview.ShapeableImageView
            android:id="@+id/iv_start_icon"
            android:layout_width="20dp"
            android:layout_height="0dp"
            android:layout_marginStart="19dp"
            android:layout_marginTop="15dp"
            android:layout_marginBottom="15dp"
            android:adjustViewBounds="true"
            android:visibility="gone"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:srcCompat="@drawable/icon_other"
            tools:tint="?attr/colorPrimary"
            tools:visibility="visible"/>

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/tv_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="13dp"
            android:layout_marginEnd="45dp"
            android:textSize="13sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0"
            app:layout_constraintStart_toEndOf="@id/iv_start_icon"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_goneMarginStart="19dp"
            tools:text="Item" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

<androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/tv_helper"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="14dp"
    android:layout_marginTop="7dp"
    android:alpha="0.44"
    android:textSize="9sp"
    android:visibility="invisible"
    app:layout_constraintEnd_toEndOf="@id/cardView"
    app:layout_constraintStart_toStartOf="@id/cardView"
    app:layout_constraintTop_toBottomOf="@id/cardView"
    tools:ignore="SmallSp"
    tools:text="Helper"
    tools:visibility="visible" />

</merge>

Profiler Update
I cannot fix my problem with the Profiler as it is Android Native code that is making the problems. The Inflation of the TextInputLayout that you can see on the picture takes 126.27 ms. But if I use the TextInputLayout without my CustomLayout it works just fine. So there is something terribly wrong here

enter image description here

enter image description here

GIT MWE
Do demonstrate the issue I copied all essential files into a new project. Have a look at this git.

Running this produces the following output on my Xiaomi Mi9 Lite:
CustomSpinner [Inflation]: 0 s, 295 ms
CustomSpinner [Inflation]: 0 s, 101 ms
CustomSpinner [Inflation]: 0 s, 96 ms
CustomSpinner [Inflation]: 0 s, 104 ms
CustomSpinner [Inflation]: 0 s, 134 ms

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文