Reputation: 968
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
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
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