昨天使用ContentProvider出问题了。。。。
昨天写一个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对象而不是
所以在这时候,第一种方法强制类型转换会报错。。。。第二种方法则没有问题,可以转换后跨进程传递!
纠结了一天。。。总算把这问题解决了。。。 根源就是向下转型出的问题。