如何修复慢速渲染(Android维权) [英] How to fix Slow Rendering (Android vitals)

查看:172
本文介绍了如何修复慢速渲染(Android维权)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一款应用在新版Google Play控制台 - 低延迟渲染的Android vitals部分中列为最低25%。我很担心这是因为





下面是从 systrace 中取得的两张图片,它演示了在1帧中在UI线程上运行的工作。最上面的是 layout_width = wrap_content ,最下面的是 layout_width = match_parent



我测试过的以下两种方法可以提高帧速率: b
$ b


  • 如果你以16ms( seekBar.postDelayed(runnable,16))的较短跨度发布runnable,您可以获得这种平滑的60fps:



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

  • 使用其他方式更新 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 the Runnable. Use View.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