2010-10-20 38 views
18

我創建了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; 
    } 
    } 

從我的CP調用內CP之後,我recive意外的異常:

java.lang.UnsupportedOperationException: Only CrossProcessCursor cursors are supported across process for now 

異常由CP涉及光標的包裝和傳遞它包裹,外CP不能再次把它包裝所以我在這裏遇到問題。當我檢查返回的遊標類時,我收到CursorWrapperInner。是否有任何方法可以在我的外部CP中展開光標(從此CWI到常規光標)(但不是通過在循環中將所有數據傳輸到MatrixCursor - 這太耗時)。

回答

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; 
    } 
} 
0

據我所知你不能解開光標,因爲包裝類是私有的(它可能使用反射,但SecurityManager不會允許它),但你可以嘗試創建你自己的包裝器CrossProcessCursor包裝返回的遊標並由ContentProvider返回。

1

聽起來像你使用兩個apk的東西。您不應該在不同的ContentProviders中使用同一個應用程序中的其他內容提供程序。當另一個應用程序試圖使用你的ContentProvider時,你會得到這個錯誤。解決方案是讓您的自定義遊標實現實現CrossProcessCursor接口。