ซิงค์ข้อมูลระหว่างแอพ Android และเว็บเซิร์ฟเวอร์ [ปิด]


262

ฉันต้องการซิงค์ข้อมูล (เช่นบันทึก db สื่อ) ระหว่างแอพ Android และเซิร์ฟเวอร์ หากคุณเคยเห็นEvernoteหรือแอปพลิเคชั่นที่คล้ายกันคุณจะเข้าใจอย่างแน่นอนว่าฉันหมายถึงอะไร

ฉันมีคำถาม (จินตนาการว่าเราต้องการซิงค์ระเบียน DB):

  1. ผู้ใช้ทุกคนมีส่วนของพื้นที่เซิร์ฟเวอร์สำหรับตัวเขาเอง (เช่นEvernoteหรือDropbox) บางทีผู้ใช้อาจสร้างระเบียนใหม่ด้วยมือถือและสร้างระเบียนใหม่ในเซิร์ฟเวอร์ ฉันจะจับคู่บันทึกเหล่านี้เข้าด้วยกันได้อย่างไร หากมีการบันทึกด้วย ID เดียวกันอัลกอริทึมอะไรที่คุณแนะนำฉัน?

  2. ยกเว้นJSON , มีทางใดทางหนึ่งสำหรับข้อมูลที่ส่งระหว่างอุปกรณ์โทรศัพท์มือถือและเซิร์ฟเวอร์?

  3. หากSyncAdapterและContentProviderสามารถแก้ปัญหาของฉันได้โปรดอธิบายให้ฉันด้วย (หากคุณสามารถเสนอตัวอย่างหรือแบบฝึกหัดให้ฉันหรือคำแนะนำหรือคำหลักใด ๆ ที่ช่วยขยาย / แนะนำการค้นหาของฉันก็จะได้รับการชื่นชมเช่นกัน)


1
ก่อนอื่นคุณต้องคิดออก (ตัดสินใจ) โปรโตคอลการสื่อสารของคุณกับเซิร์ฟเวอร์ - ดังนั้น - ข้อมูลใดที่คุณสามารถถ่ายโอนและวิธี
hovanessyan

นั่นเป็นสิ่งสำคัญสำหรับฉันถ่ายโอนข้อมูล SQLlite แต่ฉันจะรู้วิธีการถ่ายโอนข้อมูลอื่น ๆ ฉันไม่เข้าใจค่าเฉลี่ยของคุณเกี่ยวกับโปรโตคอล โปรดอธิบายเพิ่มเติม
Omid Nazifi

โดยโปรโตคอลฉันหมายถึงsimple.wikipedia.org/wiki/Internet_Protocol
hovanessyan

1
ลอง konysync ผลิตภัณฑ์ของ konylabs ซึ่งให้บริการโซลูชั่นแบบครบวงจรในแพลตฟอร์มต่าง ๆ (android, windows, ios), webservers, ผู้ให้บริการข้อมูล (พนักงานขาย, ผู้ให้บริการ sap), ฐานข้อมูล (sqlserver, mysql ... )
saimadan

คำตอบ:


311

ฉันจะพยายามตอบคำถามของคุณทั้งหมดโดยตอบคำถามที่มีขนาดใหญ่กว่า: ฉันจะซิงค์ข้อมูลระหว่างเว็บเซิร์ฟเวอร์และแอป android ได้อย่างไร


การซิงค์ข้อมูลระหว่างเว็บเซิร์ฟเวอร์ของคุณกับแอพ Android นั้นต้องการส่วนประกอบที่แตกต่างกันสองอย่างในอุปกรณ์ Android

ที่เก็บถาวร:

นี่คือวิธีที่โทรศัพท์ของคุณจัดเก็บข้อมูลที่ได้รับจริงจากเว็บเซิร์ฟเวอร์ วิธีหนึ่งที่เป็นไปได้สำหรับการทำให้สำเร็จคือการเขียนContentProvider ที่คุณกำหนดเองซึ่งได้รับการสนับสนุนโดยฐานข้อมูล Sqlite บทแนะนำที่ดีสำหรับผู้ให้บริการเนื้อหาสามารถดูได้ที่นี่: http://thinkandroid.wordpress.com/2010/01/13/writing-your-own-contentprovider/

