Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/184.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何避免可运行回调泄漏?_Java_Android_Multithreading_Reference_Weak References - Fatal编程技术网

Java 如何避免可运行回调泄漏?

Java 如何避免可运行回调泄漏?,java,android,multithreading,reference,weak-references,Java,Android,Multithreading,Reference,Weak References,我下面有一些代码,当我完成活动时,它们将执行来自另一个线程的回调。那么,当活动完成后,如何避免调用回调或回调中的代码 public static interface Callback{ public void onCallback(); } class ActivityA { TextView tv = ...; Handler handler = ...; public void onClick(View v) { Business.callT

我下面有一些代码,当我完成活动时,它们将执行来自另一个线程的回调。那么,当活动完成后,如何避免调用回调或回调中的代码

public static interface Callback{
    public void onCallback();
}

class ActivityA {
    TextView tv = ...;
    Handler handler = ...;
    public void onClick(View v) {
        Business.callThread(new Callback() {

            @Override
            public void onCallback() {
                handler.post(new Runnable(){
                    public void run(){
                        tv.setText("xxxx");
                    }
                });
            }
        });
    }
}

class Business {
    public static void callThread(final Callback listener) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(5000); //sleep 5s;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                listener.onCallback();
            }
        }).start();
    }
}

垃圾收集器统计对对象的引用。但是,有两种引用类型。在您的案例中有用的是:

弱引用对象,不阻止其引用对象可终结、终结和回收

将runnable创建为具有构造函数的类:

static class CallbackRunnable implements Runnable {
    WeakReference<Callback> listener;

    public CallbackRunnable(Callback listener) {
        this.listener = new WeakReference<Callback>(listener);
    }

    @Override
    public void run() {
        try {
            Thread.sleep(5000); //sleep 5s;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (listener.get() == null) {
            return;
        }
        listener.get().onCallback();
    }
}
callThread
方法实现:

public static void callThread(final Callback listener) {
    new Thread(new CallbackRunnable(listener)).start();
}

嗯,我真的不太明白这一点,当
listener.get()==null
为真时?为什么?当调用由
new Callback()
声明时,它持有对
活动的引用(它是
活动
中声明的内部对象)。当要销毁活动时,它由垃圾收集器标记。当垃圾收集器需要内存时,它会删除以前标记的对象。但它会自动决定何时调用以及清除什么。这是一个非常简单和天真的描述,但它主要是这样工作的。但是您如何知道
新回调
包含活动的引用?是关于Java引用的最新有趣的一篇文章。如果调用此
new WeakReference(new Callback())
,则
listener.get()==null
将始终为真!
public static void callThread(final Callback listener) {
    new Thread(new CallbackRunnable(listener)).start();
}