装载器和onLoaderReset Android

11
我在应用程序中实现了一个从数据库查询数据的加载器。我通过实现LoaderCallbacks<Cursor>监听器来监听发生的更改。我的问题是,当使用onLoaderReset(Loader<Cursor> loader)方法时,我想使与加载器关联的任何数据失效并释放它时,会出现问题。在所有示例中,该方法中都会进行以下调用:mAdapter.swapCursor(null);。但问题在于,我不使用适配器中的游标数据,而是以其他方式在我的应用程序中使用它(例如,在onLoadFinished(Loader<Cursor> loader,Cursor data)中直接从返回的游标中)。
        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

            if (data.moveToFirst()) {
                TOTAL_CARDS = data.getCount();
                mView.createCards(TOTAL_CARDS);
            } else {
                TOTAL_CARDS = 0;
                mView.createCards(TOTAL_CARDS);
            }


        }

这里对应的类似于 mAdapter.swapCursor 的操作是什么? 我对加载器并没有太多的经验,实际上我刚刚开始使用它们,如果有人有解决方案,我会很感激。谢谢!

编辑: 目前,我将 null 传递给加载器,它可以工作,像这样:

@Override
public void onLoaderReset(Loader<Cursor> loader) {
        loader = null;
}

};

但这是正确的解决方案吗?

1个回答

27

进行中

@Override
public void onLoaderReset(Loader<Cursor> loader) {
  loader = null;
}

仅仅将方法的局部引用置为null并不如什么都不做好。在你的示例代码中,你仅仅是将方法的局部引用置为null而已。然而,在调用该方法后,这个引用总是会被移除。 (你可能需要阅读关于该主题的进一步讨论:Java是按引用传递还是按值传递?)

onLoaderReset(Loader)方法会在你的loader回调函数(通常是一个ActivityFragment实例)被要求在之前通过onLoadFinished(Loader, Cursor)获取到的Cursor对象的所有引用都被释放之前调用。基本上,该方法要求你清理工作,因为Loader很快就会关闭它所提供给你的Cursor。在关闭了游标之后,你将无法再通过它检索数据。但是,如果游标在关闭后仍然正在使用(通常是由于你提到的CursorAdapter),则会引发异常。

同样地,onLoadFinished(Loader, Cursor)方法有一个隐含的契约,要求在该方法返回后,任何以前提供的Cursor对象都不再使用。相反,你必须用作方法参数提供的新游标替换这些引用。相比之下,onLoaderReset(Loader)要求你履行同样的契约,但不提供替代品,也就是说,你应该移除所有对以前检索到的Cursor的引用。

在你的示例中,你没有让你的Cursor从方法范围中逃逸,而是立即读取了数据。因此,在通过onLoadFinished(Loader, Cursor)提供的Cursor对象中不存在任何引用时,无需删除任何Cursor对象的引用。因此,实现一个空的onLoaderReset(Loader)以履行接口契约将为你完成工作。


谢谢您的回答和解释。只是有一个快速的问题。如果我在onLoadFinished中有一个指向Cursor的引用(我会在方法范围之外使用它),那么我应该在onLoaderReset中关闭它,对吗? - Sandra
实际上不需要。加载器会自动关闭Cursor引用。这也是你应该释放引用的主要原因。在onLoadFinished(Loader, Cursor) / onLoaderReset(Loader)方法返回后,你很可能无法再使用旧的游标。 - Rafael Winterhalter
6
onLoaderReset() 方法的一个好的使用场景是什么? - IgorGanapolsky
该方法是一个生命周期钩子。通常使用该方法来更改封闭实例或“Loader”实例的状态。 - Rafael Winterhalter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接