9

このコードを考えると:

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {

public static final int MESSAGE_NOT_CONNECTED = 1;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
}

// -------------------------------------------------
public final void setStatus(int Rid) {
    final ActionBar actionBar = getActionBar();
    actionBar.setSubtitle(Rid);
}

// -------------------------------------------------
static Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MESSAGE_NOT_CONNECTED:
            setStatus(R.string.title_not_connected);
            break;
        }
    }
}
}

コンパイルエラーが発生します:非静的メソッドsetStatus(int)への静的参照を作成できません...

setStatus()のgetActionBar()は非静的メソッドであるため、これは理にかなっています。

警告のため、Handlerクラスを静的にしました。このHandlerクラスは静的である必要があります。そうしないと、リークが発生する可能性があります。

質問:静的ハンドラー内からsetStatus()メソッドに適切にアクセスするにはどうすればよいですか?

編集:新しいハンドラーコードが答えです。

static class hHandler extends Handler {
    private final WeakReference<MainActivity> mTarget;
    hHandler(MainActivity target) {
        mTarget = new WeakReference<MainActivity>(target);
    }

    @Override
    public void handleMessage(Message msg) {
        MainActivity target = mTarget.get();
        If(target == null) {
             return;
        }
        switch (msg.what) {
        case MESSAGE_NOT_CONNECTED:
            target.setStatus(R.string.title_not_connected);
            break;
        }
    }
}
4

3 に答える 3

10

WeakReferenceこの記事で説明されているように、を使用してみてください。

于 2012-08-06T16:38:12.083 に答える
1

現在、を使用しているためWeakReferencemTarget.get()が返される場合がありnullます。編集したコードでは、を実行する前にtargetであるかどうかを確認していません。したがって、弱参照オブジェクトがGCされている場合、これはをスローする可能性があります。nulltarget.setStatus(R.string.title_not_connected)NullPointerException

于 2012-10-04T12:01:42.577 に答える
0

私のアクティビティのonDestroyメソッドでは、次のように呼び出します。

this.myHandler.removeCallbacksAndMessages(null);

これは「このHandlerクラスは静的であるか、リークが発生する可能性があります」という警告を取り除くものではありませんが、メッセージを破棄してリークを停止すると思います。私のハンドラークラスは、私のアクティビティの内部の非静的クラスです。私のアクティビティには、MyHandlermyHandlerのインスタンスがあります。

これを行うと、ハンドラーのhandleMessageメソッドが呼び出されません。これは、アクティビティへの参照を含むハンドラーを含むメッセージが破棄されたことを意味すると思います。リークテストツールでテストしたことがないので、コメントを受け付けています。これが私がアイデアをコピーした場所です:http ://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html回答者:Cyril2013年1月15日午前7時50分

于 2013-02-12T01:45:40.493 に答える