您的位置:首页 > 产品设计 > UI/UE

通过AsyncQueryHandler异步对数据库进行增删查操作

2017-11-21 16:01 666 查看

AsyncQueryHandler的作用

异步对数据库进行增加、删除、更新、查询操作。避免在主线程中直接调用数据库相关操作导致的ANR异常。

AsyncQueryHandler使用步骤

自定义继承AsyncQueryHandler的子类,实现相关的方法。

void onDeleteComplete(int token, Object cookie, int result)

异步删除完成时调用。

调用方式:startDelete(int token, Object cookie, Uri uri, String selection, String[] selectionArgs)

void onInsertComplete(int token, Object cookie, Uri uri)

异步插入完成时调用。

调用方式:startInsert(int token, Object cookie, Uri uri, ContentValues initialValues)

void onQueryComplete(int token, Object cookie, Cursor cursor)

调用方式:startQuery(int token, Object cookie, Uri uri, String[] projection, String selection, String[] selectionArgs, String orderBy)

void onUpdateComplete(int token, Object cookie, int result)

异步更新完成时调用。

调用方式:startUpdate(int token, Object cookie, Uri uri, ContentValues values, String selection, String[] selectionArgs)

自定义实现代码示例:

private class MessageAsyncQueryHandler extends AsyncQueryHandler {
public MessageAsyncQueryHandler(ContentResolver cr) {
super(cr);
}
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
if (cursor == null)
return;
Log.d(TAG, " on query message complete size " + cursor.getCount()+"--token:"+token);
ArrayList<MessageCache> results = new ArrayList<MessageCache>();
//数据分页查询结果返回
if (token == SmsProviderHelp.MESSAGES_LIST_QUREY_TOKEN) {
if(cursor != null && cursor.getCount() != 0 && cursor.moveToFirst()){
while (!cursor.isAfterLast()) {
MessageCache cache;
try {
cache = new MessageCache(mActivity, cursor);
results.add(cache);
cursor.moveToNext();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Log.d(TAG, "--results.size():"+results.size()+"--singleQueryNum:"+singleQueryNum);
if(results.size() == singleQueryNum){
if(null != ptrl){
ptrl.refreshFinish(PulltoRefreshLayout.SUCCEED);
}
addDatatoAdapter(results);
mMessageAdapter.notifyDataSetChanged();
// if we load more message,we not need select last item.
Log.d(TAG, "--onQueryComplete--shouldFocusBottom:"+shouldFocusBottom);
if(shouldFocusBottom){
mListView.setSelectionFromTop(mDataList.size() - 1, 0);
shouldFocusBottom = false;
Log.d(TAG, "--setSelection--:"+(mDataList.size() - 1));
}else{
Log.d(TAG, "--setSelection--:"+(ONCE_ADD_DATA_NUM - 1));
mListView.setSelectionFromTop(ONCE_ADD_DATA_NUM - 1, 0);
}
}else{
// refresh failed
if(null != ptrl){
ptrl.refreshFinish(PulltoRefreshLayout.FAIL);
}
}
}
//数据库插入动作查询结果返回
else if(token == SmsProviderHelp.MESSAGES_INSERT_BY_ID_TOKEN){
if(cursor.getCount() != 0 && cursor.moveToFirst()){
MessageCache insertItem = null;
try {
insertItem = new MessageCache(mActivity, cursor);
} catch (Exception e) {
e.printStackTrace();
}
if(null != insertItem){
Log.d(TAG, "--insert one Item:"+insertItem.toString()+"--shouldFocusBottom:"+shouldFocusBottom);
mDataList.add(insertItem);
mMessageAdapter.notifyDataSetChanged();
if(shouldFocusBottom){
mListView.setSelectionFromTop(mDataList.size() - 1, 0);
shouldFocusBottom = false;
}
}

}
}
//数据库更新动作查询结果返回
else if(token == SmsProviderHelp.MESSAGES_UPDATE_BY_ID_TOKEN){
if(cursor.getCount() != 0 && cursor.moveToFirst()){
MessageCache updateItem = null;
try {
updateItem = new MessageCache(mActivity, cursor);
} catch (Exception e) {
e.printStackTrace();
}
if(null != updateItem){
Log.d(TAG, "--update one Item:"+updateItem.toString()+"--mID:"+updateItem.mID);
int position = mSparseArray.get(updateItem.mID, -1);
if(position != -1){
Log.d(TAG, "--position:"+position+"--replace the old value");
mDataList.set(position, updateItem);
mMessageAdapter.notifyDataSetChanged();
}
}
}
}
}
@Override
protected void onDeleteComplete(int token, Object cookie, int result) {
super.onDeleteComplete(token, cookie, result);
}
}


方法调用

查询方法:

public void startQuery (int token, Object cookie, Uri uri, String[] projection, String selection, String[] selectionArgs, String orderBy)

参数

token

在onQueryComplete中用作操作标识

cookie

传入 onQueryComplete(int, Object, Cursor)变量参数

uri

The URI, using the content:// scheme, for the content to retrieve.

projection

需要查询的列

selection

查询的条件语句

selectionArgs

查询的条件参数

orderBy

结果排序操作与 SQL 中的ORDER BY 一致

代码示例:

Uri uri = Uri.parse("content://mypro.message/messages");
asyncQuery.startQuery(token, null, uri, null, “_id = ?” +" and number = ?", new String[]{messageId,number},null);


总结:

通过上面步骤即可实现数据库操作的异步执行,不会影响到主线程的正常运行,避免在数据库操作上产生ANR异常。

上面的onQueryComplete回调,是自己实现的数据库消息分页加载、listView单项Item刷新的算法。

流程大概是:根据query token来区分是何种操作,此处有3种情况。

1. 分页查询结果返回。从cursor中解析出数据datalist,增加到list中(消息类型注意最新的消息在最下面)

2. 数据库插入动作查询结果返回。此处监听数据库的变化,可参考 通过ContentObserver监听数据库某表的增加、删除、更新动作,实现listView异步单项Item的刷新 当为insert操作时,根据messageId查询该条消息,查询完成返回增加到list中,调用notifyDataSetChanged

3. 数据库更新动作查询结果返回。此处监听数据库的变化,可参考 通过ContentObserver监听数据库某表的增加、删除、更新动作,实现listView异步单项Item的刷新 当为update操作时,根据messageId查询该条消息,查询完成返回增加到list中,调用notifyDataSetChanged

若对你有帮助或有任何疑问,可以一起交流学习。可以留言评论哦~

转载请注明出处:adayabetter的博客
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: