【问题标题】:How to optimize setTint如何优化 setTint
【发布时间】:2021-02-17 19:03:14
【问题描述】:

我正在制作一级方程式灯光系统。因此,我创建了一个颜色为#212121 的圆圈网格。当我尝试更改颜色时,它给了我错误:

2021-02-17 09:41:25.186 29905-29905/com.example.ligthsouttimer I/Choreographer: Skipped 241 frames!  The application may be doing too much work on its main thread.

当我只改变一个圆圈时没有问题,但现在它不断跳过所有事情发生的帧。
我正在手机上运行(三星 Galaxy A40)。


我的 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">

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

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="25dp"
            android:layout_marginTop="50dp"
            android:layout_marginEnd="25dp"
            android:layout_marginBottom="50dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintDimensionRatio="h,3:2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/blk_rectangle" />

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:orientation="vertical"
            android:padding="5dp"
            app:layout_constraintBottom_toBottomOf="@+id/imageView"
            app:layout_constraintEnd_toEndOf="@+id/imageView"
            app:layout_constraintStart_toStartOf="@+id/imageView"
            app:layout_constraintTop_toTopOf="@+id/imageView">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:orientation="horizontal">

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle11"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle21"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle31"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle41"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle51"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:orientation="horizontal">

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle12"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle22"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle32"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle42"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle52"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:orientation="horizontal">

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle13"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle23"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle33"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle43"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle53"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:orientation="horizontal">

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle14"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle24"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle34"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle44"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <ImageView
                        android:id="@+id/circle54"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:padding="5dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintDimensionRatio="w,1:1"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:srcCompat="@drawable/circle" />
                </androidx.constraintlayout.widget.ConstraintLayout>

            </LinearLayout>

        </LinearLayout>

        <Button
            android:id="@+id/start_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/imageView" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

我的圈子xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <solid
        android:color="#212121" />

</shape>

我的颜色 xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#6200EE</color>
    <color name="colorPrimaryDark">#3700B3</color>
    <color name="colorAccent">#03DAC5</color>

    <color name="black">#000000</color>
    <color name="red">#ff0000</color>
    <color name="grey">#212121</color>
</resources>

我的 MainActivity.kt:

package com.example.ligthsouttimer

import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.ShapeDrawable
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.databinding.DataBindingUtil
import com.example.ligthsouttimer.databinding.ActivityMainBinding
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.view.*

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        setContentView(R.layout.activity_main)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        binding.startBtn.setOnClickListener {
            DrawableCompat.setTint(circle13.drawable,ContextCompat.getColor(applicationContext, R.color.red))
            DrawableCompat.setTint(circle14.drawable,ContextCompat.getColor(applicationContext, R.color.red))
            Thread.sleep(1_000)
            DrawableCompat.setTint(circle23.drawable,ContextCompat.getColor(applicationContext, R.color.red))
            DrawableCompat.setTint(circle24.drawable,ContextCompat.getColor(applicationContext, R.color.red))
            Thread.sleep(1_000)
            DrawableCompat.setTint(circle33.drawable,ContextCompat.getColor(applicationContext, R.color.red))
            DrawableCompat.setTint(circle34.drawable,ContextCompat.getColor(applicationContext, R.color.red))
            Thread.sleep(1_000)
            DrawableCompat.setTint(circle43.drawable,ContextCompat.getColor(applicationContext, R.color.red))
            DrawableCompat.setTint(circle44.drawable,ContextCompat.getColor(applicationContext, R.color.red))
            Thread.sleep(1_000)
            DrawableCompat.setTint(circle53.drawable,ContextCompat.getColor(applicationContext, R.color.red))
            DrawableCompat.setTint(circle54.drawable,ContextCompat.getColor(applicationContext, R.color.red))

            var random_sleep = (2..3000).random().toLong()
            Thread.sleep(random_sleep)

            DrawableCompat.setTint(circle13.drawable,ContextCompat.getColor(applicationContext, R.color.grey))
            DrawableCompat.setTint(circle14.drawable,ContextCompat.getColor(applicationContext, R.color.grey))
            DrawableCompat.setTint(circle23.drawable,ContextCompat.getColor(applicationContext, R.color.grey))
            DrawableCompat.setTint(circle24.drawable,ContextCompat.getColor(applicationContext, R.color.grey))
            DrawableCompat.setTint(circle33.drawable,ContextCompat.getColor(applicationContext, R.color.grey))
            DrawableCompat.setTint(circle34.drawable,ContextCompat.getColor(applicationContext, R.color.grey))
            DrawableCompat.setTint(circle43.drawable,ContextCompat.getColor(applicationContext, R.color.grey))
            DrawableCompat.setTint(circle44.drawable,ContextCompat.getColor(applicationContext, R.color.grey))
            DrawableCompat.setTint(circle53.drawable,ContextCompat.getColor(applicationContext, R.color.grey))
            DrawableCompat.setTint(circle54.drawable,ContextCompat.getColor(applicationContext, R.color.grey))
        }

    }
}

