当前位置: 首页 > 知识库问答 >
问题:

弱引用无效

爱琪
2023-03-14

我在静态处理程序中使用弱引用来避免内存泄漏,然而,有时这个引用会被取消,我不明白为什么。

静态处理程序在存储库类中定义,该存储库类有一个在后台执行操作的方法,接收回调以在操作完成时通知调用方:

public class MyRepository {

    public void performOperation(ContentResolver cr, RepositoryCallback callback) {
        MyHandler handler = new MyHandler(cr, callback);
        handler.startQuery(...)
    }

    interface RepositoryCallback {
        void onSuccess(MyModel model);
    }

    // Handler class code here
}

处理程序的代码如下所示:

private static class MyHandler extends AsyncQueryHandler {

    private final WeakReference<RepositoryCallback> weakCallback;

    public MyHandler(ContentResolver cr, RepositoryCallback callback) {
        super(cr);
        this.weakCallback = new WeakReference<>(callback);
    }

    @Override
    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
        RepositoryCallback callback = this.weakCallback.get();
        if (callback != null) { // --> Here sometimes it is null
            // Do some stuff with the cursor to create MyModel
            callback.onSuccess(model);
        }
    }

}

出于某种原因,这样做。weakCallback。get()有时是空的,我试图理解为什么。

活动代码如下所示:

public class MyActivity extends AppCompatActivity {
    public void loadModel() {
        showLoadingView();
        myRepository.performOperation(context.getContentResolver(), new RepositoryCallback() {
            @Override
            public void onSuccess(MyModel model) {
                hideLoadingView();
                // Do something with model
            }
        });
    }
}

正如您所见,我正在为回调创建一个匿名类,但没有人持有对它的引用。

这就是弱引用无效的原因吗?

谢谢。

共有1个答案

酆乐湛
2023-03-14

这是与弱引用相关的“经典”错误。

如果观察者持有对观察者的唯一引用,并且该引用很弱,则可以清除该引用,并对观察者进行垃圾收集。

由于您使用的是匿名类,可观察将保存对它的唯一引用,因此它将被清除。

作为旁注——在我的整个Android开发经验中,每当我看到开发人员使用弱引用时,总是有一种代码味道。通常,这表明开发人员不了解弱引用是如何工作的,或者他们不信任自己的代码。

一个很好的经验法则是,你永远不应该使用弱引用。

编辑:

我认为Handler通常是一个反模式。你可以在这个Reddit线程中读到更多关于这一点的信息。还有一个线程,我帮助一个开发人员看看他如何在他的代码库中摆脱HandlerThread

另一方面,杰克·沃顿不同意我的说法。

从那里拿走你想要的,但是,总的来说,我会说拥有一个静态的处理程序肯定是反模式的。

如果你担心Android Studion的警告,那么请记住Google负责AsyncWorkLoaders。这个警告不仅仅是无用的,而且实际上很糟糕。他们应该把它变成你不应该使用静态Hadler

如果您只需要将工作转移到BG线程,然后在UI线程上获得回调,那么使用RxJava之类的工具会更好。甚至是邪恶的异步任务

我猜您正在使用AsyncQueryHandler来访问ContentProvider。这也是一个非常有争议的方法。如果您不需要与其他应用程序共享数据,那么最好使用一些ORM来为您处理多线程。

 类似资料:
  • 介绍 弱引用缓存。对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。丢弃某个键时,其条目从映射中有效地移除。该类使用了WeakHashMap做为其实现,缓存的清理依赖于JVM的垃圾回收。 使用 与TimedCache使用方法一致: WeakCache<String, String> weakCache = CacheUtil.newWeakC

  • 本文向大家介绍详解JAVA 弱引用,包括了详解JAVA 弱引用的使用技巧和注意事项,需要的朋友参考一下 定义 弱引用是使用WeakReference创建的引用,弱引用也是用来描述非必需对象的,它是比软引用更弱的引用类型。在发生GC时,只要发现弱引用,不管系统堆空间是否足够,都会将对象进行回收。 说明 弱引用,从名字来看就很弱嘛,这种引用指向的对象,一旦在GC时被扫描到,就逃脱不了被回收的命运。 但

  • 问题内容: 我目前正在尝试诊断应用程序中的缓慢内存泄漏。到目前为止,我掌握的事实如下。 我有4天运行该应用程序的堆转储。 该堆转储包含约800个WeakReference对象,这些对象指向保留40mb内存的对象(所有对象都是同一类型,出于这个问题的目的,我将其称为Foo)。 Eclipse内存分析工具显示,这些WeakReferences引用的每个Foo对象均未被其他任何对象引用。我的期望是,这应

  • 本文向大家介绍Lua教程之弱引用table,包括了Lua教程之弱引用table的使用技巧和注意事项,需要的朋友参考一下 这次要介绍的内容比较少,就一个——弱引用table 1.无法超越人类智慧的智能——自动内存管理的缺陷 我们都知道,Lua是具备自动内存管理的,好吧,也许有些朋友不知道。 我们只管创建对象,无须删除对象(当然,对于不要的对象你需要设置一下nil值),Lua会自动删除那些被认为是垃圾

  • 本文向大家介绍浅谈C语言中的强符号、弱符号、强引用和弱引用,包括了浅谈C语言中的强符号、弱符号、强引用和弱引用的使用技巧和注意事项,需要的朋友参考一下 首先我表示很悲剧,在看《程序员的自我修养--链接、装载与库》之前我竟不知道C有强符号、弱符号、强引用和弱引用。在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样感觉的朋友交流也希望高人指点。   首先我们看一下书中关于它

  • 本文向大家介绍Java 中的弱引用是什么,包括了Java 中的弱引用是什么的使用技巧和注意事项,需要的朋友参考一下 Java里一个对象obj被创建时,被放在堆里。当GC运行的时候,发现没有任何引用指向obj,那么就会回收obj对象的堆内存空间。 换句话说,一个对象被回收, 必须满足两个条件: (1)没有任何引用指向它 (2)GC被运行。 在实际开发中,我们可以通过把所有指向某个对象的referec