前言html
本文翻譯自Android開發者官網的一篇文檔,主要用於介紹關於無縫性設計相關的一些要點。android
中國版官網原文地址爲:https://developer.android.google.cn/guide/practices/app-design/seamlessness。數據庫
路徑爲:Android Developers > Docs > 指南 > Best practies > Performance > Designing for seamlessness安全
正文網絡
即使您的應用是快速並且響應的,可是某些設計決策仍然可能給用戶帶來問題——由於和其它應用或對話框的非計劃內的交互,無心的數據丟失,不期的阻塞,等。爲了不這些問題,它幫助理解應用運行的上下文和能夠影響到應用的系統交互。簡而言之,您應該努力開發一款與系統和其它應用無縫交互的應用。app
一個常見的無縫問題是,當應用的後臺進程——例如,服務或者廣播接收者——彈出對話框來響應某事件時。這視乎是無害的行爲,尤爲是當在模擬器上單首創建及測試應用時。可是,當您的應用在真機上運行的時候,在您的後臺進程顯示對話框時,您的應用可能不會擁有用戶焦點。這可能最終變成您的應用在活動的應用後面顯示對話框,或者可能從當前應用獲取焦點,而且在用戶正在進行的任何操做前顯示對話框(例如撥打電話)。那種行爲對您的應用或用戶都不起做用。less
爲了不這些問題,您的應用應該使用合適的系統特點來通知用戶——【Notification】類。經過使用通知,當事件發生時您的應用能夠示意用戶,在狀態欄上顯示一個圖標而不是搶佔焦點並打擾用戶。ide
另一個無縫性問題的例子是,當activity由於沒有正確實現onPause()方法以及其它生命週期方法而無心間丟失狀態或者用戶數據時。或者,若是您的應用暴露數據來給其它應用使用,您應該經過ContentProvider來暴露,而不是(舉個例子)經過全世界都能讀的原始文件或數據庫來這樣作。組件化
這些例子有一個共同點是,它們涉及到系統和其它應用良好地協做。Android系統被設計爲將應用視爲一種鬆耦合組件的組合,而不是大塊的黑盒子代碼。這容許您做爲一個開發者將整個系統視爲一個這些組件的更大組合。這經過容許您清晰並沒有縫地集成其它應用來讓您受益,而且這樣的話您應該設計您本身的代碼來反饋這個恩惠。佈局
本文將討論常見的無縫性問題以及如何避免它們。
不要丟棄數據
請時刻謹記,Android是一個移動平臺。這提及來很明顯,可是更要的是記住其它Activity(好比「電話來了」應用)能夠在任什麼時候刻彈出來覆蓋在您本身的Activity上。這將激發onSaveInstanceState()方法和onPause()方法,而且頗有可能會致使您的應用被殺死。
若是當其它Activity出現時,用戶正在您的應用中編輯數據,當您的應用被殺死時將頗有可能丟失那些數據。固然,除非首先保存正在進行的工做。「Android方式」的作法是:接收或者編輯輸入的Android應用應該重寫onSaveInstanceState()方法而且以適當的方式保存它們的狀態。當用戶從新訪問您的應用時,她應該可以取回她的數據。
一個典型的這種行爲的良好使用示例是郵件應用。若是當另一個應用啓動時,用戶正在撰寫郵件,該應用應該將這封正在進行的郵件做爲草稿保存。
不要暴露原始數據
若是您不會穿着內衣在街上走,那麼您的數據也不該該。由於這有可能暴露某些類型的應用讓全世界讀取,這一般不是最好的主意。暴露原始的數據須要其它應用來理解您的數據格式;若是您改變那個格式,您將破壞其它沒有進行相似更新的應用。
「Android方式」是建立一個ContentProvider經過清晰、穩當的、可維護的API來將數據暴露給其它應用。使用ContentProvider很是像插入一個Java語言接口來分開並組件化兩個緊耦合的代碼片斷。這意味着您將能夠修改您的內部數據格式,而不用改變ContentProvider暴露的接口,而且這不會影響其它應用。
不要打擾用戶
若是用戶正在運行一個應用(好比正在通話時使用電話應用),那麼這是一個很是安全的賭注,他是故意這樣作的。那就是爲何除了直接響應來自當前Activity的用戶輸入以外,您應該避免生成activity。
也就是說,不要從正在後臺運行的BroadcastReceiver或者Service調用startActivity()。這樣作將中斷當前應用正在運行的工做,而且致使吵到用戶。可能更嚴重的是,您的Activity可能變成一個「按鍵強盜」而且收到一些用戶正在提供給前一個Activity的輸入信息。根據您的應用的所做所爲,這多是一個壞消息。
您應該使用NotificationManager來設置通知,而不是從後臺生成Activity用戶界面。這些將會出如今狀態欄,而且用戶能夠在空閒的時候點擊它們,來看看您的應用給他們顯示了什麼。
(請注意,全部的這些不適用於您本身的Activity已經在前臺的場景:在那些場景中,用戶但願看到您下一個Activity來響應輸入事件。)
有不少事情要作?在線程中完成吧
若是您的應用須要執行一些昂貴或者長時間運行的計算,您可能應該把它們移動到一個線程中。這將阻止可怕的「應用未響應」對話框顯示給用戶,最終的結果是您的應用火爆地終止了。
默認狀況下,Activity中的全部代碼以及它的全部視圖都運行在相同的線程中。這也是處理UI事件的同一個線程。例如,當用戶按了一個按鍵,按鍵按下事件就被添加到該Activity的主線程隊列中。事件處理系統須要從隊列中取出事件並快速處理它們;若是沒有,幾秒鐘後系統會判定該應用已經被掛起而且爲用戶殺死它。
若是您有長時間運行的代碼,那麼在Activity中內聯運行它將會在事件處理線程中運行,從而有效地阻塞事件處理。這將延遲輸入處理,並致使ANR對話框。爲了不這種現象,將計算移動到子線程中。【爲響應而設計】文檔中會討論如何作。
不要過分加載一個單獨的activity屏幕
全部值得使用的應用可能有多個不一樣的屏幕。當爲您的UI設計屏幕時,確保使用多個Activity對象實例。
根據您開發的背景,您可能解釋Activity爲相似於Java Applet的東西,由於它是您應用的入口點。可是,那並不徹底正確:Applet子類是Java Applet惟一的入口點,可是Activity應該被認爲是可能的進入應用的幾個入口點之一。您「main」Activity和任何其它Activity之間您可能擁有的惟一差異是,「main」Activity碰巧是惟一一個對AndroidManifest.xml文件中的「android.intent.action.MAIN」行動表達過興趣的Activity。
因此,當設計應用時,將應用當作是Activity對象的組合。從長遠看,這將會讓您的代碼更加具備可維護性,而且做爲一個很好的反作用,它與Android的應用歷史以及「回退棧」模式配合得很是好。
繼承系統主題
當涉及到用戶接口的外觀和感受時,重要的是將它們很好地融合在一塊兒。用戶被那些與他們所指望的用戶接口大相徑庭的應用弄得很煩躁。當設計您的UI時,您應該儘量嘗試避免滾動您的界面。相反,使用主題。您能夠重寫或者繼承那些您須要的主題部分,但至少您正在從和其餘應用相同的UI基礎啓動。更多詳情,請查閱【類型和主題】。
設計您的UI來適配多屏幕分辨率
不一樣的Android驅動設備將支持不一樣的屏幕分辨率。有一些將甚至可能在運行中改變分辨率,好比經過切換到橫屏模式。重要的是確保您的佈局和圖片在不一樣的設備屏幕上足夠靈活,以正確顯示。
幸運的是,這很是容易實現。簡單來講,您必需要作的是爲主要分辨率提供不一樣的圖片版本(若是您使用任何一個),而且設計您的佈局來適配不一樣的尺寸。(例如,避免使用硬編碼位置而且使用相對佈局。)若是您作了不少,系統會處理剩下的,而且您的應用在任何設備上都看起來很不錯。
假設網速慢
Android設備將會提供各類不一樣的網絡鏈接選項。全部的這些選項將擁有一些數據訪問規定,雖然有些將會比其它的快。但是,最小的公分母是GPRA,這是一種用於GSM網絡的非3G數據服務。即便是支持3G的設備也將花費不少時間在非3G網絡上,因此在將來很長一段時間緩慢的網絡將仍然是一個事實。
那就是爲何您應該老是編寫您的應用來最小化網絡訪問和帶寬。您不能假設網絡是很快的,因此您應該老是爲網速變慢作好計劃。若是您的用戶碰巧在更快的網絡,那是很棒的——他們的用戶體驗將只會提高。不過,您但願避免相反的狀況:基於任何給定的時刻用戶所在的位置,部分時間可使用,但剩餘時間卻很是慢的應用,多是不受歡迎的。
這裏有一個潛在的問題是,若是您正在使用模擬器,將很容易掉進這個陷阱,由於模擬器使用的是您的桌面電腦網絡鏈接。那幾乎能夠確信比蜂窩網絡快不少,因此您將須要更改模擬器上用來模擬更慢的網絡速度的設置。當啓動模擬器時,您能夠在AndroidStudio中經過AVD Manager或者經過【命令行選項】來作這件事。
不要假設觸摸屏或者鍵盤
Android將會支持多種遙控器形式的因素。那是一種很奇特的說法,某些Android設備將擁有完整的「QWERTY」的鍵盤,而後其餘的設備將擁有40按鍵,12按鍵,或者甚至其它按鍵配置。類似地,有些設備將擁有觸摸屏,可是不少卻沒有。
當構建您的應用時,請記住那些。不用假設特別的鍵盤佈局——固然,除非您確實熱衷於限制您的應用以致於讓它只能在那些設備上使用。
節省設備電池
若是常常被插到牆裏,那麼移動設備就不那麼移動了。移動設備是電池驅動的,而且讓電池一次充電後延續的時間越長,全部人就越開心——尤爲是用戶。電池電量的兩個最大消費者是處理器和無線通訊;那就是爲何儘量編寫您的應用來作儘量少的工做,而且儘量少地使用網絡是很重要的。
最小化您應用使用的處理器時間實際上來源於【編寫高效的代碼】。爲了最小化來自使用無線電通訊的電量流失,請確保優雅地處理錯誤條件,而且只取您所須要的。例如,若是一次失敗了,不要常常重試網絡操做。若是它失敗了一次,極有多是由於用戶沒有接收信號,因此若是立刻嘗試,可能將要再次失敗;全部您將作的都是浪費電量。
用戶時很是明智的:若是您的程序是很是耗電的,您能夠期望他們注意到。在那個點上,您惟一能確信的事情是,您的程序安裝時間將不會很長了。
結語
本文最大限度保持原文的意思,因爲筆者水平有限,如有翻譯不許確或不穩當的地方,請指正,謝謝!