6

我刚刚开始使用新的 cursorLoader 并且遇到了问题。以下代码只是为了了解 cursorLoader 的工作原理,但我不断得到:

“尝试重新查询已关闭的游标”,当我恢复此活动时。在我开始使用 cursorLoader 之前,该应用程序运行良好。有任何想法吗?

private Cursor getSectionData(CharSequence parent_id) {
    
    String[] projection = new String[] {Titles.SECTION, Titles.TITLE, Titles._ID, Titles.CODE_RANGE,};
    Uri titles =  Titles.CONTENT_URI;
    String select = "" + Titles.PARENT_ID + " match " + parent_id + "";
    CursorLoader loader = new CursorLoader(this, titles, projection, select, null, null);
    Cursor cTitles = loader.loadInBackground();
    
    
    String[] projection1 = new String[] {Codes.CODE, Codes.EXCERPT, Codes._ID,};
    Uri codes =  Codes.CONTENT_URI;
    String select1 = "" + Codes.PARENT_ID + " match " + parent_id + "";
    CursorLoader loader1 = new CursorLoader(this, codes, projection1, select1, null, null);
    Cursor cCodes = loader1.loadInBackground();

    
    
    //Cursor cTitles = db.rawQuery("select section, title, _id, code_range from titles where parent_id match " + parent_id + "", null);
    //startManagingCursor(cTitles);
    //Cursor cCodes = db.rawQuery("select code, excerpt, _id from codes where parent_id match " + parent_id + "", null);
    
    mQuery = "select code, excerpt, _id from codes where parent_id match " + parent_id + "";
    
    //startManagingCursor(cCodes);
    Cursor[] c = {cTitles, cCodes};
    Cursor cursor = new MergeCursor(c);
    startManagingCursor(cursor);
    
    return cursor;

}
4

1 回答 1

12

我不相信从 loader.loadInBackground() 捕获光标是你想要的。loadInBackground() 的实现基本上执行查询并返回 UI 线程上的光标,这是您试图避免的。

任何时候在 UI 线程上等待返回值时都要小心。这应该是一个很好的指标,表明这不是您想要的。

我为解决此问题所做的是重新启动加载程序。就我而言,我正在尝试使用操作栏来搜索我的内容。我的类扩展了 ListFragment 并实现了 LoaderManager.LoaderCallbacks 包含它的 Activity 实现了 OnQueryTextListener 并在这里调用片段是我在片段中执行的代码。

public void doSearch(String query) {
    Bundle bundle = new Bundle();
    bundle.putString("query", query);

    getLoaderManager().restartLoader(LoaderMangerIdHelper.INVENTORY, bundle, this);
}

请注意,您必须重新启动加载程序。装载机全部由系统管理。这将导致您的 onCreateLoader 被重新调用。因此,您必须在其中检查查询字符串以设置您的选择。

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
    String SELECTION = "someColumn=?";
    List<String> selectionArgs = new ArrayList<String>();
    selectionArgs.add("someArgs");

    if (bundle != null && bundle.containsKey("query")) {
        SELECTION += " AND columnTitle LIKE ?";
        selectionArgs.add(bundle.getString("query") + "%");
    }

    final String[] SELECTION_ARGS = new String[selectionArgs.size()];
    selectionArgs.toArray(SELECTION_ARGS);

    mLoader = new CursorLoader(getActivity(), RoamPay.Product.CONTENT_URI, null, SELECTION,
            SELECTION_ARGS, null);

    return mLoader;
}

这将在后台启动 cursorLoading。回调应该和往常一样。

   @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // Swap the new cursor in. (The framework will take care of closing the
        // old cursor once we return.)
        mAdapter.swapCursor(data);

        // The list should now be shown.
        if (isResumed()) {
            setListShown(true);
        } else {
            setListShownNoAnimation(true);
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        // This is called when the last Cursor provided to onLoadFinished()
        // above is about to be closed. We need to make sure we are no
        // longer using it.
        mAdapter.swapCursor(null);
    }
于 2011-06-02T18:00:23.090 回答