我正在创建ContentProvider,它是另一个ContentProvider的代理(用于安全问题并允许访问完整应用程序的部分功能)。
public class GFContactsProvider extends ContactsProvider implements
DatabaseConstants {
private Context mContext;
private ContentResolver mContentResolver;
@Override
public boolean onCreate() {
mContext = getContext();
mContentResolver = mContext.getContentResolver();
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Cursor result = mContentResolver.query(ContactsContract.getContactsURI(Long.parseLong(address.get(1))), null, null, null, ContactsContract.ContactColumns.SHOW_NAME);
return result;
}
}
从我的CP调用内部CP后,我发现意外的异常:
java.lang.UnsupportedOperationException: Only CrossProcessCursor cursors are supported across process for now
该异常涉及CP对Cursor的包装并将其传输包裹,外部CP无法再次包装它,所以我在这里遇到问题。当我检查返回游标的类时,我收到了CursorWrapperInner。
有没有办法在我的外部CP中打开游标(从这个CWI到常规Cursor)(但不是通过循环将所有数据传输到MatrixCursor - 这太费时了。)
答案 0 :(得分:10)
无需“解开”光标。问题是,如果您的内容提供者向另一个进程中运行的客户端提供结果,则从query()返回的Cursor必须实现CrossProcessCursor接口。文档(AFAICS)中没有说明,但您可以从日志中看到这一点。
您需要做的就是实现CrossProcessCursor接口,并将其包裹在光标周围。
// your query statement does not seem right..BTW
Cursor result = mContentResolver.query(...);
// now, you return a CrossProcessCursorWrapper.
return new CrossProcessCursorWrapper(result);
CrossProcessCursor方法的实现从AbstractCursor移植。稍作修改,编译器很高兴:
public class CrossProcessCursorWrapper extends CursorWrapper implements
CrossProcessCursor {
public CrossProcessCursorWrapper(Cursor cursor) {
super(cursor);
}
@Override
public CursorWindow getWindow() {
return null;
}
@Override
public void fillWindow(int position, CursorWindow window) {
if (position < 0 || position > getCount()) {
return;
}
window.acquireReference();
try {
moveToPosition(position - 1);
window.clear();
window.setStartPosition(position);
int columnNum = getColumnCount();
window.setNumColumns(columnNum);
while (moveToNext() && window.allocRow()) {
for (int i = 0; i < columnNum; i++) {
String field = getString(i);
if (field != null) {
if (!window.putString(field, getPosition(), i)) {
window.freeLastRow();
break;
}
} else {
if (!window.putNull(getPosition(), i)) {
window.freeLastRow();
break;
}
}
}
}
} catch (IllegalStateException e) {
// simply ignore it
} finally {
window.releaseReference();
}
}
@Override
public boolean onMove(int oldPosition, int newPosition) {
return true;
}
}
答案 1 :(得分:1)
听起来像你使用两个apk或什么的。你不应该在同一个应用程序中使用彼此的不同ContentProviders。当另一个应用程序尝试使用您的ContentProviders时,您会收到此错误。解决方案是让您的自定义Cursor实现实现CrossProcessCursor接口。
答案 2 :(得分:0)
据我所知你无法打开Cursor,因为包装类是私有的(可能是使用反射但安全管理器可能不允许)但你可以尝试创建自己的包装器来实现CrossProcessCursor ,包装返回的光标,由ContentProvider返回。