1. 程式人生 > >Android5,6,7,8新特性

Android5,6,7,8新特性

前言

Google每釋出一個Android新版本,都會在官網更新最新的功能,我們通過https://developer.android.google.cn/about/versions/nougat/index.html
檢視每個版本的功能,針對新特性作產品相容。否則App執行在新的版本會出現一系列問題。下面是Android每個版本的功能和行為變更。

Android行為變更

Android官網提供的版本從4.x開始,4.x之前的版本相容做的較少,不做分析,本文主要分析Android5,6,7,8版本變更。

Android 5.0(Lollipop)

Api級別:21

Android Runtime(ART)

大多數Android應用無需任何更改就可以在ART下工作。不過,部分適合Dalvik的技術並不適用於ART。如需立交有關最重要的問題的資訊,請參閱在Android Runtime(ART)上驗證應用行為。如存在一下情況,應特別注意:

  • 你的應用使用Java原生介面(JNI)執行C/C++程式碼
  • 你使用生成非標準程式碼的開發工具(例如,一些程式碼混淆工具)
  • 你使用與壓縮垃圾回收不相容的技術

聲音和震動

如果你當前使用Ringtone、MediaPlayer或Vibrator類向通知中新增聲音和震動,則移除此程式碼,以便系統可以在”優先”模式中正確顯示通知。取而代之的是,使用Notification.Builder方法新增聲音和震動。

將裝置設為RINGER_MODE_SILENT可使裝置進入新的優先模式。如果你將裝置設為RINGER_MOVE_NORMAL或RINGER_MODE_VIBRATE,則裝置將退出優先模式。

以前,Android使用STREAM_MUSIC作為主流式傳輸來控制平板電腦裝置上的音量。在Android 5.0中,手機和平板電腦裝置的主音量模式傳輸現已合併,由STREAM_RING或STREAM_NOTIFICATION進行控制。

鎖定螢幕可見性

預設情況下,在Android 5.0中,通知現在顯示使用者的鎖定螢幕上,使用者可以選擇保護敏感資訊不被公開,再次情況下,系統會自動刪減通知顯示的文字。要自定義此刪減的通知,請使用setPublicVersion()。

如果通知不包含個人資訊,或者你想允許媒體播放控制元件顯示在通知上,則呼叫setVisibility()方法並將通知的可見性級別設為VISIBILITY_PUBLIC 。

浮動通知

現在,當裝置處於活動狀態時(即,裝置未鎖定且其螢幕已開啟),通知可以顯示在小型浮動視窗中(也稱為”浮動通知”)。這些通知看上去類似於精簡版的通知,只是浮動通知還顯示按鈕。使用者可以在不離開當前應用的情況下處理或清除浮動通知。

可能觸發浮動通知的條件示例包括:

  • 使用者的activity處於全屏模式中(應用使用fullScreenIntent)
  • 通知具有較高的優先順序並使用鈴聲或震動

如果你的應用在以上任何情形下實現通知,請確保系統正確顯示浮動通知。

getRecentTasks

為提升使用者隱私的安全性,現已棄用activityManager.getRecentTask()方法。對於向後相容性,此方法仍會返回它的一小部分資料,包括應用自己的任務和可能的一些其他非敏感任務(如首頁)。如果你的應用使用此方法檢索它自己的任務,則改用getAppTasks檢索資訊。

繫結到服務

Context.bindService() 方法現在需要顯式 Intent,如果提供隱式 intent,將引發異常。為確保應用的安全性,請使用顯式 intent 啟動或繫結 Service,且不要為服務宣告 intent 過濾器。

webview

Android 5.0 更改了應用的預設行為。如果您的應用是面向 API 級別 21 或更高級別:預設情況下,系統會阻止混合內容和第三方 Cookie。要允許混合內容和第三方 Cookie,請分別使用 setMixedContentMode() 和 setAcceptThirdPartyCookies() 方法。系統現在可以智慧地選擇要繪製的 HTML 文件部分。這個新的預設行為有助於減少記憶體佔用和提升效能。如果您要一次渲染整個文件,可通過呼叫 enableSlowWholeDocumentDraw() 停用此優化。

如果您的應用是面向低於 21 的 API 級別:系統允許混合內容和第三方 Cookie,並始終一次渲染整個文件。

