3

最近、アプリの重大なパフォーマンスの問題に気付きました。私は基本的に次のレイアウトを持っています... ここに画像の説明を入力

説明
要するに、ページとしてViewPager3 を保持する a がありRelativeLayoutます。各ページ内には多数の がありTextViewます。最近、オートコンプリート用の簡単な SQL クエリを実行するためにEditTextを入力すると、多くの遅延が発生することに気付きました。TextWatcher私の HTC One M8 は、テキストを入力するときに途切れたり遅れたりしますが、約 7 ミリ秒しかかからないクエリを測定したので、遅いのはクエリではないことがわかります。

メソッド プロファイリング、Systrace、および昔ながらのLogデバッグを使用した結果、文字を入力するたびに、EditText1,700 の呼び出しが A、B、および C内のonMeasureで行われていることがわかりました。累積すると、全体で約 15 個の独立した しかありません。ページ。通常は1 回か 2 回ではなく、それぞれが何百回も呼び出されていることに気付きました。TextViewRelativeLayoutTextViewonMeasure

質問 ページ B に を入力すると、ページ A と C の他の も「再測定」される
理由がわかりません。さらに重要なことに、なぜが頻繁に呼び出されるのかについて洞察を持っている人はいますか? そして、への呼び出しの数を大幅に減らす解決策を知っている人はいますか?EditTextTextViewonMeasureonMeasure

詳細
これは役立つかもしれません:onMeasure呼び出しRelativeLayoutの伝播onMeasureViewPager.

4

1 に答える 1

7

特定の問題を特定するのに十分な情報はありませんが、一般的に何が起こっているかを伝えることができます。

ルート ビューをmeasure呼び出すと、各サブビューが呼び出さmeasureれ、ツリーを下っていきます。

「現在のビュー」と呼ばれるビューが、そのサブビューのそれぞれに自分自身を測定するように依頼した後、すべての子ビューに十分なスペースがないと判断したとします。最大サイズを提案して、それぞれにもう一度自分自身を測定するように求めます。次に、「Relative Layout B」というビューが、指定された最大値に基づいて根本的にサイズを変更するとします。変化があまりにも大きいため、「現在のビュー」は各子供にもう一度尋ねなければなりません。このループを解決するには、あと数回の反復が簡単に必要になる可能性があります。

「現在のビュー」がそのサイズを決定すると、「ビュー ページャー」に報告します。「View Pager」に 3 つのビューを表示するのに十分なスペースがなく、再測定を依頼する必要があるとします。現在、TextView のonMeasure. ViewPager の上の他の各ビューが数回繰り返されると、すぐに大きな数値が表示されるようになります。

すでに指摘したように、最善の解決策は、そのツリーの深さを減らすことです。あるいは、はるかに単純な測定アルゴリズム (FrameLayout、LinearLayout) を持つレイアウト マネージャーを使用することもできます。

1500は多いけど。それらのビューの 1 つは、奇妙なことをしています。DDMS スイートの TreeView ツールを使用すると、非常に簡単に識別できるはずです。日食では「TreeView」と呼ばれます。Studio で Android アイコンをクリックし、Hierarchy View パースペクティブに切り替えます。SDK ツール ディレクトリから、コマンド ラインから実行することもできます。

追加: 実行中に Hierarchy Viewer をアプリに接続すると、ビュー ツリー全体がいずれかのペインに表示されます。ツリーの各ノードには、下部に向かって 3 つの色付きのガムドロップがあります。最初のガムドロップは測定フェーズを表します。ガムドロップが緑色の場合、そのビューの測定フェーズは高速です。黄色の場合、そのノードはレイアウト内のノードの上位 50 パーセンタイルにあります。赤の場合、レイアウトで最も遅いです。

問題のあるビューまで黄色のトレイルをたどることができるはずです。

于 2014-08-15T18:27:22.667 に答える