Перетаскивание курсора в ContentProvider - PullRequest
18 голосов
/ 20 октября 2010

Я создаю 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 и его переноса, Outer CP может 'Оберните его снова, поэтому у меня возникла проблема.Когда я проверил класс возвращаемого курсора, я получил CursorWrapperInner.

Есть ли способ развернуть курсор (от этого CWI до обычного Cursor) во внешнем CP (но не путем передачи всех данных в MatrixCursor в цикле - это слишкомотнимающие много времени).

Ответы [ 3 ]

10 голосов
/ 09 марта 2011

Нет необходимости «разворачивать» курсор. Проблема заключается в том, что если ваш поставщик контента предоставляет результаты клиенту, работающему в другом процессе, курсор, возвращенный функцией query (), должен реализовывать интерфейс 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 голос
/ 08 января 2011

Похоже, вы используете два apk или что-то.Вы не должны получать это с разными ContentProviders, использующими друг друга в одном приложении.Когда другое приложение пытается использовать ваши ContentProviders, вы получаете эту ошибку.Решение состоит в том, чтобы позволить вашей пользовательской реализации Cursor реализовать интерфейс CrossProcessCursor.

0 голосов
/ 10 декабря 2010

Насколько я знаю, вы не можете развернуть Cursor, потому что класс-оболочка является закрытым (это может быть возможно с помощью отражений, но SecurityManager, вероятно, не допустит этого), но вы можете попытаться создать свою собственную обертку, которая реализует CrossProcessCursor , оборачивает возвращенный курсор и возвращается вашим ContentProvider.

...