ContentProviderกำหนดอินเตอร์เฟซที่สอดคล้องกันในการโต้ตอบกับข้อมูลที่จัดเก็บของคุณ นอกจากนี้ยังอาจอนุญาตให้แอปพลิเคชันอื่นโต้ตอบกับข้อมูลของคุณได้หากคุณต้องการ เบื้องหลังContentProviderของคุณอาจเป็นฐานข้อมูล Sqlite, Cache หรือกลไกการจัดเก็บข้อมูลตามอำเภอใจ

ในขณะที่ฉันอยากจะแนะนำให้ใช้ContentProviderกับฐานข้อมูล Sqlite คุณสามารถใช้กลไกการจัดเก็บตามจาวาที่คุณต้องการ

รูปแบบการแลกเปลี่ยนข้อมูล:

นี่คือรูปแบบที่คุณใช้ในการส่งข้อมูลระหว่างเว็บเซิร์ฟเวอร์และแอพ Android ของคุณ สองรูปแบบที่ได้รับความนิยมสูงสุดในวันนี้คือ XML และ JSON เมื่อเลือกรูปแบบของคุณคุณควรคิดถึงไลบรารีการทำให้เป็นอนุกรมที่มีอยู่ ฉันรู้ว่ามีห้องสมุดที่ยอดเยี่ยมสำหรับการทำให้เป็นอนุกรม json เรียกว่า gson: https://github.com/google/gsonแม้ว่าฉันจะแน่ใจว่ามีไลบรารีที่คล้ายกันสำหรับ XML

บริการซิงโครไนซ์

คุณจะต้องการงานอะซิงโครนัสบางประเภทที่สามารถรับข้อมูลใหม่จากเซิร์ฟเวอร์ของคุณและรีเฟรชเนื้อหามือถือเพื่อแสดงเนื้อหาของเซิร์ฟเวอร์ นอกจากนี้คุณจะต้องแจ้งเตือนเซิร์ฟเวอร์เมื่อใดก็ตามที่คุณทำการเปลี่ยนแปลงเนื้อหาในเครื่องและต้องการแสดงการเปลี่ยนแปลงเหล่านั้น Android ให้รูปแบบSyncAdapterเป็นวิธีการแก้รูปแบบนี้ได้อย่างง่ายดาย คุณจะต้องลงทะเบียนบัญชีผู้ใช้จากนั้น Android จะเล่นเวทมนต์ให้คุณมากมายและอนุญาตให้คุณทำการซิงค์โดยอัตโนมัติ นี่คือบทแนะนำที่ดี: http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1/


สำหรับวิธีที่คุณระบุว่าบันทึกนั้นเหมือนกันหรือไม่โดยทั่วไปคุณจะสร้างรายการที่มีรหัสเฉพาะที่คุณเก็บไว้ทั้งบนอุปกรณ์ android และเซิร์ฟเวอร์ คุณสามารถใช้สิ่งนั้นเพื่อให้แน่ใจว่าคุณกำลังอ้างถึงข้อมูลอ้างอิงเดียวกัน นอกจากนี้คุณสามารถจัดเก็บแอตทริบิวต์คอลัมน์เช่น "updated_at" เพื่อให้แน่ใจว่าคุณได้รับข้อมูลใหม่ล่าสุดเสมอหรือคุณไม่ได้เขียนทับข้อมูลที่เขียนใหม่โดยไม่ได้ตั้งใจ


3
แล้วข้อมูลจำนวนมากล่ะ ฉันจะซิงค์ได้อย่างไร
Pratik Butani

4
อธิบายได้ดีมากฉันเพิ่งได้ทราบ ... SyncAdapter -> "แสดงเวทย์มนตร์มากมาย" ฉันหวังว่าคุณจะพูดถึงมันว่าเป็นมนต์ดำ
MRodrigues

@Mododues: SyncAdapter อาจเป็นมนต์ดำสำหรับนักพัฒนา แต่มันยังคงทำเวทมนตร์เพื่อความมั่นคงและฟังก์ชั่นมันจะดีกว่า libs อื่น ๆ อีกมากมาย
Milad Metias

