現在のアクティビティのビュー階層のビューが変更されたときに特定のアクション (ログ、スクリーンショットなど) を実行するデバッグ ユーティリティを作成しようとしています。ここでの変更は、ビュー ツリーの視覚的表現を変更することになります。TextView でのテキストの設定、View での背景色の変更、または ViewGroup への子の追加/からの子の削除です。
理想的には、これらの変更がいつ発生し、どのビュー/ビュー サブツリーが影響を受けるかを通知する API を探しています。
私は可能な解決策を検討するのに多くの時間を費やしましたが、最もクリーンなのは ViewTreeObserver の OnPreDrawListener と OnGlobalLayoutListener を使用することです。関心のあるイベントが発生すると通知されるようです。ただし、影響を受けるビューに関するコンテキスト情報は提供されません。私の知る限り、これらのリスナーをビューの ViewTreeObserver にアタッチすると、ビュー ツリー内の何かが変更されるたびに通知が発生し、個々のビューに対して分離された ViewTreeObserver を作成する方法がありません。これは、どのプロパティが変更されたかを判断するために、各通知でビュー ツリー全体を走査する必要があることを意味します。
setBackgroundColor
もう 1 つの方法は、View クラスにバイナリ パッチを適用して、これらのクラスが対象のメソッドやその他のメソッドでAPI にコールバックするようにすることです。android-aspectjはそのために使用できます。ここでの欠点は、これは私がコンパイルしたクラスに対してのみ機能することであり、ソースを直接変更するだけで済むため、ほとんど役に立ちません。同じ考えに沿って、dexmakerは、実行時にクラスにパッチを適用できるため、より完全なソリューションになります。ただし、ここで、クラスのロードの問題に遭遇します。クラスにパッチを当てるには、自分でロードする必要がありますClassLoader
しかし、View クラスはすべて Android によって既に読み込まれています。1 つの解決策は、作成後にビュー ツリーを複製することですが、ストック ロードされたクラスを使用する代わりに、パッチを適用した独自のクラスを使用します。これは、パッチが適用される前にアプリがビュー ツリーへの参照を取得した場合を除いて、ほとんど機能します。もちろん、レイアウト変更イベント (ビューの追加/削除) ごとにクローンをやり直す必要もあります。このプロセスが遅くなることは理解していますが、これまでのところ、最も透過的で完全なソリューションです。
最後に、これはおそらく最も難しいアプローチですが、Android に組み込まれているメソッド トレース システム ( Traceview ) を使用して、実行時にトレース イベントを受け取る方法はありますか? 現在、システムはオフライン処理のためにトレースを SD カード上のファイルにダンプします。それは明らかに私のニーズには遅すぎますが、これらのイベントをインターセプトするためのフックがネイティブ SDK に公開されていると便利です。
あらゆる提案を歓迎します。現時点では、移植可能なソリューションを探しているわけではないので、反射/非表示の API トリックについて自由に言及してください。この巨大な投稿を読んでくれてありがとう。