Provider中查询的一个Cursor对象问题
来源:互联网 发布:keynote在windows播放 编辑:程序博客网 时间:2024/06/11 21:59
昨天写一个provider的时候出现了如下问题:
写完之后在同一个进程内使用provider完全没有问题,但是一旦到其他进程(另一个apk)里使用的时候就会报错
E/DatabaseUtils( 339): Writing exception to parcel
E/DatabaseUtils( 339): java.lang.UnsupportedOperationException: Only CrossProcessCursor cursors are supported across process for now
E/DatabaseUtils( 339): at android.database.CursorToBulkCursorAdaptor.<init>(CursorToBulkCursorAdaptor.java:97)
E/DatabaseUtils( 339): at android.content.ContentProvider$Transport.bulkQuery(ContentProvider.java:122)
E/DatabaseUtils( 339): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:98)
E/DatabaseUtils( 339): at android.os.Binder.execTransact(Binder.java:287)
E/DatabaseUtils( 339): at dalvik.system.NativeStart.run(Native Method)
E/DatabaseUtils( 339): Caused by: java.lang.ClassCastException: android.content.ContentResolver$CursorWrapperInner
E/DatabaseUtils( 339): at android.database.CursorToBulkCursorAdaptor.<init>(CursorToBulkCursorAdaptor.java:81)
这就奇怪了,ContentProvider不就是问了跨进程才出现的啊。现在已跨进程就出问题。。。。那不就相当与没用了。
provider的query方法里面大概是这样写的
String whereInext = "";
if(number.indexOf("1") >= 0 || number.indexOf("0") >= 0){
//search the contacts directly,no need to get the where at all
return null ;
} else {
whereInext = this.getPinYinWhere(number);
}
return db.query(TABLE_CONTACT_INDEX, null, whereInext, null, null, null , null);
看 上去好像没错。。。返回的也是一个Cursor对象。。。其实不然。。。代码稍作修改就行了,正确的代码如下:
String whereInext = "";
if(number.indexOf("1") >= 0 || number.indexOf("0") >= 0){
//search the contacts directly,no need to get the where at all
return null ;
} else {
whereInext = this.getPinYinWhere(number);
}
SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
sqlBuilder.setTables(TABLE_CONTACT_INDEX);
Cursor cursor = sqlBuilder.query(db, null, whereInext, null , null , null , null);
Log.d("cx","--------number is-------"+number+"-----where from number is-----"+whereInext);
return cursor;
同样都是返回的Cursor对象。。。为什么上一种方法就会出问题呢。。
其实是这样的:
这就是java的多态,返回的都是一个Cursor对象。。。这就是为什么向下转型是不安全的。。。
provider将cursor跨进程传递时将会强制向下转换为CrossProcessCursor类型。。。。
就在这时候,只有第二种方法中返回的cursor原始的类型 is a CrossProcessCursor,然而第一种方法返回的curso对象而不是
所以在这时候,第一种方法强制类型转换会报错。。。。第二种方法则没有问题,可以转换后跨进程传递!
注意1:按照作者的意思第一种方式db.query返回的cursor不是个CrossProcessCursor,所以出错。但是我在2.2中测试来看它返回的是CrossProcessCursor。之后查阅2.2中SQLiteDatabase的源码,它返回的是SQLiteCursor,SQLiteCursor继承于AbstractWindowedCursor,而AbstractWindowedCursor又继承于AbstractCursor,而AbstractCursor又是实现了CrossProcessCursor。它和测试结果相符合。作者的Android可能是更早期的版本,才引起他所说的问题。
另外我才android4.0源码中看到无论SQLiteDatabase还是SQLiteQueryBuilder都是调用SQLiteDatabase的rawQueryWithFactory()方法来进行查询的,且返回类型都是声明为Cursor.
注意2:ContentProvider在进程中传递Cursor对象,需要将其转化CursorToBulkCursorAdaptor。(具体可以参照源码ContentProviderNative的bulkQuery函数)
但是其实我通过ContentResolver最后查询返回所得的Cursor对象并不是CursorToBulkCursorAdaptor。
- Provider中查询的一个Cursor对象问题
- android provider 中关于Cursor的一个问题
- Android数据库操作查询中Cursor类的问题
- Cursor使用过程中遇到的一个问题
- 解决django中使用cursor查询带like的sql问题
- Android Cursor的问题 如何查询得到的内容很多,如何取其中的特定的一个
- Android中Cursor关闭的问题
- Android中Cursor关闭的问题
- Android中Cursor关闭的问题
- Android中Cursor关闭的问题
- Android中Cursor关闭的问题
- Android中Cursor关闭的问题
- AE使用Cursor查询时遇到的问题0x8004020A
- Content Provider中主键的问题
- Android 中查询数据库时Cursor类的使用
- Android 中查询数据库时Cursor类的使用
- Android中Cursor对象的几种生成方法
- Android自定义Cursor遇到的一个小问题
- throw和throws区别
- Binnis——一项全新的类壁球运动
- 通过ANR来查看死锁
- HTML5之Worker用法
- Gmail Exchange ActiveSync Settings
- Provider中查询的一个Cursor对象问题
- 判断密码的js
- 批处理操作注册表教程(上)
- ProviderTestCase2实例
- 批处理操作注册表教程(下)
- 1.41亿部手机装有间谍软件! 360推国内首个CIQ查杀工具
- 页面下拉菜单 div ul li css
- MDIFrameWnd类GetActiveFrame和MDIGetActive的区别
- android_launcher的源码详细分析和壁纸修改