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

};

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

4

1 回答 1

27

正在做

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

就像什么都不做一样好。在您的示例代码中,您只是将方法对其参数的本地引用归零。但是,在方法调用返回后,此引用将始终被删除。(您可能想阅读Java 是“按引用传递”还是“按值传递”?进一步讨论该主题。)

onLoaderReset(Loader)当您的加载程序的回调(通常是一个ActivityFragment实例)被要求释放Cursor对它之前获得的所有引用时,该方法被调用onLoadFinished(Loader, Cursor)。基本上这种方法要求你清理,因为它Loader会很快关闭Cursor它之前提供给你的。游标关闭后,您将无法再通过它检索数据。但是,如果光标在关闭后仍处于使用状态(通常由CursorAdapter您提到的 a 使用),这将导致抛出异常。

Similarly, onLoadFinished(Loader, Cursor) has an implicit contract asking that after the method returns any formerly provided Cursor objects must not longer be in use. Instead, you have to replace these references by the new cursor which is provided as a method argument. In contrast, onLoaderReset(Loader) asks you to fulfill the same contract, but without providing a replacement, i.e. you should remove all references to a formerly retrieved Cursor.

In your example, you do not let your Cursor escape the method scope but instead you are reading the data right away. Therefore, it is not necessary to remove any references to a Cursor object which was provided via onLoadFinished(Loader, Cursor) since there are none. An empty implementation of onLoaderReset(Loader) to fulfill the interface contract will therefore do the job for you.

于 2013-05-02T11:52:53.973 回答