新しいGoogle Play ConsoleのAndroid Vitalsセクションの「レンダリングが遅い」で下位25%にランクされているアプリがあります。私はこれを心配しています。そのような記事これは、Google Play が Play ストアのランキングでアプリの順位が下位 25% に入るとペナルティを課す可能性があることを示唆しているようです。
しかし、私のアプリではこの指標を改善するのは不可能のようです。このアプリは音楽を再生し、他の音楽プレーヤーと同様に 250 ミリ秒ごとに更新される 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 のアルゴリズムによってアプリのランキングが台無しになるのではないかと心配していますが、スコアを向上させる方法はありますか?
ベストアンサー1
レイアウト内のがTextView
問題の原因です。 があるためですlayout width
。wrap_content
の幅はコンテンツ (この例ではテキスト) の幅と同じでなければなりません。そのため、 を呼び出すたびに、TextView.setText
コストのかかる測定/レイアウト パスを実行する必要があります。 を に設定するだけで、layout_width
問題match_parent
は解決します。
以下は から取得した 2 つの画像ですsystrace
。これは、1 フレームで UI スレッドで実行された作業を示しています。上の画像は で実行されlayout_width=wrap_content
、下の画像は で実行されたものですlayout_width=match_parent
。
私がテストした次の 2 つの方法でフレーム レートが向上します。
実行可能ファイルを 16 ミリ秒 (
seekBar.postDelayed(runnable, 16)
) のような短いスパンで投稿すると、次のようなスムーズな 60 fps が得られます。P/s: 理由はまだわかりません。
count
内部ではなく他の方法で値を更新しますRunnable
。 を使用してView.postOnAnimation(Runnable)
、Runnable を再スケジュールします。 結果は、サンプル プロジェクトで 60 FPS になります。
編集:Runnable
使用する2つ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);
}
};