我在静态处理程序中使用弱引用来避免内存泄漏,然而,有时这个引用会被取消,我不明白为什么。
静态处理程序在存储库类中定义,该存储库类有一个在后台执行操作的方法,接收回调以在操作完成时通知调用方:
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
}
});
}
}
正如您所见,我正在为回调创建一个匿名类,但没有人持有对它的引用。
这就是弱引用无效的原因吗?
谢谢。
这是与弱引用相关的“经典”错误。
如果观察者持有对观察者的唯一引用,并且该引用很弱,则可以清除该引用,并对观察者进行垃圾收集。
由于您使用的是匿名类,可观察将保存对它的唯一引用,因此它将被清除。
作为旁注——在我的整个Android开发经验中,每当我看到开发人员使用弱引用时,总是有一种代码味道。通常,这表明开发人员不了解弱引用是如何工作的,或者他们不信任自己的代码。
一个很好的经验法则是,你永远不应该使用弱引用。
编辑:
我认为Handler
通常是一个反模式。你可以在这个Reddit线程中读到更多关于这一点的信息。还有一个线程,我帮助一个开发人员看看他如何在他的代码库中摆脱HandlerThread
。
另一方面,杰克·沃顿不同意我的说法。
从那里拿走你想要的,但是,总的来说,我会说拥有一个静态的处理程序
肯定是反模式的。
如果你担心Android Studion的警告,那么请记住Google负责AsyncWork
和Loaders
。这个警告不仅仅是无用的,而且实际上很糟糕。他们应该把它变成你不应该使用静态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