2014-09-05 78 views
4

我正在創建一個使用REST API的android應用程序(我的第一個)。 我使用後臺作業來獲取內容,並計劃使用帶有from_id參數的GET請求以獲得更多內容。當然,從API獲取的任何東西都存儲在SQLite數據庫中(我正在使用greendao),並且該應用程序僅使用已存在的數據,以便快速完成。你如何處理移動應用程序中的陳舊緩存記錄

所以,問題是:如果給定的記錄在服務器上更新會發生什麼?如果一旦讀取的記錄被緩存,應用程序將如何注意到同步有變化?哪些策略可行?

謝謝。

編輯:

由於薩蒂什p在他的回答中指出,客戶端 - 服務器通信與處理的ETag(我必須添加使用IF-Modified-Since的可能性)。

但我主要關心的是如何將這與應用程序UI混合使用。鑑於此示例:

  1. 從本地數據庫中讀取已從REST服務中檢索到但從客戶端獲取的元素的列表,以使應用程序更具響應性。
  2. 用戶單擊其中一個元素並顯示詳細視圖。同樣,數據從本地數據庫加載。我猜想在這一點上,請求使用ETag或If-Modified-Since標題的特定記錄的GET請求。
  3. 恰巧,服務器返回一個修改後的記錄,因此本地數據被修改,所以現在是時候更新用戶所看到的任何內容。

問題:如果詳細視圖已填充,因爲當遠程請求返回,我怎麼能更新視圖本地數據庫讀取已經做了什麼?我不認爲用新鮮的數據替換當前數據是可以接受的,用戶會看到一個變化。

+0

