3

アクティビティを再起動するのではなく、onConfigurationChanged を介して自分でローテーションを処理している、やや複雑な Android アプリケーションがあります。デバイスまたはエミュレーターをしばらく (何度も回転させて) 使用した後、アプリケーションが断続的に正しくレイアウトされていないことに気付き始めました (ランドスケープ モードでは縦長の幅が維持されます)。

アクティビティのすべての「onAction」イベントにトレース ログ ステートメントを追加したところ、次の 2 つの異なるフローが表示されます。

正しい:

  1. onConfigurationChanged
  2. onMeasure (古い幅)
  3. onLayout
  4. onMeasure (新しい幅)
  5. onSizeChanged
  6. onLayout
  7. onDraw

レイアウトが間違っているとこんな流れが見える

正しくない:

  1. onMeasure (新しい幅)
  2. onSizeChanged
  3. onLayout
  4. onDraw
  5. onConfigurationChanged
  6. onMeasure (新しい幅)
  7. onLayout
  8. onDraw

ディスパッチされるメッセージを見ると、問題の一部がわかると思います: 3 つの重要なメッセージが投稿されているのがわかります:

  • MessageType 1003 --> mWinFrame の新しいサイズ
  • MessageType 1000 --> 新しいメジャー/レイアウト パス (mWinFrame のサイズを使用)
  • MessageType 118 --> 構成の変更、onConfigurationChanged のキックオフ。

レイアウトが正しい場合、順序は 118、1003、1000 のようです。間違っている場合、順序は 1003、1000、118 のように見えるため、onConfigurationChanged が発生する前に新しい幅で測定されます。

おまけに、レイアウトが正しくない場合、階層ビューアーをアタッチして階層をダンプするとすぐに正しくなりますが、onPreDraw で再レイアウトや無効化を何度要求しても正しくなりません。

質問:

1) 順不同の呼び出しがあったとしても、最終的に onConfigurationChanged を取得し、新しい幅と高さで発生する再レイアウトを要求しますが、なぜ画面が更新されないのでしょうか?

2) これらのメッセージの投稿順序が時間の経過とともに変化するのはなぜですか? 私はこれを新しい起動時に見たことはありませんが、電話/エミュレーターが「しばらく実行されている」ときに見始めます。

4

1 に答える 1

0

これを回避する方法の 1 つは、onPause() で setVisible(false) を実行し、Runnable を投稿して setVisible(true) onResume() を実行することです。

これにより、測定/レイアウトする前に正しい高さを登録する時間が与えられます.hierarchyviewerの手がかりは、おそらくこれではない魔法の方法があることを示唆していますが、少なくとも今のところ問題を解決しているようです.

于 2011-03-08T20:05:09.370 に答える