我想在后台线程中运行我的内容解析器操作(查询,插入,删除)。
我发现AsyncQueryHandler可以解决我的问题。 AsyncQueryHandler的问题是:批量插入。我在我的应用程序中有这种操作,并且在AsyncQueryHandler类中没有要覆盖的bulkInsert方法。
在处理AsyncQueryHandler时如何处理批量插入?除了AsyncQueryHandler之外还有其他选择吗?
答案 0 :(得分:1)
嘿,你可以在这种情况下使用CursorLoader。这将查询内容解析器并返回一个游标。它使用AsyncTaskLoader在后台线程上执行游标查询,这样它就不会阻止应用程序的UI。 您可以查看minimalist one了解更多详情。
您可以将批量插入方法定义到您的内容提供商中,如下所示
@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;
}
答案 1 :(得分:0)
在一天结束时,我改变了我的架构。
我删除了bulkInsert并对Content Values数组进行了交互。这样我可以毫无问题地使用AsyncQueryHandler。
经过思考和思考,我认为这对我来说是最好的选择。
答案 2 :(得分:0)
AsyncQueryHandler
可能不支持bulkInsert
,因为此方法无法保证插入的原子性。这是什么意思?好吧,如果startInsert
由于某种原因失败,那么就没有完成插入。这意味着您可以进行无插入或一次插入。只有2个选项。保持原子性,即如果失败,则基础数据源保持不变。
如果10个项目中的bulkInsert
由于某种原因中间失败,可以有很多选项:插入3个项目或插入5个项目。因此没有原子性。当ContentProvider
未覆盖bulkInsert
并最终多次使用隐式insert
时,会发生这种情况。因此,在插入每个项目之后,事务被认为是成功的并且进行提交。这意味着对于10个项目,发生10个事务,并且如果其中任何一个失败,则不会回滚到数据源的先前状态。操作的原子性丢失了。
但这很糟糕。如果您拥有ContentProvider
并且已覆盖bulkInsert
并确保维持原子性,该怎么办?然后,您应该可以使用AsyncQueryHandler
来执行bulkInsert
。 https://github.com/Madrapps/AsyncQuery库正是这样做的。它与Android的AsyncQueryHandler
相同,但支持bulkInsert
。
如果您担心原子性,请确保使用可以处理ContentProvider
的{{1}}。