web-dev-qa-db-ja.com

遅いレンダリングを修正する方法(Android Vitals)

新しいGoogle Play Consoleの下部25%に表示されているアプリがあります-Android Slow RenderingのVitalsセクション。このため、 Google Playと思われる記事 は、下位25%に該当する場合、Playストアのランキングでアプリにペナルティを課す可能性があります。

ただし、このアプリではこの指標を改善することは不可能のようです。音楽を再生し、他の音楽プレーヤーと同じように250msごとに更新されるSeekBarとTextViewがあります。私はデモンストレーションのための最小限の基本的なプログラムを作成しました:

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のアルゴリズムがアプリのランキングを台無しにすることを恐れていますが、スコアを向上させる方法はありますか?

16
Steve M

レイアウトのTextViewが問題の原因です。 _layout width_の_wrap_content_があるため、その幅はコンテンツの幅(この例ではテキスト)と等しくなければならないということです。したがって、_TextView.setText_を呼び出すたびに、高価なメジャー/レイアウトパスが発生する必要があります。 _layout_width_を_match_parent_に設定するだけで問題が解決します。

enter image description here

enter image description here

systraceから取得した2つの画像は、1フレームでUIスレッド上で実行された作業を示しています。上は_layout_width=wrap_content_で、下は_layout_width=match_parent_で行われます。

私がテストした次の2つの方法は、フレームレートを向上させます。

  • 16ms(seekBar.postDelayed(runnable, 16))のような短いスパンでランナブルをポストすると、このスムーズな60fpsが得られます: enter image description here

    追記:理由はまだわかりません。

  • count内ではなく、他の方法を使用してRunnable値を更新します。 Runnableを再スケジュールするには、View.postOnAnimation(Runnable)を使用します。結果は、サンプルプロジェクトの60FPSです。

編集:postOnAnimation(Runnable)を使用する2つの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);
    }
  };
_
16
Tin Tran

コードを確認しました。これが実際のコードなのか、それともこれ以上のことなのかわかりません。いずれにしても、Androidのレンダリングの問題のいくつかに注意を向けます。

1。オーバードロー

オーバードローは、他の色によってのみ再度色付けされるピクセルを色付けすることにより、GPU処理時間を無駄にする場所です。親コンテナレイアウトに背景を追加し、その後、子にも背景を追加した場合、またはアプリケーションテーマのスタイルファイルに共通の背景を追加してから、残りのxmlに背景を追加した場合、これらは共通になる可能性があります作成したレイアウトファイル。

オーバードローの原因は何でもかまいません。コードを確認してみてください。すべてのモバイルデバイスに開発者向けツールがインストールされており、開発者向けオプションで上書きをチェックできます。 ここ はオーバードローの公式ドキュメントです。

2。ビュー階層

各ビューをレンダリングするには、Androidは3つの段階を経ます:

1.対策

2.レイアウト

3.描く

Androidこれらのステージを完了するのにかかる時間は、階層内のビューの数に比例します。レイアウトファイルに、線形レイアウトを含む制約レイアウトがあることがわかります。私はしませんこの使用法を参照してください。制約レイアウトは、開発者がビューの階層を減らすのに役立つように導入されました。特定のレイアウトに含めることができる子の数を減らします。これを支援するツールもあります。 ここ が公式ですAndroidガイドをご覧ください。GPUレンダリングの問題を解決するには、次の手順を試してください。

3
Bawender Yandra