為移動應用提供離線支持

jopen 9年前發布 | 10K 次閱讀 移動應用

為移動應用提供離線支持

對移動應用的離線支持可以理解為應用在網絡連接不穩定的情況下能夠做出優雅的反應的能力。在移動設備這一相對較新的技術背景中,新的問題也隨之產 生,例如網絡連接的正常或異常、高延遲以及低帶寬等情況。這些問題出現的時間并不算長,剛剛上手進行移動開發的工程師對此并不十分了解。除此之外,創建一 個能夠適應不同網絡情況的移動應用可能還包括以下需求:

  • 在網絡調用失敗的情況下顯示適當的錯誤信息。
  • 允許在“訪客模式”下使用該應用,而某些特性只在用戶登錄之后才可以使用。
  • 在UI上明確地顯示出網絡連接斷開的信息(連接模式/離線模式)。
  • 在網絡連接斷開的情況下禁用某些控件。
  • 在沒有網絡連接的情況下也允許用戶進行數據查詢與操作(離線數據訪問)。
  • 在不同的網絡連接條件下對應用進行測試!
  • </ul>

    雖然以上這幾點從使用性的角度來看都是非常重要的,但其中某一點的復雜性尤為突出,即“離線數據訪問”。應用程序或許需要支持多種不同的離線數據訪問場景或是級別,在下文中我將一一進行講解。

    本地緩存

    應用程序在沒有網絡連接的情況下依然能夠顯示信息,而在連上網絡的情況下需要刷新數據。要實現這一點,需要在移動設備上對數據進行一定程度的持久化,并且通常需要保留一段時間。

    為移動應用提供離線支持

    對緩存中的數據進行刷新有三種不同的“策略”,接下來我將逐一進行分析。

    網絡優先

    總是嘗試從服務器上獲取數據,如果無法從服務器上獲取,再轉而從本地緩存中獲取數據。如果你特別希望總是顯示最近的、經過更新的信息,那么這種策略對你非常有幫助。

    本地優先

    在一段指定的時間之內完全不會從網絡上獲取數據,而是通過本地緩存進行獲取。如果你的應用能夠接受顯示被緩存的數據而不存在什么風險,那么這種方式非常適合你。另一方面,這種方式的用戶體驗更好,因為通常來說不會產生任何延遲。

    混合 / 智能

    這種方式在從服務端獲取數據之前先從本地緩存中返回結果。可以選擇等待服務端的通知,或是在后臺對服務進行輪詢的方式,對本地的緩存數據進行刷 新。這種機制能夠在性能與用戶體驗之間取得一種良好的平衡,而它仍然會對本地緩存進行定期刷新,避免了為用戶顯示“過期”數據的風險。

    此外,通過某種服務端緩存的支持,可以有效地彌補本地緩存的不足之處。正如HTTP緩存一樣,當需要從服務器獲取數據的時候,客戶端可以通過發送 一個“修訂號”以確認該數據是否已經被更新了。服務端將檢查客戶端所發送的修訂號是否與服務器上的數據一致,根據結果不同,或者通知客戶端不必更新數據, 或者將最新的數據返回。

    示例場景

    對于性能與用戶體驗的改進使得本地緩存在許多場景中非常實用,這種實用性的關鍵條件在于數據無需進行實時顯示。能夠將數據在本地緩存中保留的時間越長,這種方式的優點就越突出。

    這方面的例子包括用戶所感興趣的地區或聯系人,這種信息具有很高的實用性,同時又不太會非常頻繁地更新,因此是使用本地緩存理想的應用場景。

    本地隊列

    一旦應用程序失去了網絡連接,可以將服務器請求放入本地隊列,以便之后的處理。這種方式讓用戶能夠發起即發即棄(fire and forget)的操作,等到這些操作由服務器成功處理之后(如果確實經過處理的話)收到操作完成的通知信息。

    為移動應用提供離線支持

    在本地隊列處理多個操作時,你需要考慮以下問題:

    • 用戶應當收到該操作已加入隊列的通知。
    • 用戶很可能想要了解隊列的實際狀態,哪些操作已經完成了,還有哪些操作還在等待中?
    • 對于仍處于隊列中的操作來說,手動撤消或重試的能力或許是十分重要的。
    • 一旦這些操作被發送到服務器,用戶希望了解最終的處理結果(成功或失敗)。
    • 當操作進入隊列之后,用戶有可能需要重新啟動整個流程,因而需要中斷這個操作。
    • </ul>

      在使用者進行審核或測量等現場工作,以及發送報告時,本地隊列是一個很好的主意。如果這些操作不需要更新記錄,只是插入新記錄而已,那么整個實現會變得更加簡單,無需進行并發管理或沖突處理。

      示例場景

      本地隊列能夠幫助你在進行操作時無需等待其結果,這對于庫存檢查或審核等操作來說是非常重要的,讓使用者無需等待網絡連接也能夠使用該應用,或發送報告 。

      數據同步

      通過使用本地緩存與隊列,你就能夠保持設備與服務器數據的更新,這就是我們熟知的“同步”。有以下幾種方式可以實現數據同步。

      為移動應用提供離線支持

      保持移動端數據的更新

      在這種場景下,你需要讓你的移動應用數據保持同步。有兩種方式可以實現這一需求:如上文所描述的方式一樣使用本地緩存、或者向服務器請求最新的變 更。這些最新的變更也被稱為“增量”,能夠讓移動應用對服務器的當前狀態進行重建。為了能夠對最新的更新進行查詢,你需要使用一些審核字段,例如 ‘UpdatedOn’、 ‘CreatedOn’和‘DeletedOn’。

      在第二種場景中,數據在設備中并未修改,因此也無需處理任何沖突,因此服務器上的數據總是正確的。

      保持服務器數據的更新

      這一點可以通過使用本地隊列實現,但僅僅使用隊列本身是不夠的。如果在我的請求發送到服務器時,服務器上的數據狀態與我嘗試進行修改的時候已經有 所變化,這時該如何處理?如果請求的執行被延遲,例如出現網絡連接斷開的情況,就有可能造成并發沖突的增長。在這種情況下,開發者(或用戶)必須決定如何 對服務器與應用中的變更進行“合并”。對于每一次數據沖突來說,有以下幾種合并方式:

      • 保留設備上的版本
      • 保留服務器上的版本
      • 同時保留兩個版本
      • </ul>

        合并記錄的操作往往是由移動開發者通過自動化實現的。至于具體使用哪一種算法,要由應用程序的業務規則來確定。一旦出現無法完全自動化的情況,將提示用戶做出決定。

        同時保持移動端與服務器的數據更新

        這種方式也被稱為雙向同步。你很可能已經猜到了,這種策略是對以上兩種技術的一個結合,它是目前所描述的場景中最完整,也是最強大的。但請注意, 雖然創建一種可以支持雙向同步的應用很有誘惑性,但它也是目前為止最為復雜的一種場景。而且問題不僅僅在于它的復雜性,正如我在本文中已經提到的,雙向同 步并不總是必要的。

        示例場景

        雙向同步為移動應用帶來了一個全新級別的用戶體驗,而必須使用雙向同步方式的關鍵條件之一是讓一個團隊或小組里的所有用戶都能夠及時了解其它人的 活動情況。這方面的一個例子是協作應用,需要顯示更新、注釋或狀態變更的最新狀態。可以想象如果有一個協作式的地址簿,那么團隊中的每位成員都能夠在任何 時間更新其中的聯系人信息。

        思考

        為你創建的移動應用加入對離線場景的支持能夠極大地提高用戶體驗,但如何選擇合適的支持級別,并隨后實現這一功能,這并不是一件簡單的任務。我在下文中列舉了一些當你計劃為應用加入離線功能時應當考慮的問題。

        數據大小

        在進行數據本地緩存時,對于存儲的數據大小要有所警覺。盡量爭取在緩存的數據量與得到的用戶體驗改善之間達到一種良好的平衡,這一點十分重要。如 果數據量十分龐大(例如保存一個完整的Sharepoint網站內容),你可能必須考慮為用戶提供一個選項,讓他選擇要將哪些數據進行緩存,以用于離線閱 讀。

        數據存儲

        一定要對于如何進行數據存儲,以及存儲在何處作出明智的抉擇。這些數據是否包含敏感信息?如果是的話,就需要在保存數據時進行加密。而一旦你選擇 了對數據進行加密,請確保將解密數據所用的密鑰保存在一個安全的地方,可以考慮使用操作系統的功能實現這一點。還要注意一點,在某些平臺上你的應用程序代 碼是可以被閱讀(或反射)的,因此可以考慮對代碼進行混淆。最后,但并非無關緊要的是,確保你能夠通過某種機制遠程地消除設備上的數據。像移動設備管理 (MDM)平臺等工具能夠幫助你實現這一功能,但也可以由應用程序本身完成這一點。

        電池使用

        如果你計劃使用輪詢機制或是后臺作業(job),請確保你仔細考慮電池用量的情況。某些操作和網絡功能會很快耗光你的電量,并損害你的用戶體驗。你可以在開始啟動一個耗電量很大的操作之前先檢測電池電量的狀態,以及該設備是否正在充電等等。

        數據的應用

        你或許需要對數據進行查詢與操作(新增、修改、刪除),這取決于你的應用程序的需求。在具有一定復雜性的場景中,使用數據庫作為持久化機制是一個不錯的選擇。要選擇一個合適的數據庫,需要考慮以下一些問題:

        • 對平臺的支持:我能夠在應用的每個版本上都使用這個數據庫嗎?? (iOS、Android、Web、混合應用等等……)
        • 選擇關系型數據庫還是NoSQL數據庫技術
        • 通過ORM的支持,將對象模型方便地映射到數據庫中
        • 數據大小
        • 對于同步協議的支持(例如CouchDB)
        • </ul>

          下面我們將逐個分析一些類庫及數據庫,這對于我們實現離線功能非常實用。

          使用類庫及數據庫

          SQLite

          SQLite 是一個開源的關系型數據庫,非常適合于在移動設備上使用。它使用一個單一的文件用于保存數據,因此對于持久化的管理非常簡單。對于同步及解決沖突來說,它 起不到太大的作用,但對于信息的緩存及隊列操作來說,它是一個簡單易用的選擇。它能夠支持主要的移動平臺,例如iOS、Android、Xamarin和 Windows Phone。

          SQLCypher

          正如上文所說,如果你所緩存或加入隊列中的數據十分敏感,那么在保存數據的同時需要對其加密。 SQLCypher 是一種對SQLite數據庫進行加密的一種十分健壯的選擇。它支持每種主流的移動平臺,但這個類庫是需要付費的。根據安全級別和支持功能的不同,它有多個版本可以提供。

          Couchbase Mobile

          Couchbase最初的名稱是Membase,它是一個開源的分布式NoSQL數據庫。它特別適合用于離線應用的場景,因為它能夠通過 Couchbase Mobile 和一個額外的同步網關對數據進行雙向同步。它支持主流的移動平臺,包括Xamarin和PhoneGap,并且提供了本地文件加密的功能。

          Meteor

          Meteor 是一個用于創建web應用的開源平臺,內置了實時更新的能力。Meteor是基于開源的Node.js平臺和MongoDB所創建的,它提供了一種發布-訂閱機制,能夠將數據的變化實時傳遞給每個連接中的客戶端。

          它通過PhoneGap和Cordova等混合工具支持所有移動平臺。

          結語

          一旦用戶開始期望他們的個人應用能夠實現與企業級應用同等級別的用戶體驗,就無法忽視對離線功能的支持。能夠為用戶提供離線場景的良好支持,將極大地改善移動應用的用戶體驗,對于員工的生產力也是至關重要的。

          請留意在設備上進行數據本地存儲時的安全問題,并且請盡量不要低估你的應用對于用戶的電池電量消耗可能造成的影響。

          關于作者

          為移動應用提供離線支持 Gustavo Machado 是KidoZen的工程部門的副總裁,負責牽頭公司的下一代企業移動平臺的執行。他對于使用不同技術以及敏捷實踐開發高度分布式的系統具有豐富的經驗。他也是一個活躍的 博客 撰寫人,推ter帳號是@machadogj。

          查看英文原文: Mobile Apps Offline Support

          </div> </div> 原文 http://www.infoq.com/cn/articles/mobile-apps-offline-support

           本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
           轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
           本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!