在探究之前,需要确认下CursorLoader和ContentProvider的基本流程,以便于提供有力的理论支持,这次死循环调用
消耗时间比较久,根本原因是没有搞清楚CursorLoader和ContentProvider的结合过程
1.创建cursorLoader
@Override
public Loader<Cursor> onCreateLoader(int loaderID, Bundle arg1)
{
//创建一个cursorLoader,确定了当收到变化通知时,如何进行 query
//cursorLoader第一次加载时,会触发查询,查询会触发观察者的注册过程
//离开了loader 所在界面,loader查询不会被触发的,返回界面时触发
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor returnCursor)
//当查询完成,会窒息onLoadFinished,经过测试,目前发现都是在主线中
2.
try {
cursor = db.query(tableName, projection, finalSelection, selectionArgs,
null, null, sortOrder);
} catch (Exception e) {
e.printStackTrace();
}
if (cursor != null) {
//实际是注册观察者,监听范围是 DBAuthority.DB_AUTHORITY_URI)
//根据实践认为,如果没有cursorLoader存在,这个注册是无效的
cursor.setNotificationUri(getContext().getContentResolver(), DBAuthority.DB_AUTHORITY_URI);
}
3.内容发送变更通知观察者
SQLiteDatabase db = mDbHelper.get().getWritableDatabase();
String tableName = getUriMatcher().getTableName(match);
int affectedRows = 0;
try {
B: affectedRows = db.update(tableName, values, selection, selectionArgs);
} catch (Exception e) {
e.printStackTrace();
}
A:getContext().getContentResolver().notifyChange(uri, null);
A的含义是通知所有观察者,uri对应的内容发生变化了,注意,根据实践测试,请不要认为只有监控这个uri的观察者才能收到
如果B的操作不执行,那么A的通知不会生效
4.循环问题分析:
cursorLoader首次加载---刷新界面---item从本地数据库获取信息失败---item 请求网络成功(但是没有item需要的数据)---修改数据库---触发第一步的cuerLoader变化‘
5.循环解决方案:
item请求网络的原因是item从本地获取信息失败,所以请求网络。
我们控制网络请求只能进行一次,避免反复请求
其他问题:数据库操作慢是因为接口没有增量返回,导致大量数据库操作,占用了线程池,可以在contentProvider相关操作打日志观察的到