I pass a handler created on mainUI thread from Activity and passed to a thread which performs some network operation and when i obtain result i send the result back to the activity using the handler.
This approach had issue in memory leaks when i went through these links:
Inner ClassHandler Memory Leak
Android Developers
So i had implemented WeakReference, and kept the activity instance using WeakReference. But i am still seeing Activity instance alive even after activity is destroyed.
I created a Handler inside activity and passed activity instance as weakreference to handler.
By the time my Handler responds with a message delivered to it after 10secs, Activity is destroyed. But the weak reference still has the Activity instance and i am seeing the Toast, after Activity is destroyed.
Is there some where my understanding wrong ?
Can someone explain how to handle messages delivered to a handler,but the UI is not around ?
import java.lang.ref.WeakReference;
import android.os.Handler;
import android.os.Message;
public abstract class SingleParamHandler <T> extends Handler
{
private WeakReference<T> mActivityReference;
public SingleParamHandler(T activity) {
mActivityReference = new WeakReference<T>(activity);
}
@Override
public void handleMessage(Message msg) {
if (mActivityReference.get() == null) {
return;
}
handleMessage(mActivityReference.get(), msg);
}
protected abstract void handleMessage(T activity, Message msg);
}
import android.app.Activity;
import android.os.Bundle;
import android.os.Message;
import android.widget.Toast;
public class MainActivity extends Activity {
MyHandler<MainActivity> handler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
handler = new MyHandler<MainActivity>(this);
new Thread(new MyRunnable(handler)).start();
}
public void onDestroy() {
super.onDestroy();
System.out.println("######## Activity onDestroy() ###### ");
}
private class MyRunnable implements Runnable {
private Handler mHandler;
public MyRunnable(Handler handler) {
mHandler = handler;
}
public void run() {
try {
Thread.sleep(10000);
mHandler.sendMessage(Message.obtain(handler, 1));
} catch ( Exception e) {
e.printStackTrace();
}
}
}
private static class MyHandler<T> extends SingleParamHandler<T> {
public MyHandler(T activity) {
super(activity);
}
@Override
public void handleMessage(T act, Message msg) {
if(msg.what == 1) {
Toast.makeText((MainActivity)act, "Called after activity destroyed", Toast.LENGTH_LONG).show();;
}
}
}
}
Based on the response obtained, i am updating the answer here. You may do it in the way u liked. But this is one way.
Added the below function in SingleParamHandler
public void clear() {
mActivityReference.clear();
}
And in Activity onDestroy()
public void onDestroy() {
super.onDestroy();
System.out.println("######## Activity onDestroy() ###### ");
handler.clear();
}