2012-03-05 15 views
7

पर एक बाकी दूरस्थ सर्वर के साथ एक SQL डेटाबेस को सिंक्रनाइज़ मैं के लिए सर्वोत्तम प्रक्रियाएं एक कस्टम एंड्रॉयड ContentProvider जो दुकानों और एक SQLite डेटाबेस से डेटा को पुन: प्राप्त किया है।एंड्रॉयड

के डीबी तालिकाओं में से एक मान लेते हैं एक _ID स्तंभ और एक NAME स्तंभ और इस तरह एक सामग्री है:

|==========|==========| 
| _ID | NAME | 
|==========|==========| 
| 1  | d1 | 
| 2  | d2 | 
| 3  | d3 | 
| 4  | d4 | 
|==========|==========| 

यह SQLite DB एक दूरस्थ डेटाबेस के साथ सिंक में रखा जाता है और नए डेटा समय-समय पर अधिक प्राप्त किए गए है जाल।

  1. मौजूदा पंक्तियों को हटाया जा सकता
  2. नई पंक्तियों जोड़ा जा सकता है
  3. मौजूदा पंक्तियों के नाम स्तंभ संशोधित किया जा सकता

अब चलो: मेज पर संभव संचालन इस प्रकार हैं मान लेते हैं कि सभी संभव संचालन एक ही बार में होती हैं और एक दूरस्थ सर्वर से कुछ करने की तारीख डेटा लाते समय के बाद, इस तालिका के लिए नई सामग्री निम्नानुसार निर्धारित किए हैं:

|==========|==========| 
| _ID | NAME | 
|==========|==========| 
| 1  | d7 | 
| 3  | d3 | 
| 4  | d6 | 
| 5  | d5 | 
|==========|==========| 

वहाँ ऐसा करने के लिए दो अलग-अलग दृष्टिकोण हो सकता है:

  1. क्वेरी डेटाबेस और प्रत्येक मौजूदा पंक्तियों की जाँच को देखने के लिए अगर वे अद्यतन करने की आवश्यकता है, तो किसी भी नई पंक्तियाँ जोड़ सकते हैं और किसी भी लापता हुई पंक्तियां हटाना - हालांकि इस विधि हम एक पेजिनेशन दृष्टिकोण के साथ डेटाबेस को अपडेट करना चाहते हैं, न कि एक नेटवर्क लाने के साथ
  2. संपूर्ण तालिका को एक DELETE SQL कमांड के साथ हटाएं और फिर सर्वर
  3. से प्राप्त सभी पंक्तियां जोड़ें

एंड्रॉयड पर, मैं वर्तमान में बैच कार्रवाई साथ दूसरी विधि को लागू कर रहा हूँ प्रदर्शन को अधिकतम करने:

final ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(); 

// with this URI, the content provider deletes all rows 
operations.add(ContentProviderOperation.newDelete(Users.CONTENT_URI).build()); 

final ContentValues values = new ContentValues(); 
values.put(ID_COLUMN, 1); 
values.put(NAME_COLUMN, "d7"); 
values.put(ID_COLUMN, 3); 
values.put(NAME_COLUMN, "d3"); 
values.put(ID_COLUMN, 4); 
values.put(NAME_COLUMN, "d6"); 
values.put(ID_COLUMN, 5); 
values.put(NAME_COLUMN, "d5"); 

operations.add(ContentProviderOperation.newInsert(Users.CONTENT_URI).withValues(values).build()); 

getApplicationContext().getContentResolver().applyBatch(MyContentProvider.AUTHORITY, operations); 

इस का सबसे अच्छा तरीका है, या विधि 1 (या किसी अन्य विधि) प्रदर्शन के मामले में बेहतर होगा ?

संपादित करें: उदाहरण के लिए, दृष्टिकोण 2 लेना, एक ओवरराइड ContentProvider#bulkInsert जो डेटाबेस लेनदेन का उपयोग करता है बैच-सम्मिलन ऑपरेशन को बहुत तेज कर सकता है: this question देखें।

उत्तर

1

सबसे अच्छा विकल्प उचित API कार्यान्वयन की आवश्यकता है - जब आप कुछ db_version (पूर्णांक या अंतिम अद्यतन की टाइमस्टैम्प, या जो कुछ भी) संग्रहीत करना चाहिए।

और अद्यतन सर्वर के दौरान डेटा, और ऑपरेशन प्रकार के साथ प्रतिक्रिया करता है - जोड़ने, अपडेट को हटा दें।

+0

मुझे डर है कि यह संभव नहीं है हूँ। सर्वर आरईएसटी एपीआई सिर्फ जेएसओएन प्रतिनिधित्व में वस्तुओं की सूची देता है और यह क्लाइंट अज्ञेयवादी है। सर्वर से कोई सिंक-विशिष्ट जानकारी उपलब्ध नहीं है। –

+1

सभी हटाएं और फिर नए आइटम डालें। – kzotin

+1

हां, मुझे यह भी लगता है कि इस मामले में यह एकमात्र विकल्प है। मैं बस सोच रहा था कि अगर मैं इस सिंक एपीआई को जोड़ने के लिए वेब सेवा लोगों को मनाने में कामयाब रहा, तो इससे अधिक लचीलापन बढ़ जाएगा। एंकर आखिरी संशोधित दिनांक हो सकता है और एक क्लाइंट उन सभी आइटम्स के लिए सर्वर से पूछ सकता है जिन्हें निर्दिष्ट दिनांक के बाद जोड़ा/संशोधित/हटा दिया गया है। हालांकि, हटाए गए आइटमों के लिए, सर्वर को हटाए गए आइटमों का ट्रैक रखने की आवश्यकता है, लेकिन कैसे?हो सकता है कि वास्तव में किसी भी आइटम को हटाया जाए लेकिन उन्हें डेटाबेस में "हटाए गए" के रूप में चिह्नित किया जाए? क्या इस मामले में डीबी आकार की आवश्यकता नहीं होगी? –