ContentProvider中的光标包装/解包

Viv*_*viQ 18 android cursor android-contentprovider

我正在创建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;
     }
    }
Run Code Online (Sandbox Code Playgroud)

从我的CP调用内部CP后,我发现意外的异常:

java.lang.UnsupportedOperationException: Only CrossProcessCursor cursors are supported across process for now
Run Code Online (Sandbox Code Playgroud)

例外涉及由CP包裹Cursor并将其传输包裹,外部CP不能再包装它,所以我在这里遇到问题.当我检查返回游标的类时,我收到了CursorWrapperInner.有没有办法在我的外部CP中打开游标(从这个CWI到常规Cursor)(但不是通过循环将所有数据传输到MatrixCursor - 这太费时了).

Den*_*ark 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);
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)