vedavis
vedavis

Reputation: 968

Android: Calling non-static methods from a static Handler class

Given this code:

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;
        }
    }
}
}

I am getting the compile error: Cannot make a static reference to the non-static method setStatus(int) ...

Which makes sense, because getActionBar() in setStatus() is a non-static method.

I made the Handler class static because of the warning: This Handler class should be static or leaks might occur.

The question: how do I properly access the setStatus() method from within the static handler?

EDIT: new handler code is the answer.

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;
        }
    }
}

Upvotes: 9

Views: 8634

Answers (3)

Alex Lockwood
Alex Lockwood

Reputation: 83311

Try using a WeakReference, as described in this article.

Upvotes: 10

flobacca
flobacca

Reputation: 978

In my activity's onDestroy method I call:

this.myHandler.removeCallbacksAndMessages(null);

This does not get rid of the "This Handler class should be static or leaks might occur" warning, but I believe it destroys the message hence stopping the leak. My handler class is an inner non-static class of my activity. My activity has an instance of MyHandler myHandler.

When I do this, the handler's handleMessage method isn't called, which I assume means that the message containing the handler, which contained a reference to the activity was destroyed. Am open for comments as I haven't tested it with any leak testing tools. Here is where I copied the idea: http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html answerer: CyrilJanuary 15, 2013 at 7:50 AM

Upvotes: 0

NickL
NickL

Reputation: 4276

Since you are now using a WeakReference, mTarget.get() might return null. In your edited code, you are not checking if target is null before executing target.setStatus(R.string.title_not_connected). So this may throw a NullPointerException if the weakreference object has been GC'ed.

Upvotes: 1

Related Questions