On below code Eclipse generate warning "This Handler class should be static or leaks might occur".
public class MyActivity extends Activity implements Runnable
{
final Handler handler = new Handler()
{
@Override
public void handleMessage( Message message)
{
String sResult = (String) message.obj;
if( (sResult != null) && (sResult != ""))
{
MyNonStatic = (TableLayout) findViewById( R.id.tableLayout); // any non-static method
}
return;
}
};
public void run()
{
final Message message = handler.obtainMessage( 1, MyFunction( context));
handler.sendMessage( message);
}
public String MyFunction( Context context)
{
return "MyNewString";
}
}
I review many topics on site, but not get solution. Please help me for this code?
Add: i need call non-static method (for example findViewById()) in handleMessage()!
If handler is not static, your Service or Activity cannot be garbage collected, even after being destroyed. This may lead to memory leaks, for some time at least - as long as the messages stay int the queue.
A Handler object takes log messages from a Logger and exports them. It might for example, write them to a console or write them to a file, or send them to a network logging service, or forward them to an OS log, or whatever. A Handler can be disabled by doing a setLevel(Level.
As given in Handler documentation on android dev site, there are two main uses for a Handler: To schedule messages and runnables to be executed as some point in the future; and. To enqueue an action to be performed on a different thread than your own.
Android handles all the UI operations and input events from one single thread which is known as called the Main or UI thread. Android collects all events in this thread in a queue and processes this queue with an instance of the Looper class.
Here is an example of using a weak reference and static handler class to resolve the problem as recommended in the Lint documentation:
public class MyClass{
//static inner class doesn't hold an implicit reference to the outer class
private static class MyHandler extends Handler {
//Using a weak reference means you won't prevent garbage collection
private final WeakReference<MyClass> myClassWeakReference;
public MyHandler(MyClass myClassInstance) {
myClassWeakReference = new WeakReference<MyClass>(myClassInstance);
}
@Override
public void handleMessage(Message msg) {
MyClass myClass = myClassWeakReference.get();
if (myClass != null) {
...do work here...
}
}
}
private final MyHandler mHandler = new MyHandler(this);
public MyHandler getHandler() {
return new MyHandler(this);
}
}
handler - Handler identifying the thread on which the callback should happen. If null, the callback will happen from the thread pool of the process.
Imagine the situation. Some Activity calls PendingIntent.send(...)
and put the non-static inner subclass of Handler
. And then activity is destroyed. But inner class lives.
Inner class still holds a link to destroyed activity, it cannot be garbage-collected.
And hence you need to make it static.
Source: Handlers and memory leaks in Android
From Android lint checks:
HandlerLeak ----------- Summary: Ensures that Handler classes do not hold on to a reference to an outer class Priority: 4 / 10 Severity: Warning Category: Performance In Android, Handler classes should be static or leaks might occur. Messages enqueued on the application thread's MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a WeakReference to its outer class.
First part of the warning is because final Handler handler = new Handler()
creates an anonymous inner class. Inner classes can't be created in a standalone fashion, you always need an outer instance. Remember how you would create this in Java OuterClass.InnerClass innerObject = outerObject.new InnerClass();
. Every inner class object also has to keep a reference to outer object Outer.this
to access outer's members.
Second part is final Message message = handler.obtainMessage( 1, MyFunction( context));
has a handle to your inner handler class (which has a handler to outer Activity class). If this message lives long enough, it won't be possible to garbage collect your Activity.
What can block your message being processed? Unfortunately lint tool can't figure that out, so it always warns you about possible memory leak. If you are sure about what you are doing, you can suppress these messages by various methods.
For your case it doesn't look like a good idea to make Activity
a Runnable
but anyway may be you should use Handler.post or best Activity.runOnUIThread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With