Android 6.0

API級別:23

執行時許可權

對於以 Android 6.0(API 級別 23)或更高版本為目標平臺的應用,請務必在執行時檢查和請求許可權。要確定您的應用是否已被授予許可權,請呼叫新增的 checkSelfPermission() 方法。要請求許可權,請呼叫新增的 requestPermissions() 方法。即使您的應用並不以 Android 6.0(API 級別 23)為目標平臺,您也應該在新許可權模式下測試您的應用。

取消支援Apache HTTP客戶端

Android 6.0 版移除了對 Apache HTTP 客戶端的支援。如果您的應用使用該客戶端,並以 Android 2.3(API 級別 9)或更高版本為目標平臺,請改用 HttpURLConnection 類。此 API 效率更高,因為它可以通過透明壓縮和響應快取減少網路使用,並可最大限度降低耗電量。要繼續使用 Apache HTTP API,您必須先在 build.gradle 檔案中宣告以下編譯時依賴項:

android {useLibrary 'org.apache.http.legacy'}

BoringSSL

Android 正在從使用 OpenSSL 庫轉向使用 BoringSSL 庫。如果您要在應用中使用 Android NDK,請勿連結到並非 NDK API 組成部分的加密庫,如 libcrypto.so 和 libssl.so。這些庫並非公共 API,可能會在不同版本和裝置上毫無徵兆地發生變化或出現故障。此外,您還可能讓自己暴露在安全漏洞的風險之下。請改為修改原生程式碼,以通過 JNI 呼叫 Java 加密 API,或靜態連結到您選擇的加密庫。

通知

此版本移除了 Notification.setLatestEventInfo() 方法。請改用 Notification.Builder 類來構建通知。要重複更新通知,請重複使用 Notification.Builder 例項。呼叫 build() 方法可獲取更新後的 Notification 例項。

adb shell dumpsys notification 命令不再列印輸出您的通知文字。請改用 adb shell dumpsys notification –noredact 命令列印輸出 notification 物件中的文字。

音訊管理器變更

不再支援通過 AudioManager 類直接設定音量或將特定音訊流靜音。setStreamSolo() 方法已棄用,您應該改為呼叫 requestAudioFocus() 方法。類似地,setStreamMute() 方法也已棄用,請改為呼叫 adjustStreamVolume() 方法並傳入方向值 ADJUST_MUTE 或 ADJUST_UNMUTE。

相機服務變更

在此版本中,相機服務中共享資源的訪問模式已從之前的“先到先得”訪問模式更改為高優先順序程序優先的訪問模式。對服務行為的變更包括:

  • 根據客戶端應用程序的“優先順序”授予對相機子系統資源的訪問權,包括開啟和配置相機裝置。帶有對使用者可見 Activity 或前臺Activity 的應用程序一般會被授予較高的優先順序,從而使相機資源的獲取和使用更加可靠;
  • 當高優先順序的應用嘗試使用相機時,系統可能會“驅逐”正在使用相機客戶端的低優先順序應用。在已棄用的 Camera API 中,這會導致系統為被驅逐的客戶端呼叫 onError()。在 Camera2 API 中,這會導致系統為被驅逐的客戶端呼叫onDisconnected();
  • 在配備相應相機硬體的裝置上,不同的應用程序可同時獨立開啟和使用不同的相機裝置。但現在,如果在多程序用例中同時訪問相機會造成任何開啟的相機裝置的效能或能力嚴重下降,相機服務會檢測到這種情況並禁止同時訪問。即使並沒有其他應用直接嘗試訪問同一相機裝置,此變更也可能導致低優先順序客戶端被“驅逐”。
  • 更改當前使用者會導致之前使用者帳戶擁有的應用內活動相機客戶端被驅逐。對相機的訪問僅限於訪問當前裝置使用者擁有的使用者個人資料。舉例來說,這意味著,當用戶切換到其他帳戶後,“來賓”帳戶實際上無法讓使用相機子系統的程序保持執行狀態

Android 7.0

API級別:24

電池和記憶體

Android 7.0 包括旨在延長裝置電池壽命和減少 RAM 使用的系統行為變更。這些變更可能會影響您的應用訪問系統資源,以及您的應用通過特定隱式 intent 與其他應用互動的方式。

