即使在调用onDestroy()之后,活动实例仍然存在

Man*_*ani 12 android android-service android-activity

我传递一个在mainUI线程上创建的处理程序Activity并传递给执行某些网络操作的线程,当我获得结果时,我使用处理程序将结果发送回活动.

当我通过这些链接时,这种方法在内存泄漏方面存在问题:
Inner ClassHandler内存泄漏
Android开发人员

所以我已经实现了WeakReference,并使用了活动实例WeakReference.但Activity即使活动被破坏,我仍然看到实例存活.

我创建了一个Handler内部活动,并将活动实例作为弱引用传递给处理程序.
当我Handler回复10秒后传递给它的消息时,会Activity被销毁.但弱参考仍然有Activity实例,我看到Toast,后被Activity摧毁.

有些地方我的理解错了吗?
有人可以解释如何处理传递给处理程序的消息,但UI不在?

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

}
Run Code Online (Sandbox Code Playgroud)

根据获得回复,我在这里更新答案.你可以用你喜欢的方式做到这一点.但这是一种方式.

在SingleParamHandler中添加了以下函数

public void clear() {
    mActivityReference.clear();
}
Run Code Online (Sandbox Code Playgroud)

并在Activity onDestroy()

public void onDestroy() {
    super.onDestroy();
    System.out.println("######## Activity onDestroy() ###### ");
    handler.clear();
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ser 5

你不需要WeakReference这里.该Handler可以只包含对一个参考Activity.在Activity的onDestroy()只是调用一个方法上MyHandler,参考设置到Activitynull.检查nullhandleMessage().

另一种选择是:在activity中onDestroy()调用一个方法来中断休眠线程,使其在发送消息之前关闭.