如何修复缓慢渲染(Android vitals)
我有一个应用程序,在新的Google Play控制台-Android vitals部分的底部25%中列出,用于慢速渲染。我之所以担心这一点,是因为谷歌Play似乎说,如果你排名垫底25%,谷歌Play可能会在Play商店排名中惩罚你的应用程序 然而,似乎不可能改进我的应用程序的这一指标。它播放音乐,并有一个SeekBar和TextView,每250毫秒更新一次,就像任何音乐播放器一样。我制定了最低限度的基本程序来演示:如何修复缓慢渲染(Android vitals),android,google-play,frame-rate,Android,Google Play,Frame Rate,我有一个应用程序,在新的Google Play控制台-Android vitals部分的底部25%中列出,用于慢速渲染。我之所以担心这一点,是因为谷歌Play似乎说,如果你排名垫底25%,谷歌Play可能会在Play商店排名中惩罚你的应用程序 然而,似乎不可能改进我的应用程序的这一指标。它播放音乐,并有一个SeekBar和TextView,每250毫秒更新一次,就像任何音乐播放器一样。我制定了最低限度的基本程序来演示: public class MainActivity extends AppC
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);
}
}
此处为完整项目:
当我在与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
这意味着几乎我所有的帧都需要>16毫秒来渲染,我猜这是由于更新的周期性。据我所知,我测试过的所有其他音乐播放器应用程序也存在这种缓慢的渲染问题。我担心谷歌的算法会破坏我的应用程序排名,有什么办法可以提高我的分数吗?你版面中的
TextView
导致了这个问题。因为它有wrap_content
的layout width
,也就是说它的宽度必须等于内容的宽度(本例中的文本)。因此,每次调用TextView.setText
时,都必须进行昂贵的度量/布局过程。只需将layout\u width
设置为match\u parent
即可解决此问题
这里有两张图片是从systrace
中拍摄的,它演示了在一个框架中在UI线程上运行的工作。顶部是用layout\u width=wrap\u content
完成的,底部是用layout\u width=match\u parent
完成的
我测试过的以下两种方法将提高帧速率:
- 如果以较短的跨度(如16ms)发布runnable(
),您将获得平滑的60fps: 附言:我还不知道为什么seekBar.postDelayed(runnable,16)
- 使用其他方法更新
值,而不是在计数
中。使用可运行
重新安排Runnable。对于示例项目,结果为60FPSView.postOnAnimation(Runnable)
Runnable
使用postOnAnimation(Runnable)
我查过你的密码了。不确定这是否是实际代码,或者您对此是否有更多了解。无论如何,我将提请大家注意android中的一些渲染问题 1。透支 Overdraw是一种浪费GPU处理时间的方法,它以像素为单位进行着色,而像素只会被其他东西再次着色。如果在父容器布局中添加了背景,然后在子容器布局中也添加了背景,或者在应用程序主题的样式文件中添加了公共背景,然后在创建的其余xml布局文件中添加了背景,则这些背景可能很常见 透支的原因可能是任何原因,请检查您的代码。在所有移动设备中都安装了一个开发者工具来检查开发者选项中的Overdraw。是透支的官方文件 2。查看层次结构 要渲染每个视图,Android将经历三个阶段: 1.措施 2.布局 3.抽签 Android完成这些阶段所需的时间与层次结构中的视图数量成正比。我在布局文件中看到,您有约束布局,其中包括线性布局。我看不出这有什么用。引入约束布局以帮助开发人员减少视图层次结构。减少特定布局可以包含的子级数。还有一个工具可以帮助您实现这一点。是android的官方指南。
尝试以下步骤来解决GPU渲染问题。我在Moto X Pure和Galaxy S8+上设置了布局宽度,以匹配父帧,并且仍然大部分是简陋的帧。虽然使用X Pure,“慢速UI线程”类别的帧数很少,第90-99百分位帧数减少到20毫秒多一点。你是在谈论示例项目还是你的生产应用程序?即使使用match_Parentation,示例项目上的Janky帧你是如何使用postOnAnimation()获得60 FPS的,这对我不起作用。您的意思是只更新postOnAnimation()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);
}
};