Project Svelte:後臺優化

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

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

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

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

  • 面向 Android 7.0 開發的應用不會收到 CONNECTIVITY_ACTION 廣播,即使它們已有清單條目來請求接受這些事件的通知。在前臺執行的應用如果使用 BroadcastReceiver 請求接收通知,則仍可以在主執行緒中偵聽 CONNECTIVITY_CHANGE。
  • 應用無法傳送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 廣播。此項優化會影響所有應用,而不僅僅是面向 Android 7.0 的應用。

的應用使用任何 intent,您仍需要儘快移除它們的依賴關係,以正確適配 Android 7.0 裝置。Android 框架提供多個解決方案來緩解對這些隱式廣播的需求。例如,JobScheduler API 提供了一個穩健可靠的機制來安排滿足指定條件(例如連入無限流量網路)時所執行的網路操作。您甚至可以使用 JobScheduler 來適應內容提供程式變化。

系統許可權更改

為了提高私有檔案的安全性,面向 Android 7.0 或更高版本的應用私有目錄被限制訪問 (0700)。此設定可防止私有檔案的元資料洩漏,如它們的大小或存在性。此許可權更改有多重副作用:

  • 私有檔案的檔案許可權不應再由所有者放寬,為使用 MODE_WORLD_READABLE 和/或 MODE_WORLD_WRITEABLE 而進行的此類嘗試將觸發 SecurityException。
    注:迄今為止,這種限制尚不能完全執行。應用仍可能使用原生 API 或 File API 來修改它們的私有目錄許可權。但是,我們強烈反對放寬私有目錄的許可權。
  • 傳遞軟體包網域外的 file:// URI 可能給接收器留下無法訪問的路徑。因此,嘗試傳遞 file:// URI 會觸發 FileUriExposedException。分享私有檔案內容的推薦方法是使用 FileProvider。
  • DownloadManager 不再按檔名分享私人儲存的檔案。舊版應用在訪問 COLUMN_LOCAL_FILENAME 時可能出現無法訪問的路徑。面向 Android 7.0 或更高版本的應用在嘗試訪問 COLUMN_LOCAL_FILENAME 時會觸發 SecurityException。通過使用DownloadManager.Request.setDestinationInExternalFilesDir() 或DownloadManager.Request.setDestinationInExternalPublicDir() 將下載位置設定為公共位置的舊版應用仍可以訪問 COLUMN_LOCAL_FILENAME 中的路徑,但是我們強烈反對使用這種方法。對於由 DownloadManager 公開的檔案,首選的訪問方式是使用ContentResolver.openFileDescriptor() 。

在應用件共享檔案

對於面向 Android 7.0 的應用,Android 框架執行的 StrictMode API 政策禁止在您的應用外部公開 file:// URI。如果一項包含檔案 URI 的 intent 離開您的應用,則應用出現故障,並出現 FileUriExposedException 異常。

要在應用間共享檔案,您應傳送一項 content:// URI,並授予 URI 臨時訪問許可權。進行此授權的最簡單方式是使用 FileProvider 類。

螢幕縮放

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

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

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

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

  • 在螢幕寬度為 sw320dp 的裝置上測試您的應用,並確保其充分執行。
  • 當裝置配置發生變更時,更新任何與密度相關的快取資訊,例如快取點陣圖或從網路載入的資源。當應用從暫停狀態恢復執行時,檢查配置變更。
    注:如果您要快取與配置相關的資料,則最好也包括相關元資料,例如該資料對應的螢幕尺寸或畫素密度。儲存這些元資料便於您在配置變更後決定是否需要重新整理快取資料。
  • 避免用畫素單位指定尺寸,因為畫素不會隨螢幕密度縮放。應改為使用與密度無關畫素 (dp) 單位指定尺寸。

檢查你的應用是否使用私有庫

為幫助您識別載入私有庫的問題,logcat 可能會生成一個警告或執行時錯誤。例如,如果您的應用面向 API 級別 23 或更低級別,並在執行 Android 7.0 的裝置上嘗試訪問私有庫,您可能會看到一個類似於下面所示的警告:

