如何解决慢速渲染(Android的重要)

我有一个应用程序在新的Google Play控制台 – 慢动作渲染的Android重要部分中列为最低的25%。 我担心这一点,因为这些文章似乎认为Google Play可能会在Play商店排名中惩罚您的应用程序,如果您跌至最低的25%。

但是,我的应用程序似乎不可能改进这个指标。 它播放音乐,并有一个SeekBar和TextView每250毫秒更新任何音乐播放器会。 我做了最基本的程序来演示:

public class MainActivity extends AppCompatActivity { int count; SeekBar seekBar; TextView textView; Runnable runnable = new Runnable() { @Override public void run() { textView.setText(Integer.toString(count)); seekBar.setProgress(count); ++count; seekBar.postDelayed(runnable, 250); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); seekBar = (SeekBar) findViewById(R.id.seek); textView = (TextView) findViewById(R.id.text); seekBar.post(runnable); } } 

完整的项目在这里: https : //github.com/svenoaks/SlowRendering.git

当我在类似于Nexus设备的硬件上运行这个程序时,我得到了这些结果
adb shell dumpsys gfxinfo com.example.xyz.slowrendering命令:

 Stats since: 19222191084749ns Total frames rendered: 308 Janky frames: 290 (94.16%) 90th percentile: 32ms 95th percentile: 36ms 99th percentile: 44ms Number Missed Vsync: 2 Number High input latency: 0 Number Slow UI thread: 139 Number Slow bitmap uploads: 0 Number Slow issue draw commands: 283 

这将意味着几乎所有的帧都需要16ms的渲染时间,我想这是由于更新的周期性。 据我所知,我testing过的所有其他音乐播放器应用程序也都有这个慢速渲染问题。 我担心谷歌的algorithm毁了我的应用排名,有什么办法可以提高我的分数吗?

您的布局中的TextView导致了问题。 因为它具有wrap_content layout width ,它的宽度必须等于内容的宽度(本例中的文本)。 因此,每次调用TextView.setText时,都必须进行昂贵的度量/布局传递。 简单地将layout_width设置为match_parent将解决问题。

在这里输入图像说明

在这里输入图像说明

这里有两个图像来自systrace ,它展示了在1个框架中在UI线程上运行的工作。 最上面的是layout_width=wrap_content ,最下面的是layout_width=match_parent

我已经testing了以下两种方法将会提高帧速率:

  • 如果以16ms( seekBar.postDelayed(runnable, 16) )的较短跨度seekBar.postDelayed(runnable, 16)可以获得这种平滑的60fps: 在这里输入图像说明

    P / S:我不确定为什么。

  • 使用其他方式来更新count数值,而不是在Runnable 。 使用View.postOnAnimation(Runnable)重新安排Runnable。 样本项目的结果是60FPS。

编辑:使用postOnAnimation(Runnable)两个Runnable

 Runnable runnable = new Runnable() { @Override public void run() { textView.setText(Integer.toString(count)); seekBar.setProgress(count); seekBar.postOnAnimation(this); } }; Runnable updateCount = new Runnable() { @Override public void run() { ++count; seekBar.postDelayed(this, 250); } }; 

我检查了你的代码。 不知道这是否是实际的代码,或者如果你有更多这样的。 在任何情况下,我会提请注意一些在Android中的渲染问题。

1. OverDraw

Overdraw是你浪费GPU处理时间的地方。 如果您已经为父容器布局添加了背景,然后又添加了背景,或者如果您为应用程序主题的样式文件添加了公共背景,然后将背景添加到其余的xml,则这些可能很常见你创build的布局文件。

透支的原因可以是任何东西,请尝试检查你的代码。 在所有移动设备上都安装了一个开发者工具来检查开发者选项中的透支。 这是透支的官方文件。

2.查看层次结构

为了呈现每个视图,Android经历了三个阶段:

1.测量

2.layout

3.draw

Android完成这些阶段所花费的时间与您的层次结构中的视图数量成正比。 我在你的布局文件中看到,你有包含线性布局的约束布局。 我没有看到这个用法。 引入了约束布局来帮助开发人员减less视图层次结构。 减less一个特定的布局可以有的孩子的数量。 还有一个工具来帮助你。 这是官方的Android指南。 尝试这些步骤来找出GPU渲染问题。