AsyncQueryHandler 批量插入

AsyncQueryHandler bulk insert

我想 运行 在后台线程中执行我的 Content Resolver 操作(查询、插入、删除)。

我发现 AsyncQueryHandler 可以解决我的问题。 AsyncQueryHandler 的问题是:批量插入。我的应用程序中有这种操作,并且在 AsyncQueryHandler class 中没有要覆盖的 bulkInsert 方法。

在处理 AsyncQueryHandler 时如何处理批量插入?除了 AsyncQueryHandler 之外还有其他选择吗?

嘿,您可以在这种情况下使用 CursorLoader。这将查询内容解析器和 returns 游标。它使用 AsyncTaskLoader 在后台线程上执行游标查询,这样它就不会阻塞应用程序的 UI。 您可以查看 http://www.theappguruz.com/blog/use-android-cursorloader-example 了解更多详情。

并且您可以像下面这样将批量插入方法定义到您的内容提供程序中

@Override
public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) {
    //mOpenHelper is object of helper class.
    final SQLiteDatabase db = mOpenHelper.getWritableDatabase();


            db.beginTransaction();
            int rowsInserted = 0;
            try {
                for (ContentValues value : values) {

                    long _id = db.insert(TABLE_NAME, null, value);
                    if (_id != -1) {
                        rowsInserted++;
                    }
                }
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }

            if (rowsInserted > 0) {
                getContext().getContentResolver().notifyChange(uri, null);
            }
            return rowsInserted;


}

最后,我改变了我的架构。

我删除了 bulkInsert 并对内容值数组进行了交互。这样我就可以毫无问题地使用 AsyncQueryHandler。

想来想去,我认为这是我最好的选择。

AsyncQueryHandler 不支持 bulkInsert 可能是因为此方法不保证插入的原子性。这是什么意思?好吧,如果 startInsert 由于某种原因失败,则没有完成任何插入。这意味着您可以不进行任何插入,也可以进行一次插入。只有2个选项。保持原子性,即,如果失败,底层数据源保持与以前相同。

如果 10 项中的 bulkInsert 由于某种原因在中间失败,可以有多种选择:插入 3 项或插入 5 项。因此没有原子性。当 ContentProvider 没有覆盖 bulkInsert 并最终多次使用隐式 insert 时,就会发生这种情况。因此,在插入每个项目后,事务被认为是成功的并进行了提交。这意味着对于 10 个项目,发生 10 个事务,如果其中任何一个失败,则不会回滚到数据源的先前状态。操作的原子性丢失。

但这很糟糕。如果您拥有 ContentProvider 并且您已覆盖 bulkInsert 并确保保持原子性怎么办。那么你应该可以使用AsyncQueryHandler来执行bulkInserthttps://github.com/Madrapps/AsyncQuery 库正是这样做的。它与 Android 的 AsyncQueryHandler 相同,但支持 bulkInsert

如果您担心原子性,请确保您使用自己的 ContentProvider 可以处理 bulkInsert