1. 程式人生 > >Android N Preview 行為變更

Android N Preview 行為變更


Android N 除了提供諸多新特性和功能外,還對系統和 API 行為做出了各種變更。本文重點介紹您應該瞭解並在開發應用時加以考慮的一些重要變更。

如果您之前釋出過 Android 應用,請注意您的應用可能受到這些平臺變更的影響。

效能提升

為延長裝置的電池壽命、降低記憶體使用率以及提升應用效能,Android N 對系統行為做出了一些變更。這些變更可能會影響系統資源和系統通知對應用的可用性。您應仔細檢查這些變更並評估應用可能需要做何調整以適應這些變更。

打盹

Android 6.0(API 級別 23)引入了打盹模式,當用戶裝置未插接電源、處於靜止狀態且螢幕關閉時,該模式會推遲 CPU 和網路活動,從而延長電池壽命。而 Android N 則通過在裝置未插接電源且螢幕關閉狀態下、但不一定要處於靜止狀態(例如使用者外出時把手持式裝置裝在口袋裡)時應用部分 CPU 和網路限制,進一步增強了打盹模式。


圖 1. 打盹模式如何應用第一級系統活動限制以延長電池壽命的圖示。

當裝置處於充電狀態且螢幕已關閉一定時間後,裝置會進入打盹模式並應用第一部分限制:關閉應用網路訪問、推遲作業和同步。如果進入打盹模式後設備處於靜止狀態達到一定時間,系統則會對 、 鬧鈴、GPS 和 Wi-Fi 掃描應用餘下的打盹限制。無論是應用部分還是全部打盹限制,系統都會喚醒裝置以提供簡短的維護時間視窗,在此視窗期間,應用程式可以訪問網路並執行任何被推遲的作業/同步。


圖 2. 打盹模式如何在裝置處於靜止狀態達到一定時間後應用第二級系統活動限制的圖示。

請注意,啟用螢幕或插接裝置電源時,系統將退出打盹模式並取消這些處理限制。此項新增的行為不會影響有關使您的應用適應 Android 6.0(API 級別 23)中所推出的舊版本打盹模式的建議和最佳實踐,如

打盹和應用待機優化中所討論。您仍應遵循這些建議(例如使用 Google Cloud Messaging (GCM) 傳送和接收訊息)並開始安排更新計劃以適應新增的打盹行為。

Project Svelte:後臺優化

Android N 刪除了三項隱式廣播,以幫助優化記憶體使用和電量消耗。此項變更很有必要,因為隱式廣播會在後臺頻繁啟動已註冊偵聽這些廣播的應用。刪除這些廣播可以顯著提升裝置效能和使用者體驗。

移動裝置會經歷頻繁的連線變更,例如在 Wi-Fi 和移動資料之間切換時。目前,可以通過在應用清單檔案中註冊一個接收器來偵聽隱式 廣播,讓應用能夠監控這些變更。由於很多應用會註冊接收此廣播,因此單次網路切換即會導致所有應用被喚醒並同時處理此廣播。

同理,應用可以註冊接收來自其他應用(例如相機)的隱式  和  廣播。當用戶使用相機應用拍攝照片時,這些應用即會被喚醒以處理廣播。

為減緩這些問題,Android N 應用了以下優化措施:

  • 面向 Android N 開發的應用不會收到  廣播,即使它們已有清單條目來請求接受這些事件的通知。在前臺執行的應用如果使用 請求接收通知,則仍可以在主執行緒中偵聽 CONNECTIVITY_CHANGE

未來的 Android 版本還可能會棄用其他隱式廣播以及未繫結的後臺服務。有鑑於此,您應避免依賴在清單檔案中宣告的接收器來偵聽隱式廣播或刪除此依賴關係,以及避免或刪除對後臺服務的依賴關係。

Android 框架提供多種解決方案來降低這些隱式廣播或後臺服務的必要性。例如, API 提供了一個穩健可靠的機制來安排滿足指定條件(例如連入不按流量計費的網路)時所執行的網路操作。您甚至可以使用  來響應內容提供程式所發生的變更。

如需瞭解有關此行為變更及如何改寫應用的詳細資訊,請參閱後臺優化

許可權更改