library "libandroid_runtime.so"("/system/lib/libandroid_runtime.so") needed   
or dlopened by "/data/app/com.popular-app.android-2/lib/arm/libapplib.so"   
is not accessible for the namespace "classloader-namespace" - the access  
is temporarily granted as a workaround for http://b/26394120  

這些 logcat 警告通知您哪個庫正在嘗試訪問私有平臺 API,但不會導致您的應用崩潰。但是,如果應用面向 API 級別 24 或更高級別,logcat 會生成以下執行時錯誤,您的應用可能會

java.lang.UnsatisfiedLinkError: dlopen failed:   
library "libcutils.so"("/system/lib/libcutils.so") needed or dlopened  
by"/system/lib/libnativeloader.so" is not accessible for the   
namespace "classloader-namespace"
at java.lang.Runtime.loadLibrary0(Runtime.java:977)
at java.lang.System.loadLibrary(System.java:1602)  

如果您的應用使用動態連結到私有平臺 API 的第三方庫,您可能也會看到上述 logcat 輸出。利用 Android 7.0DK 中的 readelf 工具,您可以通過執行以下命令生成給定 .so 檔案的所有動態連結的共享庫列表:

aarch64-linux-android-readelf -dW libMyLibrary.so

其他重要說明

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

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

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

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

  • 由於之前的 Android 版本中的一項錯誤,系統未能將對主執行緒上的一個 TCP 套接字的寫入操作舉報為違反嚴格模式。Android 7.0 修復了此錯誤。呈現出這種行為的應用現在會引發 android.os.NetworkOnMainThreadException 。一般情況下,我們不建議在主執行緒上執行網路操作,因為這些操作通常會出現可能導致 ANR 和卡頓的高尾延遲。
  • Debug.startMethodTracing() 方法系列現在預設在您的共享儲存空間上的軟體包特定目錄中儲存輸出,而非 SD 卡根目錄。這意味著應用不再需要請求 WRITE_EXTERNAL_STORAGE 許可權來使用這些 API 。
  • 許多平臺 API 現在開始檢查在 Binder 事務間傳送的大負載,系統現在會將 TransactionTooLargeExceptions 作為 RuntimeExceptions 再次引發,而不再只是默默記錄或抑制它們。一個常見例子是在 Activity.onSaveInstanceState() 上儲存過多資料,導致 ActivityThread.StopInfo 在您的應用面向 Android 7.0 時引發 RuntimeException。
  • 如果應用向 View 釋出 Runnable 任務,並且 View 未附加到視窗,系統會用 View 為 Runnable 任務排隊;在 View 附加到視窗之前,不會執行 Runnable 任務。此行為會修復以下錯誤:

    如果一項應用是從並非預期視窗 UI 執行緒的其他執行緒釋出到 View,則 Runnable 可能會因此執行錯誤的執行緒。

    如果 Runnable 任務是從並非環路執行緒的其他執行緒釋出,則應用可能會曝光 Runnable 任務。

  • 如果 Android 7.0 上一項有 DELETE_PACKAGES 許可權的應用嘗試刪除一個軟體包,但另一項應用已經安裝了這個軟體包,則系統需要使用者進行確認。在這種情況下,應用在呼叫 PackageInstaller.uninstall() 時預計的返回狀態應為 STATUS_PENDING_USER_ACTION 。

  • 名為 Crypto 的 JCA 提供程式已棄用,因為它僅有的 SHA1PRNG 演算法為弱加密。應用無法再使用 SHA1PRNG(不安全地)派生金鑰,因為不再提供此提供程式。

Android 8.0(概念)

API級別:24

合併Chrome OS

據傳,谷歌或可合併Android與Chrome OS以使平臺更加統一。

多視窗模式

多視窗模式能夠充分利用大屏手機、平板的螢幕空間。

OpenJDK替換Java API

Android不再使用Java API是因為官司敗訴過。OpenJDK能夠更簡單地建立通用程式碼,從而改善Android的開發環境。

3D Touch功能

實際上國產華為已經有相關產品預先支援3D
Touch功能了,而三星也將會提供相應的支援。

獨立升級

如果真的可以實現的話,使用者就可以直接通過谷歌進行升級,完全避開第三方的限制,相信這是使用者及其渴望的。無需等待,可從官方直升最新版,但是怎樣解決相容等問題是急需解決的問題。