2010-10-20 12 views
18

मैं 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; 
    } 
    } 

मेरी सी.पी. से भीतरी सी.पी. कॉल करने के बाद मैं अनपेक्षित अपवाद recive:

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

अपवाद सी.पी. द्वारा कर्सर की रैपिंग से संबंधित है और यह लिपटे हस्तांतरण, आउटर सी.पी. इसे फिर से लपेट नहीं कर सकते तो मुझे यहाँ एक समस्या है। जब मैंने लौटा कर्सर की कक्षा की जांच की तो मुझे कर्सरवापर इंटर्नर मिला। क्या मेरे बाहरी सीपी में कर्सर को खोलने का कोई तरीका है (इस सीडब्ल्यूआई से नियमित कर्सर तक) लेकिन लूप में मैट्रिक्स कर्सर में सभी डेटा ट्रांसफर करके नहीं - यह बहुत समय लेने वाला है)।

उत्तर

10

कर्सर को "अनचाहे" करने की कोई आवश्यकता नहीं है। समस्या यह है कि, यदि आपका कंटेंट प्रदाता किसी क्लाइंट को परिणाम प्रदान कर रहा है जो किसी अन्य प्रक्रिया में चलता है, तो कर्सर जिसे आप क्वेरी() से लौटाते हैं, को क्रॉसप्रोसेसर कर्सर इंटरफ़ेस को कार्यान्वित करना होगा। यह दस्तावेज (AFAICS) में नहीं बताया गया है, लेकिन आप इसे अपने लॉग से देख सकते हैं।

आपको केवल क्रॉसप्रोसेसर कर्सर इंटरफ़ेस को लागू करने की आवश्यकता है, और इसे अपने कर्सर के चारों ओर लपेटें।

// your query statement does not seem right..BTW 
Cursor result = mContentResolver.query(...); 
// now, you return a CrossProcessCursorWrapper. 
return new CrossProcessCursorWrapper(result); 

क्रॉसप्रोसेसर कर्सर विधियों का कार्यान्वयन सार कर्सर से पोर्ट किया गया है। कुछ मामूली संशोधन किए जाते हैं ताकि संकलक खुश हो:

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

जहां तक ​​मुझे पता है कि आप कर्सर को अनचाहे नहीं कर सकते हैं क्योंकि रैपर वर्ग निजी है (प्रतिबिंब का उपयोग करके यह संभव हो सकता है लेकिन सुरक्षा प्रबंधक शायद इसे अनुमति नहीं देगा) लेकिन आप अपना खुद का रैपर बनाने की कोशिश कर सकते हैं जो उपकरण CrossProcessCursor, लौटा कर्सर लपेटता है और आपके ContentProvider द्वारा वापस कर दिया जाता है।

1

लगता है जैसे आप दो एपीके या कुछ का उपयोग करते हैं। आपको एक ही एप्लिकेशन के भीतर एक दूसरे का उपयोग करके विभिन्न सामग्री प्रदाता के साथ यह नहीं मिलना चाहिए। जब कोई अन्य एप्लिकेशन आपके ContentProviders का उपयोग करने का प्रयास करता है, तो आपको यह त्रुटि मिलती है। समाधान आपके कस्टम कर्सर कार्यान्वयन को CrossProcessCursor इंटरफ़ेस को लागू करने देना है।