Android N 做了一些許可權更改,包括使用者帳戶許可權和向外部儲存裝置寫入資訊的新許可權,這些更改可能會影響您的應用。下面概要列出了預覽版中已發生更改的許可權。

  • GET_ACCOUNTS(已棄用)

    GET_ACCOUNTS 許可權現已棄用。對於面向 Android N 的應用,系統將忽略此許可權。

輔助工具改進

為提高平臺對於視力不佳或視力受損使用者的可用性,Android N 做出了一些更改。這些更改一般並不要求更改您的應用程式碼,不過您應仔細檢查並使用您的應用測試這些功能,以評估它們對使用者體驗的潛在影響。

螢幕縮放

Android N 支援使用者設定顯示尺寸,以放大或縮小螢幕上的所有元素,從而提升裝置對視力不佳使用者的可訪問性。使用者無法將螢幕縮放至低於最小螢幕寬度 sw320dp,該寬度是 Nexus 4 的寬度,也是常規中等大小手機的寬度。

圖 3. 右側螢幕顯示的是一臺執行 Android N 系統映像的裝置增大顯示尺寸後的效果。

當裝置密度發生更改時,系統會以如下方式通知正在執行的應用:

  • 如果是面向 API 級別 23 或更低版本系統的應用,則系統會自動終止其所有後臺程序。這意味著如果使用者切換離開此類應用,轉而開啟 Settings 螢幕並更改 Display size 設定,則系統會像處理記憶體不足的情況一樣終止該應用。如果應用具有任何前臺程序,則系統會如處理執行時變更中所述將配置變更通知給這些程序,就像對待裝置螢幕方向變更一樣。
  • 如果是面向 Android N 的應用,則其所有程序(前臺和後臺)都會收到有關配置變更的通知,如處理執行時變更中所述。

大多數應用並不需要進行任何更改即可支援此功能,不過前提是這些應用遵循 Android 最佳實踐。具體要檢查的事項:

  • 在螢幕寬度為  的裝置上測試您的應用,並確保其充分執行。
  • 當裝置配置發生變更時,更新任何與密度相關的快取資訊,例如快取點陣圖或從網路載入的資源。當應用從暫停狀態恢復執行時,檢查配置變更。

    注:如果您要快取與配置相關的資料,則最好也包括相關元資料,例如該資料對應的螢幕尺寸或畫素密度。儲存這些元資料便於您在配置變更後決定是否需要重新整理快取資料。

  • 避免用畫素單位指定尺寸,因為畫素不會隨螢幕密度縮放。應改為使用與密度無關畫素 (dp) 單位指定尺寸。

設定嚮導中的視覺設定

Android N 在“Welcome”螢幕中加入了“Vision Settings”,使用者可以在新裝置上設定以下輔助工具設定:Magnification gestureFont sizeDisplay size 和 TalkBack。此項變更增強了與不同螢幕設定相關的錯誤的可見性。要評估此功能的影響,您應在啟用這些設定的狀態下測試應用。您可以在 Settings > Accessibility 中找到這些設定。

NDK 應用連結至平臺庫

Android N 做了一些名稱空間更改,以阻止載入非公開 API。如果您使用 NDK,則只能使用 Android 平臺提供的公開 API。在下一個官方釋出的 Android 版本上使用非公開 API 會導致應用崩潰。

為提醒您使用了非公開 API,在 Android N 裝置上執行的應用會在有應用呼叫非公開 API 時在日誌訊息輸出中生成一個錯誤。此錯誤還會作為訊息顯示在裝置螢幕上,以幫助增強您對此情況的認識。您應檢查應用程式碼以刪除使用非公開平臺 API,並使用預覽版裝置或模擬器全面測試應用。

如果您的應用依賴平臺庫,則請參見 NDK 文件,瞭解使用公開 API 等效項替換普通私有 API 的典型修復。您還可以連結至平臺庫,而無需實現此應用,如果應用使用的庫是平臺的一部分(例如 libpng),但不屬於 NDK,則更可如此。此情況下,請確保您的 APK 包含您打算連結到的所有 .so 檔案。

注意:有些第三方庫可能會連結至非公開 API。如果您的應用使用這些庫,那麼當您的應用在下一個官方釋出的 Android 版本上執行時可能會出現崩潰現象。

