当许多行插入批量操作的Andr​​oid的ContentProvider调用setNotificationUri()来CursorAdapter的阵阵 [英] Android ContentProvider calls bursts of setNotificationUri() to CursorAdapter when many rows are inserted with a batch operation

查看:150
本文介绍了当许多行插入批量操作的Andr​​oid的ContentProvider调用setNotificationUri()来CursorAdapter的阵阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义的的ContentProvider ,其管理访问SQLite数据库。要装入数据库表中的内容 ListFragment ,我用的是 LoaderManager CursorLoader 的CursorAdapter

I have a custom ContentProvider which manages the access to a SQLite database. To load the content of a database table in a ListFragment, I use the LoaderManager with a CursorLoader and a CursorAdapter:

public class MyListFragment extends ListFragment implements LoaderCallbacks<Cursor> {
    // ...
    CursorAdapter mAdapter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mAdapter = new CursorAdapter(getActivity(), null, 0);
        setListAdapter(mAdapter);
        getLoaderManager().initLoader(LOADER_ID, null, this);
    }

    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new CursorLoader(getActivity(), CONTENT_URI, PROJECTION, null, null, null);
    }

    public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
        mAdapter.swapCursor(c);
    }

    public void onLoaderReset(Loader<Cursor> loader) {
        mAdapter.swapCursor(null);
    }
}

SQLite数据库得到由后台任务,获取了许多来自web服务的项目,并通过的ContentProvider 插入这些项目到数据库中的批处理操作(<$ C更新$ C> ContentResolver的#applyBatch())。

The SQLite database gets updated by a background task which fetches a number of items from a web service and inserts these items into the database through ContentProvider batch operations (ContentResolver#applyBatch()).

即使这是一个批量操作,的ContentProvider#插入()被调用的每一行插入到数据库中,并在当前实现中,的ContentProvider 要求 setNotificationUri()的每次插入命令。

Even if this is a batch operation, ContentProvider#insert() gets called for each row is inserted into the database and, in the current implementation, the ContentProvider calls setNotificationUri() for each insert command.

的结果是的CursorAdapter 接收通知的爆发,导致在UI被更新,随之而来的恼人的闪烁效果过于频繁。

The result is that the CursorAdapter receives bursts of notifications, resulting in the UI being updated too often with consequent annoying flickering effect.

理想情况下,当间歇操作进行时,应该有一种方法来通知 ContentObserver 仅在任何间歇操作的结束,而不是与每个插入命令。

Ideally, when a batch operation is in progress, there should be a way to notify ContentObserver only at the end of any batch operation and not with each insert command.

有谁知道这是可能的吗?请注意,我可以改变的ContentProvider 的实施和覆盖任何它的方法。

Does anybody know if this is possible? Please note I can change the ContentProvider implementation and override any of its methods.

推荐答案

我发现,我从谷歌的I / O应用程序发现了一个简单的解决方案。你只需要重写你的ContentProvider的applyBatch方法,并在交易完成所有操作。通知将不会发送到事务提交,这导致减少的ContentProvider变化通知数被送出:

I found a simpler solution that I discovered from Google's I/O app. You just have to override the applyBatch method in your ContentProvider and perform all the operations in a transaction. Notifications are not sent until the transaction commits, which results in minimizing the number of ContentProvider change-notifications that are sent out:

@Override
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
        throws OperationApplicationException {

    final SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    db.beginTransaction();
    try {
        final int numOperations = operations.size();
        final ContentProviderResult[] results = new ContentProviderResult[numOperations];
        for (int i = 0; i < numOperations; i++) {
            results[i] = operations.get(i).apply(this, results, i);
        }
        db.setTransactionSuccessful();
        return results;
    } finally {
        db.endTransaction();
    }
}

这篇关于当许多行插入批量操作的Andr​​oid的ContentProvider调用setNotificationUri()来CursorAdapter的阵阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