如何修复慢速渲染(Android维权) [英] How to fix Slow Rendering (Android vitals)
问题描述
我有一款应用在新版Google Play控制台 - 低延迟渲染的Android vitals部分中列为最低25%。我很担心这是因为
下面是从 systrace
中取得的两张图片,它演示了在1帧中在UI线程上运行的工作。最上面的是 layout_width = wrap_content
,最下面的是 layout_width = match_parent
。
我测试过的以下两种方法可以提高帧速率: b 如果你以16ms( P / s:我不确定为什么。 使用其他方式更新
$ b
seekBar.postDelayed(runnable,16)
)的较短跨度发布runnable,您可以获得这种平滑的60fps:
count
值,而不是在可运行
。使用 View.postOnAnimation(Runnable)
重新安排Runnable。样本项目的结果是60FPS。编辑:
two Runnable
使用
$ b 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);
}
};
I have an app that is listed as in the bottom 25% in the new Google Play Console - Android vitals section for Slow Rendering. I am concerned of this because of such articles that seem to say Google Play may penalize your app in the Play Store rankings if you fall in the bottom 25%.
However, it seems impossible to improve this metric for my app. It plays music and has a SeekBar and TextView which is updated every 250ms as any music player would. I made the minimum basic program to demonstrate:
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);
}
}
Full project here: https://github.com/svenoaks/SlowRendering.git
When I run this program on hardware similar to the Nexus devices, I get these results for a
adb shell dumpsys gfxinfo com.example.xyz.slowrendering
command:
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
This would mean almost all my frames taking >16ms to render, I guess due to the periodic nature of the updating. All other music player apps I have tested also have this Slow Rendering problem as far as I can see. I fear Google's algorithm ruining my app ranking, is there any way I can improve my score?
The TextView
in your layout is causing the problem. Because it has layout width
of wrap_content
, which said that it's width has to be equals to the width of the content (the text in this example). Therefore, every time you call TextView.setText
an expensive measure/layout pass has to occur. Simple setting the layout_width
to match_parent
will solve the issue.
Here are two images what is taken from systrace
, it demonstrate the work run on the UI thread in 1 frame. The top one is done with layout_width=wrap_content
and the bottom one is with layout_width=match_parent
.
Two following methods that i have tested will improve the frame rate:
If you post the runnable in shorter span like 16ms (
seekBar.postDelayed(runnable, 16)
), you get this smooth 60fps:P/s: I am not sure why yet.
Use some other way to update the
count
value instead of inside theRunnable
. UseView.postOnAnimation(Runnable)
to reschedule the Runnable. The result is 60FPS for the sample project.
EDIT:
two Runnable
that uses 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);
}
};
这篇关于如何修复慢速渲染(Android维权)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!