2
เว็บเซอร์วิซต้องใช้อะไรในการซิงค์กับอุปกรณ์ android เป็นไปได้ไหมกับ Spring?
jublikon

58

ถ้าเราคิดเกี่ยวกับวันนี้ , คำตอบที่ได้รับการยอมรับเป็นรุ่นเก่าเกินไป ดังที่เราทราบว่าเรามีห้องสมุดใหม่มากมายที่สามารถช่วยคุณสร้างแอพพลิเคชั่นประเภทนี้

คุณควรเรียนรู้หัวข้อต่อไปนี้ที่จะช่วยให้คุณ:

  • SyncAdapter:องค์ประกอบของอะแดปเตอร์ซิงค์ในแอปของคุณหุ้มรหัสสำหรับงานที่ถ่ายโอนข้อมูลระหว่างอุปกรณ์และเซิร์ฟเวอร์ ขึ้นอยู่กับการตั้งเวลาและทริกเกอร์ที่คุณระบุในแอปกรอบการซิงค์อะแดปเตอร์จะรันโค้ดในองค์ประกอบอะแดปเตอร์ซิงค์

  • ดินแดน : ดินแดนเป็นฐานข้อมูลมือถือ: แทนที่ข้อมูล SQLite & Core

  • Retrofitไคลเอนต์ HTTP ที่ปลอดภัยสำหรับ Android และ Java โดย Square, Inc. ต้องเรียนรู้การติดตั้งเพิ่มที่ชาญฉลาด

และตรรกะการซิงค์ของคุณสำหรับฐานข้อมูลเช่น: วิธีการซิงค์ฐานข้อมูล SQLite บนโทรศัพท์ Android กับฐานข้อมูล MySQL บนเซิร์ฟเวอร์?

ขอให้โชคดีสำหรับผู้เรียนใหม่ทุกคน :)


ลิงก์ไปยังชุดติดตั้งเพิ่มที่ใช้งานไม่ได้
Greg Holst

@GregHolst อัปเดตแล้ว
Pratik Butani

3
นิ่ง ๆ หรือต้องเข้าสู่ระบบ? Archive.org มีไว้: web.archive.org/web/20160316222227/https://futurestud.io/blog/…
bobpaul

24

หากคุณเขียนสิ่งนี้ด้วยตัวเองสิ่งเหล่านี้คือสิ่งที่คุณควรคำนึงถึง

การตรวจสอบความถูกต้องที่เหมาะสมระหว่างอุปกรณ์และ Sync Server

โปรโตคอลการซิงค์ระหว่างอุปกรณ์และเซิร์ฟเวอร์ มันมักจะไปใน 3 ขั้นตอนการตรวจสอบการแลกเปลี่ยนข้อมูลการแลกเปลี่ยนสถานะ (การดำเนินงานที่ทำงานและที่ล้มเหลว)

เลือกรูปแบบน้ำหนักบรรทุกของคุณ ฉันแนะนำ SyncML ที่อิงกับ XML ผสมกับรูปแบบที่ใช้ JSON เพื่อแสดงข้อมูลจริง ดังนั้น SyncML สำหรับโปรโตคอลและ JSON สำหรับข้อมูลจริงที่มีการแลกเปลี่ยน การใช้ JSON Array ในขณะที่จัดการข้อมูลเป็นสิ่งที่ต้องการอยู่เสมอเพราะเข้าถึงข้อมูลได้ง่ายโดยใช้ JSON Array

การติดตามการเปลี่ยนแปลงข้อมูลบนไคลเอนต์และเซิร์ฟเวอร์ คุณสามารถรักษารหัสการเปลี่ยนแปลงที่เปลี่ยนและหยิบขึ้นมาในระหว่างการซิงค์ นอกจากนี้ให้ล้างการเปลี่ยนแปลงเนื่องจากวัตถุถูกซิงโครไนซ์เรียบร้อยแล้ว คุณยังสามารถใช้ตัวแปรบูลีนเพื่อยืนยันสถานะการซิงโครไนซ์เช่นครั้งสุดท้ายของการซิงค์ จะเป็นประโยชน์สำหรับผู้ใช้ปลายทางในการระบุเวลาที่การซิงค์ครั้งสุดท้ายเสร็จสิ้น

