我有一个应用程序列在新Google Play控制台的最低25% - 用于慢速渲染的Android生命周期部分。我担心这一点,因为such articles似乎说Google Play可能会在Play商店排名中对您的应用进行处罚,如果您跌到最低25%。
但是,似乎无法为我的应用改进此指标。它播放音乐,并有一个SeekBar和TextView,每隔250ms更新一次,就像任何音乐播放器一样。我做了最低限度的基本程序来演示:
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
这意味着我的几乎所有帧都需要16毫米才能渲染,我想这是因为更新的周期性。据我所知,我测试的所有其他音乐播放器应用程序也有这个慢渲染问题。我担心Google的算法会破坏我的应用排名,有什么办法可以提高我的分数吗?
答案 0 :(得分:14)
布局中的TextView
导致问题。因为它有layout width
wrap_content
,它表示它的宽度必须等于内容的宽度(本例中的文本)。因此,每次调用TextView.setText
时,都必须进行昂贵的度量/布局传递。将layout_width
简单设置为match_parent
即可解决问题。
以下是从systrace
获取的两张图片,它展示了在1帧中在UI线程上运行的工作。最上面一个是layout_width=wrap_content
完成的,最后一个是layout_width=match_parent
。
我测试的以下两种方法将提高帧速率:
如果你以更短的跨度发布runnable,例如16ms(seekBar.postDelayed(runnable, 16)
),你可以得到这个平滑的60fps:
P / s:我不知道为什么。
使用其他方式更新count
值而非Runnable
内。使用View.postOnAnimation(Runnable)
重新安排Runnable。结果是示例项目的60FPS。
编辑:
使用Runnable
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);
}
};
答案 1 :(得分:2)
我检查了你的代码。不确定这是否是实际代码,或者您是否还有更多内容。在任何情况下,我都会关注android中的一些渲染问题。
<强> 1。 OverDraw
Overdraw是您通过以像素着色而浪费GPU处理时间的地方,这些像素仅通过其他内容再次着色。如果您在父容器布局中添加了背景,然后为子项添加了背景,或者在应用程序主题的样式文件中添加了常用背景,然后在xml的其余部分添加了背景,则这些可能很常见您创建的布局文件。
透支的原因可能是任何事情,请尝试检查您的代码。所有移动设备中都安装了一个开发人员工具,用于检查开发人员选项中的Overdraw。 Here是透支的官方文档。
<强> 2。查看层次结构
为了渲染每个视图,Android经历了三个阶段:
1.测量
2.layout
3.draw
Android完成这些阶段所需的时间与层次结构中的视图数量成正比。我在您的布局文件中看到您有约束布局,其中包括线性布局。我没有看到这个的使用。引入了约束布局以帮助开发人员减少视图层次结构。减少特定布局可以拥有的子项数。还有一个工具可以帮助您解决这个问题。 Here是它的官方android指南。 尝试这些步骤来找出GPU渲染问题。