【问题讨论】:

    标签: android xml kotlin optimization android-databinding


    【解决方案1】:

    首先,可以通过扁平化结构来优化您的 xml 布局。应该可以将所有图像视图放置在单个 ConstraintLayout 中,并删除中间的 LinearLayouts 和 ConstraintLayouts。
    这应该会使视图膨胀和布局通过速度更快。


    话虽如此,实际问题是这样的:

            var random_sleep = (2..3000).random().toLong()
            Thread.sleep(random_sleep)
    

    调用Thead.sleep阻塞线程,这意味着在时间结束之前它不能做任何其他事情。此代码在主线程上执行,因此整个应用程序在睡眠时被冻结且无响应,因此“应用程序可能在其主线程上做了太多工作”。消息。


    在 Android 中使用Handler 可以最轻松地安排一些代码稍后运行。示例:

    val delay = (2..3000).random().toLong()
    Handler(Looper.getMainLooper()).postDelayed({
        // code to run after delay
    }, delay)
    

    删除Thread.sleep 调用并将所有setTint 调用延迟到该函数内应该可以解决阻塞问题。

    【讨论】:

      【解决方案2】:

      @Robco 的回答很中肯,使用Kotlin 会有所改进,您可以利用Coroutines,尤其是在这种情况下。 Handler 的问题是您需要将所有后续调用嵌套在延迟中,并且如果我必须做一些总延迟为 7 秒的事情,也没有适当的取消政策,这可能会导致崩溃根据你的代码,我更喜欢协程方式

      val tintJob = Job() // you can cancel it in onDestroy
      binding.startBtn.setOnClickListener {
          tintJob = CoroutineScope(Dispatchers.Main).launch {
              applyRedTintFor13_14()
              delay(1_000)
              applyRedTintFor23_24()
              delay(1_000)
              applyRedTintFor33_34()
              delay(1_000)
              applyRedTintFor43_44()
              delay(1_000)
              applyRedTintFor53_54()
              delay(1_000)
              delay((2..3000).random().toLong())
              applyGreyTintToAll()
         }
      }
      

      如果你使用coroutine android extensions,可以直接使用lifeCyclScope,当状态不活动时会自行销毁

      binding.startBtn.setOnClickListener {
         lifeCycleScope.launch {
              applyRedTintFor13_14()
              delay(1_000)
              applyRedTintFor23_24()
              delay(1_000)
              applyRedTintFor33_34()
              delay(1_000)
              applyRedTintFor43_44()
              delay(1_000)
              applyRedTintFor53_54()
              delay(1_000)
              delay((2..3000).random().toLong())
              applyGreyTintToAll()
         }
      }
      

      【讨论】:

      • 每个带有“应用”的句子都会给出错误未解决的参考。它也给出了一个错误,当按下 alt + enter 时,它在 tintJob 之后放置了“as CompletableJob”。我不知道这是否有什么不同。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-12
      • 1970-01-01
      • 2011-12-18
      • 2011-04-09
      • 2021-02-02
      • 2010-12-20
      • 1970-01-01
      相关资源
      最近更新 更多