จำเป็นต้องมีวิธีในการสื่อสารจากเซิร์ฟเวอร์ไปยังอุปกรณ์เพื่อเริ่มเซสชันการซิงค์เมื่อมีการเปลี่ยนแปลงข้อมูลบนเซิร์ฟเวอร์ คุณสามารถใช้ C2DM หรือเขียนการสื่อสารด้วย tcp แบบถาวรของคุณเอง วิธี tcp นั้นราบรื่นมาก

วิธีการจำลองการเปลี่ยนแปลงข้อมูลในอุปกรณ์หลายเครื่อง

และวิธีการสุดท้ายในการตรวจจับและจัดการกับความขัดแย้ง

หวังว่านี่จะช่วยเป็นจุดเริ่มต้นที่ดี


14

@Grantismo ให้คำอธิบายที่ดีเกี่ยวกับภาพรวม หากคุณต้องการทราบว่าผู้คนทำสิ่งนี้จริง ๆ ฉันขอแนะนำให้คุณดูว่า Google ทำอย่างไรกับแอป Google IO ของปี 2014 (มันคุ้มค่าที่จะดูที่ซอร์สโค้ดของแอปเหล่านี้อย่างลึกซึ้งเสมอ มีอะไรให้เรียนรู้มากมายจากที่นั่น)

นี่คือบล็อกโพสต์เกี่ยวกับมัน: http://android-developers.blogspot.com.br/2014/09/conference-data-sync-gcm-google-io.html

โดยพื้นฐานแล้วในด้านแอปพลิเคชัน: GCM สำหรับการส่งสัญญาณ Sync Adapter สำหรับดึงข้อมูลและพูดคุยอย่างถูกต้องกับผู้ให้บริการเนื้อหาที่จะทำให้สิ่งต่าง ๆ คงอยู่ (ใช่มันแยกฐานข้อมูลออกจากการเข้าถึงโดยตรงจากส่วนอื่น ๆ ของแอป)

นอกจากนี้หากคุณต้องการดูรหัสของปี 2558: https://github.com/google/iosched


ซอร์สโค้ดสำหรับแอป Google IO นั้นมีประโยชน์มากสำหรับ IMO!
Richeek

10

ตัวอย่างเช่นคุณต้องการซิงค์ตารางtodoTableจากMySqlถึงSqlite

ขั้นแรกให้สร้างชื่อคอลัมน์หนึ่งversion (type INT)ในtodoTableสำหรับทั้งสองSqliteและMySql ป้อนคำอธิบายรูปภาพที่นี่

ขั้นที่สองสร้างชื่อตารางdatabase_versionด้วยชื่อคอลัมน์เดียวcurrentVersion(INT)
ป้อนคำอธิบายรูปภาพที่นี่

ในMySqlเมื่อคุณเพิ่มรายการใหม่ลงtodoTableหรือรายการปรับปรุงคุณต้องอัปเกรดเวอร์ชันของรายการนี้โดย 1 และยังอัพเกรดcurrentVersion ป้อนคำอธิบายรูปภาพที่นี่

ในAndroidเมื่อคุณต้องการซิงค์ (โดยกดปุ่มซิงค์ด้วยตนเองหรือบริการที่ทำงานตามช่วงเวลา):

คุณจะส่งคำร้องขอกับSqlitecurrentVersion (ปัจจุบันคือ 1) ไปยังเซิร์ฟเวอร์
จากนั้นในเซิร์ฟเวอร์คุณจะพบสิ่งที่รายการที่MySqlมีค่ารุ่นมากกว่าSqlitecurrentVersion (1) แล้วตอบสนองต่อ Android (ในตัวอย่างนี้รายการ 3 กับรุ่น 2 จะตอบสนองต่อ Android)

ในSQLiteคุณจะเพิ่มหรืออัปเดตรายการใหม่todoTableและอัพเกรด currentVersion