我找到了一些資源,[這裏](https://neil.fraser.name/writing/sync/)和[here](http://codebrief.com/2013/08/client-sync) - 用於最其餘-的-US /)。你怎麼看? – Papipo 2014-09-07 10:47:59

+0

那麼,那些更多關於修補資源,而不是檢查是否過時。 – Papipo 2014-09-07 21:26:37

回答

3

薩蒂斯的回答是絕對正確的,你需要你的服務器做什麼。要點是它需要支持ETags和304響應代碼,以防上次從服務器獲取內容後內容沒有改變。現在在客戶端,基本上有三種策略可以遵循(每種策略都有自己的優點和缺點):

  1. 只有在內容未更改時才使用緩存。這意味着您將始終執行請求並向用戶顯示進度條。如果服務器返回304,那麼你的內容沒有改變,並且請求會非常快(你看到的那一刻,你顯示緩存的內容)。如果服務器實際返回新內容,則繼續顯示進度條,並在加載內容時顯示新內容。關於這一點的好處是,用戶只會看到有效的內容,因此避免了您的很多麻煩。壞消息是該應用程序沒有出現那麼快(特別是如果內容發生了變化並且連接速度很慢)。
  2. 僅在預定義時間段內使用高速緩存,然後回退到第一種情況。有幾個緩存頭可以定義這段時間('max-age'和'Expires')。在這段時間之前,您總是使用緩存(而不需要請求),然後執行請求並查看內容是否已更改。這種方法的好處是,在上述期間,應用程序非常快。壞消息是用戶有可能看到不正確的內容。
  3. 在預定義時間段內同時使用緩存和網絡,然後回退到第一種情況。您可以以不同的方式使用前面提到的緩存頭。您可以實際顯示緩存的內容並在後臺執行請求,而不僅僅顯示緩存的內容。如果請求返回了304,那麼很好,否則你將不得不使用新數據更新UI(期待兩個響應,一個使用緩存數據,一個使用新檢索數據)。積極的是,你可以獲得快速的體驗和有效的數據(大部分時間)。否定的是,你爲你的應用增加了很多複雜性(如果用戶與陳舊的數據交互,然後第二個響應進入等等,會發生什麼)。

總而言之,根據用例,每種策略都是有效的。例如,如果用戶無法與顯示數據的屏幕(如電視節目)進行交互,則第三個選項非常好。如果用戶看到正確的數據至關重要(比如說一個財務應用程序),那麼第一個選項是最好的選擇。如果速度比擁有最新數據(遊戲或其他)更重要,那麼第二個選項是您的最佳選擇。

+0

感謝您的全面解答。在第三種選擇中,我潛意識中的是一個我正在考慮的選項,你如何更新數據,使其看起來不會「突然」改變? (這是它實際上做的,因爲你需要改變陳舊的數據)。 – Papipo 2014-09-17 14:10:45

+1

這是一個UI問題,但我認爲最適合我的是立即顯示您的緩存數據,但是當您在做請求時,有一個微調器顯示屏幕上的某處(我相信該操作欄對此非常完美)。當數據再次加載時,您只需使用新數據,在適配器上執行'notifyDatatSetChanged',並隱藏微調器。這樣對用戶來說數據已經改變很明顯,但是不會破壞他的導航體驗(例如,如果可能的話,列表視圖將保持滾動到相同的位置)。 – 2014-09-18 10:00:56

2

客戶端可以執行緩存的效率完全取決於您從客戶端訪問的REST API獲得多少支持。

使用ETag是使客戶端的緩存更加高效並且服務器更快地服務於請求的行業標準。簡而言之,ETag就是返回內容的MD5散列。有關ETag的更多信息,請訪問:http://en.wikipedia.org/wiki/HTTP_ETag

如果它是Google,Facebook等流行的API,它們固有地支持ETags。 請看下面的鏈接:

ETag的使用這裏最好的解釋:https://developers.facebook.com/docs/reference/ads-api/etags-reference

  • 當客戶端上的特定資源GET,當與內容回覆我們應該包括一個ETag服務器。
  • 客戶端應該針對緩存的數據存儲該資源的ETag。
  • 無論客戶何時使用緩存信息,它都應該使用ETag驗證緩存。取決於服務實施,可以以多種方式再次工作
    • 對資源進行常規GET並將ETag作爲請求的一部分包含在內。如果內容沒有改變,服務理想情況下不會返回任何數據,但會給出特定的代碼,如(304 - 未修改)。客戶端知道緩存仍然有效並繼續使用它
    • 在資源上進行HEAD調用並返回ETag。它是標準HTTP規範的一部分。 http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html(參考9.4)。在這種情況下,客戶端將驗證ETag並決定是否進行GET調用。

樣品在上述的解釋一個資源的是像下面

GET http://serverapi.com/employees/2312312312 
+0

現在的事情是,如何支持客戶端差異(是否有任何庫?)以及如何處理本地記錄的更新,考慮到當更新的數據被檢索時,記錄顯示在屏幕(儘管從本地數據庫中檢索)。除了diff +更新本地數據外,移動應用程序還應更新屏幕上顯示的任何內容,並且應該優雅地進行。 – Papipo 2014-09-11 12:50:33

+0

你最好更新整個記錄,不要做差異和更新。查詢,比較和更新僅更改更爲昂貴。數據的更新將在後臺進行,之後可以在屏幕上顯示滾動更新數據等用戶事件。應該有其他的方式來更新Android上的應用程序屏幕,但我的應用程序開發經驗是有限的。我可以幫助您使用REST和緩存策略。 – 2014-09-11 14:11:34

-1

屏幕更新可以相當正常通過的Javascript處理,在DOM重寫特定元素 - 任選地將CSS格式以引起用戶注意UI中的更改 - 如果UI中的每個數據都具有唯一的ID /容器ID,或者可以由JS定位。

打敗某些緩存的簡單/等價方法是將查詢字符串追加到所需的資源。例如,可以在testfile.csv?12345上輕鬆訪問名爲testfile.csv的文件,並且在下一次要繞過緩存時,只需更新查詢字符串,例如testfile.csv?23456。如果手動更新查詢字符串在您的上下文中很繁瑣,那麼以PHP的性能適中命中爲代價來獲得更高的智能:調用資源testfile.csv以使查詢字符串在每個查詢之後自動更新資源被修改;獲取更新後的版本而不是緩存的版本。

+0

對不起,這不是一個混合的應用程序問題,也不是一個網站,因此JavaScript和CSS提到這裏沒有很多意義。 – Papipo 2014-09-17 14:11:27

0

最近我一直在使用GraphQL和Apollo。它自動處理所有這些東西,這很簡單。

相關問題