應用不應依賴或使用不屬於 NDK 的原生庫,因為這些庫可能會發生更改或從一個 Android 版本遷移至另一版本。例如,從 OpenSSL 切換至 BoringSSL 即屬於此類更改。此外,不同的裝置可能提供不同級別的相容性,因為不屬於 NDK 中的平臺庫沒有相容性要求。如果您必須在較舊裝置上訪問非 NDK 庫,則請依據 Android API 級別進行載入。

為幫助您診斷此類問題,下面列舉了一些在您試圖使用 Android N 開發應用時可能遇到的 Java 和 NDK 錯誤:

Java 錯誤示例:

java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/lib/libcutils.so"
    is not accessible for the namespace "classloader-namespace"

NDK 錯誤示例:

dlopen failed: cannot locate symbol "__system_property_get" referenced by ...

以下是遇到這類錯誤的應用的一些典型修復:

  • 可以使用標準 JNI 函式來替代使用 libandroid_runtime.so 中的 getJavaVM 和 getJNIEnv:
    AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h>
    AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
    JavaVM::AttachCurrentThread from <jni.h>.
    
  • 可以使用公開備選項 __system_property_get 來替代使用 libcutils.so 中的 property_get 符號。如需這樣做,請使用 __system_property_get及以下 include 函式:
    <span class="com">#include</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(136, 0, 0);"><sys/system_properties.h></span>
  • 應使用應用本地版本來替代使用 libcrypto.so 中的 SSL_ctrl 符號。例如,您應在 .so 檔案中靜態連結 libcyrpto.a,或者在應用中包含您自己的來自 BoringSSL 或 OpenSSL 的動態 libcrypto.so

Android for Work

Android N 包含一些針對面向 Android for Work 的應用的變更,包括對證書安裝、密碼重置、二級使用者管理、裝置識別符號訪問許可權的變更。如果您是要針對 Android for Work 環境開發應用,則應仔細檢查這些變更並相應地修改您的應用。

  • 您必須先安裝授權證書安裝程式,然後 DPC 才能對其進行設定。對於面向 N SDK 的配置檔案和裝置所有者應用,您應在裝置策略控制器 (DPC) 呼叫DevicePolicyManager.setCertInstallerPackage() 之前安裝授權證書安裝程式。如果尚未安裝此安裝程式,則系統會引發IllegalArgumentException
  • 針對裝置管理員的重置密碼限制現在也適用於配置檔案所有者。裝置管理員無法再使用 DevicePolicyManager.resetPassword() 來清除或更改已經設定的密碼。不過,裝置管理員仍可以設定密碼,但只能在裝置沒有密碼、PIN 或圖案時這樣做。
  • 即使設定了限制,裝置所有者和配置檔案所有者仍可以管理帳戶。而且,即使具有 DISALLOW_MODIFY_ACCOUNTS 使用者限制,裝置所有者和配置檔案所有者仍可呼叫 Account Management API。
  • 裝置所有者可以更輕鬆地管理二級使用者。當裝置在裝置所有者模式下執行時,系統將自動設定 DISALLOW_ADD_USER 限制。這樣可以防止使用者建立非託管二級使用者。此外,CreateUser() 和 createAndInitial() 方法已棄用,取而代之的是 DevicePolicyManager.createAndManageUser() 方法。
  • 裝置所有者可以訪問裝置識別符號。裝置所有者可以使用 DevicePolicyManagewr.getWifiMacAddress() 訪問裝置的 Wi-Fi MAC 地址。如果裝置上從未啟用 Wi-Fi,則此方法將返回一個 null 值。

如需瞭解有關 Android N 中針對 Android for Work 所做變更的詳細資訊,請參閱 Android for Work 更新

其他重要說明

  • 如果一個應用在 Android N 上執行,但卻是針對更低 API 級別開發的,那麼在使用者更改顯示尺寸時,系統將終止此應用程序。因此,應用必須能夠正常處理此情景。否則,當用戶從最近使用記錄中恢復執行應用時,應用將會出現崩潰現象。

    您應測試應用以確保不會發生此行為。要進行此測試,您可以通過 DDMS 手動終止應用,以造成相同的崩潰現象。

    在密度發生更改時,系統不會自動終止面向 N 及更高版本的應用;不過,這些應用仍可能對配置變更做出不良響應。

  • Android N 上的應用應能夠正常處理配置變更,並且在後續啟動時不會出現崩潰現象。您可以通過更改字型大小 (Setting > Display > Font size) 並隨後從最近使用記錄中恢復執行應用,來驗證應用行為。