1
ความคิดของคุณยอดเยี่ยม แต่ก็ยังไม่เข้าใจการออกแบบตารางอย่างถูกต้อง พร้อมกับบริการส่วนที่เหลือและบริการประสานที่เหมาะสมมันทำงานได้
Ahesanali Suthar

6

ดูparseplatform.org มันเป็นโครงการโอเพ่นซอร์ส

(เช่นเดียวกับที่คุณสามารถใช้สำหรับแพ็คเกจการค้าได้ที่back4app.com )

เป็นบริการฐานข้อมูลด้านเซิร์ฟเวอร์ที่เป็นมิตรและตรงไปตรงมาสำหรับผู้ใช้ที่ให้ API ฝั่งไคลเอ็นต์ Android ที่ยอดเยี่ยม


ข้อเสนอฟรีที่เสนอคืออะไร
Prakhar Mohan Srivastava

12
http://parse.com/ปิดตัวลง
Chintan Rathod

4
คุณยังคงสามารถใช้ฟังก์ชั่น parse.com ได้ แต่บนเซิร์ฟเวอร์ของคุณเองพวกเขาได้เปิดแหล่งข้อมูลไว้
geniushkg

3

วิธีหนึ่งในการทำให้สิ่งนี้สำเร็จให้มีแอพพลิเคชันฝั่งเซิร์ฟเวอร์ที่รอข้อมูล ข้อมูลสามารถส่งโดยใช้HttpRequestวัตถุใน Java หรือคุณสามารถเขียนTCP/IPยูทิลิตี้การถ่ายโอนข้อมูลของคุณเอง ข้อมูลสามารถส่งโดยใช้JSONรูปแบบหรือรูปแบบอื่น ๆ ที่คุณคิดว่าเหมาะสม ข้อมูลยังสามารถเข้ารหัสก่อนที่จะส่งไปยังเซิร์ฟเวอร์หากมีข้อมูลที่ละเอียดอ่อน แอปพลิเคชันเซิร์ฟเวอร์ทั้งหมดที่ต้องทำคือรอHttpRequestsให้ข้อมูลเข้ามาและแยกวิเคราะห์ข้อมูลและจัดเก็บไว้ที่ใดก็ได้ที่คุณต้องการ


จะตรวจสอบข้อมูลที่อัพเดทในแอพและเซิร์ฟเวอร์ในท้องที่ได้อย่างไร? และวิธีการรวมเข้าด้วยกัน? มันไม่ดีเลยที่ฉันส่งบันทึกทั้งหมดโดย JSON หรืออะไรก็ตามไปยังแอปพลิเคชันเพื่อรวมพวกเขา คุณคิดอย่างไร?
Omid Nazifi

2
คุณสามารถใช้การตั้งค่าสถานะเช่น "บนเซิร์ฟเวอร์" ด้วย int / bool 1/0 สำหรับใช่หรือไม่ เมื่อระเบียน / ไฟล์ / บล็อกของข้อมูลถูกส่งตรวจสอบความสำเร็จที่เซิร์ฟเวอร์และพลิกบิตเป็นใช่ ถ้าคุณใช้บางอย่างเช่น SQLite คุณสามารถทำ "SELECT * FROM my_table WHERE ส่ง = 0" เพื่อพิมพ์รายการใหม่เพื่อส่งบันทึกใหม่
Evan R.

1

ผมขอแนะนำให้ใช้โปรโตคอลเว็บเซอร์ไบนารีคล้ายกับรัฐ มันทำงานได้ดีมากและพวกเขามีการใช้ Android มันอาจจะหนักไปหน่อย แต่ขึ้นอยู่กับแอพพลิเคชั่นที่คุณกำลังสร้าง หวังว่านี่จะช่วยได้


1

@Grantismo ให้ภาพรวมที่ดีของส่วนประกอบการซิงค์ Android

ไลบรารี SyncManagerAndroid จัดเตรียมการปรับใช้การซิงค์แบบสองทางอย่างง่ายเพื่อเสียบเข้ากับกรอบการทำงานของ Android Sync (AbstractThreadedSyncAdapterOnPerformSync)

https://github.com/sschendel/SyncManagerAndroid

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.