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

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

问题描述

我有一个应用程序在新的 Google Play 控制台 - Android 生命体征部分慢渲染中被列为倒数 25%.我对此感到担忧,因为

这是从 systrace 中获取的两张图片,它展示了 UI 线程在一帧内运行的工作.顶部是使用 layout_width=wrap_content 完成的,底部是使用 layout_width=match_parent 完成的.

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

  • 如果您以较短的跨度(如 16 毫秒)发布可运行文件(seekBar.postDelayed(runnable, 16)),您将获得平滑的 60fps:

    P/s:我还不知道为什么.

  • 使用其他方式更新 count 值,而不是在 Runnable 内.使用 View.postOnAnimation(Runnable) 重新调度 Runnable.示例项目的结果是 60FPS.

两个使用 postOnAnimation(Runnable)

Runnable

可运行可运行 =新的可运行(){@覆盖公共无效运行(){textView.setText(Integer.toString(count));seekBar.setProgress(count);seekBar.postOnAnimation(this);}};Runnable updateCount = new Runnable() {@Override public void run() {++计数;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 Vitals)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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