ContentProvider和CursorLoader

时间:2017-01-07 05:01:21

标签: android android-contentprovider android-cursorloader

我正在使用CursorLoader和ContentProvider从SQLite DB中读取数据。 '药物'表有大约300,000行。我已经在' name'上创建了索引。药物中的专栏'表。

我有一个SearchFragment,我根据用户查询搜索药物,如下所示:

public void update(String query, SearchView mSearchView, String mSearchType) {

    mQuery = query;

    Bundle b = new Bundle();
    b.putString("query", mQuery);

    mLoaderManager.restartLoader(Constants.DRUG_LOADER, b, this);
    Log.d(TAG, "Searching for " + mQuery);
}


public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    Log.d(TAG, "onCreateLoader");

    return new CursorLoader(getActivity(), DrugsProvider.DRUGS_URI,
            null,
            ReapDbContract.Drugs.NAME + " like ?",
            new String[]{args.getString("query") + "%"},
            null
    );
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
    Log.d(TAG, "onLoadFinished");
    mAdapter.setCursor(c);
    mAdapter.notifyDataSetChanged();

    Log.d(TAG, "Done query for " + mQuery);
}

这是运行查询的DrugsProvider的相关部分:

@Override
public Cursor query(Uri uri, String[] projection, String where, String[] values, String sortOrder) {
    switch (sUriMatcher.match(uri)) {
        case DRUGS_TABLE:
            Cursor c = mDbHelper.query(Drugs.TABLE_NAME, projection, where, values, sortOrder);
            Log.d(TAG, "query done");
            return c;

        case DRUG_ROW:
            String id = uri.getLastPathSegment();
            return mDbHelper.getRow(Drugs.TABLE_NAME, id);

        default:
            throw new IllegalArgumentException("Invalid URI: " + uri);
    }
}

DrugsHelper实际上实现了查询:

public Cursor query(String tableName, String[] projection, String where, String[] values, String sortOrder) {
    Log.d(TAG, "query: start: " + Arrays.toString(values));
    SQLiteDatabase db = getWritableDatabase();
    Log.d(TAG, "query: db");

    Cursor c = db.query(tableName, projection, where, values, null, null, sortOrder);
    Log.d(TAG, "query: done: " + Arrays.toString(values));

    return c;
}

调试日志清楚地表明实际的数据库查询在几毫秒内执行,但在查询结束和调用onLoadFinished之间有近500毫秒的延迟。这使搜索极其缓慢。 有时在调用onCreateLoader和提供程序实际运行查询之间也会有大约500ms的延迟。这是一个示例日志:

=============================================== =================

01-07 10:23:13.618 29288-29288 / in.workcell.pos D / SearchFragment:onCreateLoader

01-07 10:23:13.627 29288-29288 / in.workcell.pos D / SearchFragment:搜索pari

01-07 10:23:13.632 29288-29524 / in.workcell.pos D / DrugsHelper:query:start:[pari%]

01-07 10:23:13.632 29288-29524 / in.workcell.pos D / DrugsHelper:query:db

01-07 10:23:13.632 29288-29524 / in.workcell.pos D / DrugsHelper:query:done:[pari%]

01-07 10:23:13.632 29288-29524 / in.workcell.pos D / DrugsProvider:查询完成

01-07 10:23:14.098 29288-29288 / in.workcell.pos D / SearchFragment:onLoadFinished

01-07 10:23:14.098 29288-29288 / in.workcell.pos D / SearchFragment:完成对pari的查询

=============================================== =================

DrugsProvider在 10:23:13.632 完成,但onLoadFinished在 10:23:14.098 被召唤,延迟 466ms !如何调试导致此延迟的原因?

0 个答案:

没有答案