2

私は非常に奇妙な問題に直面しています。カスタムビューを含む がありますActivityActionBar

このカスタム ビューの XML を次のように読み込むと:

LayoutInflater inflater = LayoutInflater.from(this);
ViewGroup vg = (ViewGroup) inflater.inflate(R.layout.action_search_form,null);

リーク: アクティビティは GC されていません。次の修正が機能します(なぜですか?):

LayoutInflater inflater = LayoutInflater.from(getApplicationContext());

ただしOnClickListener、子ビューに設定すると、再びリークします。

ImageButton clear = (ImageButton) vg.findViewById(...);
clear.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View v) {
            // Even if empty
        }
    });
}

これはすべてアクティビティのプライベート メソッドで発生し、すべてのビューはローカル変数です。

修正を見つけましたが、それが機能する理由がわかりません:ビューはシンプルだったので、XML を拡張する代わりに Java でコーディングしました。コンテキストが LayoutInflater に渡されず、アクティビティ自体から何も起こらないという事実に関連しているのではないかと思いましたが、誰かが何が起こったのかを理解するのを手伝ってくれれば、私はそれを大いに感謝します.

4

1 に答える 1

4

すべての View クラスには、Context パラメーターが必要です。XML をインフレートする場合、作成されたビューに提供されるコンテキストは、LayoutInflater に提供されるコンテキストと同じです。あなたのビューはあなたのアクティビティへの参照を保持しています。

getApplicationContext() を使用してもアクティビティがリークしない理由は、アクティビティだけでなく、アプリケーションのライフサイクル全体にグローバルなコンテキストを渡しているためです。

** 編集 **

OnClickListener もアクティビティを保持している理由に関しては、匿名の内部クラスを使用することの副作用によるものです。デフォルトでは、これらのインライン実装は、親/ラッピング クラス インスタンスへの参照を保持します。これは、インナーの実装から親のメソッドを呼び出せるようにするためです。

例えば:

myView.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        MyActivity.this.doSomethingCool();
    }
}

メソッド本体に何かがあるかどうかに関係なく、内部クラスは親クラスへの参照を維持します。

于 2013-01-17T18:51:36.610 に答える