Android O新特性和行為變更總結
1. Android O 新特性
前段時間解決了幾個 QQ 音樂多視窗螢幕顯示的 bug,雖然這個問題最終不是 Android O 版本的問題,多視窗是 Android 7.1 之後引入的(關於多視窗適配需要注意的地方,可以看看這篇文章:Android Multi-Window詳細介紹),但是趁此機會了解一下 Android O 版本的新特性也不錯,而且 Google IO 大會剛剛過去,趁這個熱度介紹一下。
在大會上介紹到的 Android O 新版本更新和優化主要集中在兩個方面:Fluid Experiences 和 Vitals,Fluid Experience 主要包含了四個顯著特性:Notification Dots, Picture In Picture, Autofill Framework 和 Smart Text Selection;
1.1 通知變更
Android O 版本重新設計了通知,讓通知的管理更加方便,首先引入了通知渠道用來讓使用者統一管理通知,當 targetApi 設定為 O 版本時,必須要實現一個或多個通知渠道,如果設定為 O 版本之前的版本,在 O 版本裝置上的行為則和 7.x 版本保持一致。通知渠道提供了一種將應用內的通知變成一個個易於管理組的方法,通知渠道建立並提交到 notification manager 後,便無法通過程式設計方式修改通知渠道的行為,這些設定之後則由使用者掌控。使用者現在可以使用一致的系統 UI 管理大多數與通知有關的設定。所有釋出至同一通知渠道的通知都具有相同的行為。當用戶長摁通知或者通過設定去到通知的設定頁面的時候,可以看到這些介面:
通過這個設定頁面可以看到,使用者可以將應用所有的通知渠道關閉,或者關閉某一個單獨的通知渠道,每一個通知渠道也有相應的行為,使用者可以去自行修改,比如修改通知渠道的優先順序,如果支援的話,使用者還可以去宣告通知是否同時顯示為應用的角標。Android O 還引入了通知角標,當一個應用的通知沒有 dismiss 的時候,會在應用的圖示上面顯示一個角標,長摁這個應用的圖示,也會顯示通知的詳情資訊:
O 版本棄用了對單個通知設定優先順序的功能,現在是對通知渠道設定優先順序,該通知渠道的所有通知都適用於該優先順序,優先順序從 IMPORTANCE_NONE(0) 至 IMPORTANCE_HIGH(4)
同時還引入了一個通知睡眠的功能,使用者可以休眠一個通知,讓它在指定的時候再出現,被休眠的時候仍然可以修改這個通知的設定,但是不會讓這個通知立馬出現。另外還可以設定一個通知的超時時間,用來讓某個通知在一段時間之後被自動 cancel。其他的比如可以獲取通知的清除方式,修改通知的背景顏色,修改通知的樣式可以看官方文件:Android O-通知。
使用場景:針對應用的不同優先級別的通知設定不同的通知渠道,強提醒可以發出聲音加震動,弱提醒可能僅僅只需要呼吸燈和角標這樣等,這樣可以最大程度減少對使用者的干擾。
1.2 畫中畫模式
在 Android O 之前,畫中畫模式已經可用於 Android TV,而 Android O 則讓這一個功能可以支援到其他的 Android 裝置,當某個 Activity 處於 PIP 模式時,它會回撥生命週期的 onPause 方法,所以此時在 PIP 模式下比如視訊播放等操作就不能夠在 onPause 裡面暫停,而應該在 onStop 裡面,這一點和多視窗模式一樣,來看看它的效果:
我們可以看到在當從 youtube 視訊切換出去之後會回到桌面,這時候會有一個視訊播放的視窗懸浮在所有的應用之上,這個小視窗在播放視訊,而此時點選這個小視窗區域會彈出幾個操作按鈕,可以選擇關閉,或者是重新開啟 youtube 視訊播放頁,而且底部的幾個按鈕也是可以自定義的,非常方便。
這裡需要提到的一點是,升級到 8.0 的系統後不是立馬會啟用這個功能,啟用這個功能可能會有點複雜:
- 第一步開啟
System UI Tuner
功能,開啟的方式是下拉通知欄,長摁右下角的設定按鈕,
直到系統提示System UI Tuner
已開啟; - 第二步去設定頁面
Settings > System > System UI Tuner > Navigation bar
,去到 navigation bar 之後選擇extra left button type
或者extra right button type
,選擇keycode
,選擇完成之後返回到上一個頁面填寫right/left keycode
為171
,代表將當前顯示頁面變為 PIP 模式視窗(如果不支援頁面沒有任何反應),然後選擇一個right/left icon
:
之後就會在導航欄上出現一個新增的按鈕,這個按鈕就是用來將頁面進入 PIP 模式;
- 第三步再返回上一個
System UI Tuner
頁面,選擇Picture-in-Picture
模式,進去之後將 Minimize 開啟即可。
完成上面的操作之後,進入支援 PIP 模式的頁面,比如 youtube 的視訊播放頁面,點選導航欄新增的那個按鈕,頁面就會縮小到一個小視窗播放,如上面的例項圖片所示。
要指定 Activity 可以使用 PIP 模式,需要在 Manifest檔案中將
android:supportsPictureInPicture
設定為 true,除了上面提到的使用者手動將 Activity 變成 PIP 模式,還可以使用 Activity.enterPictureInPictureMode(PictureInPictureArgs args)
動態將 Activity 設定為 PIP 模式, PictureInPictureArgs
這個物件引數是用來指定 Activity 處於 PIP 模式時的行為,此物件還指定了各種屬性,例如 Activity 的首選縱橫比,同時還可以使用 Activity.setPictureInPictureArgs()
更新 Activity 的 PIP 配置設定,如果 Activity 目前處於 PIP 模式,則會更新此設定。 使用場景:這個功能就很貼心了,比起以前的 Multi-window,這個更強調兩個應用的主次之分,比較適合的場景可能有視訊播放頁面的最小化,地圖應用的最小化等等。針對 QQ 音樂來說可以使用在直播頁面,MV 播放頁面等等。
1.3 自適應圖示
為了幫助開發者更好的與裝置 UI 整合,Android O 支援建立自適應圖示,系統可以基於裝置選擇的蒙版將這些圖示顯示為不同形狀。系統還將實現與圖示的自動互動,並在啟動器、快捷方式、設定、共享對話方塊以及概覽螢幕中使用它們:
可以通過定義兩層圖層(前景和背景)來指定桌面圖示外觀,必須提供沒有形狀和陰影的 PNG 格式圖象作為圖層:
在以前的 Android 版本中,圖示大小定義為 48 x 48 dp,但是現在必須按照以下的規範定義圖層大小:
1. 兩張圖層大小都必須為 108 x 108 dp。
2. 圖層中心 72 x 72 dp 範圍為可視範圍。
3. 系統會保留四周的 18dp 範圍用於生成有趣的視覺效果(如視差和跳動):
建立自適應圖示可以參考:Create adaptive icons with Android Studio:
這個就將以前混亂的圖示統一化了,現在 Android 很多應用的圖示,有的是正方形的,有的帶圓弧,而且這圓弧的弧度各有差異,有的圖示還是圓形,有的則是不規則的圖片,統一之後所有的應用圖示將具有一致的風格,比較推薦。
1.4 自動填充框架
Android O 還引入了自動填充框架,簡化了使用者在賬號建立、登入和信用卡表單之類的填寫工作,在使用者選擇自動填充框架之後,新老使用者都可以使用自動填充框架,我們使用 Chrome 的時候已經體驗過了自動填充使用者名稱和密碼的功能,只不過這次是在系統層面提供了這樣的一種功能,可以快速的填充使用者名稱,地址甚至密碼等,而且使用者也不需要去擔心安全問題。
同樣自動填充框架也需要去設定頁面開啟: Settings > Apps & Notifications > Default apps > Autofill app
,關於如何適配自動填充框架:Autofill Framework:
這個場景可以參考 Chrome 的記住賬號和密碼功能,例如現在的 QQ 登入其實是已經做了一個類似的 Auto-Fill 功能,比較適合用在賬號密碼等場景上。
1.5 xml 字型和可下載字型
Android O 推出了 xml 字型,可以在資原始檔中建立 font 字型資原始檔夾,放入相應的字型 ttf 檔案,然後建立自己的字型 xml 檔案,在 R 檔案中編譯,最終作為一種資源供 TextView 等使用,
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font
android:fontStyle="normal"
android:fontWeight="400"
android:font="@font/lobster_regular" />
<font
android:fontStyle="italic"
android:fontWeight="400"
android:font="@font/lobster_italic" />
</font-family>
同時 Android O 和 Android support library 26 提供了一個 API,可以從另一個應用中獲取字型資源,而不是將字型資源打包到 apk 中或者讓 apk 去下載,通過 Android support library 26 版本可以讓這個特性支援到 14 版本或者之上的裝置上,具體的 API 可以看看這個:Downloadable Fonts 或者這個 sample android-DownloadableFonts:
適用場景:這個比較適合在公司的一系列 APP 上使用,更換面板同時更換字型等等。
1.6 Pinned Shortcut
這個功能在 7.1.1 之後就已經有了,長摁桌面圖示就會顯示一個 App shortcuts 選單欄,然後長摁選單欄上的一項,就能把它拖下來成為單獨的一個應用圖示,被拖下來的單獨的應用圖示就是Pinned shortcuts,雖然這個功能在 7.1.1 引入的,但是在 O 版本我們可以通過提供的 API 按照一定的步驟去使用程式碼新增:Pinning Shortcuts and Widgets。
適用場景:這個可以將某些應用使用頻繁的小功能獨立出來,比如 QQ 的最常用聯絡人,音樂的聽歌識曲等功能。
1.7 TextView 字型自動適配
Android O 版本允許設定 TextView 的字型大小根據設定的初始大小自動放大或者縮小,這樣就可以讓字型的顯示在不同的螢幕和不同的顯示內容上達到最優的效果,而且使用 Android support library 26 中的 android.support.v4.widget.TextViewCompat 可以讓該特性支援到 14 版本,Android O 版本的 TextView 已經可以支援 autosize 了,設定 autosize 特性也非常簡單,在 O 版本上,只需要使用 setAutoSizeTextTypeWithDefaults(@AutoSizeTextType int autoSizeTextType)
或者
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoSizeTextType="uniform"
/>
就可以了,關於使用的細節:Autosizing TextViews。
適用場景:TextView 顯示內容較多的時候,如果可以接受的話,適當的減小字型的大小,讓顯示的字數增加。
1.8 媒體增強
Android O 版本新增 VolumeShaper 類,用來為應用提供聲音的淡入淡出等音效;新增AudioFocusRequest 類用來提供檢測音訊焦點的新功能;新增了以下的方法 getMetrics 方法用來返回一個包含配置和效能資訊的 Bundle 物件:
- MediaPlayer.getMetrics()
- MediaRecorder.getMetrics()
- MediaCodec.getMetrics()
- MediaExtractor.getMetrics()
MediaPlayer 新增了一些新的方法,這些方法可以用來增強應用處理媒體播放的能力:
- 通過控制緩衝行為改進效能的功能;
- 在搜尋幀時進行精細控制;
- 播放受數字版權管理保護的材料的功能(和 MediaDrm 類功能類似,但是不同的是這個不會暴露底層的提取器,版權和加密資料:DRM support)。
音訊錄製器 MediaRecorder 現在支援對流式傳輸有用的 MPEG2_TS 格式,MediaMuxer 現在可以處理任意數量的音訊和視訊流,而不再僅限於一個音訊曲目和/或一個視訊曲目。使用 addTrack() 可混錄所需的任意數量的曲目,MediaMuxer 還可以新增一個或多個包含使用者定義的每幀資訊的元資料曲目。元資料的格式由應用定義。僅對 MP4 容器支援元資料曲目。
1.8.1 音訊播放設定
Android O 允許應用查詢和獲取裝置如何發出聲音,應用可以通過 requestAudioFocus()
函式來為裝置範圍的音訊焦點提交一個細粒度的請求,比如傳入一個 AudioFocusRequest
物件,設定對應的 type,就可以指定獲取焦點的型別,同時可以設定當音訊焦點被強佔時候應用的行為,輕聲繼續播放還是徹底暫停。
1.8.2 LDAC 音質增強
值得一提的是,在 Android O 上引入了 sony “捐贈”的 LDAC 無線聲音加密格式,用來進行高質量音樂的藍芽通訊,這樣就可以通過藍芽耳機播放真正的無損音樂了:
可以看到使用了 LDAC 無線聲音加密協議之後,最高可以達到 990kbps 的傳輸速率,好訊息是不是!但是可惜的是 LDAC 只能再 sony 製造的耳機上使用,比如 £330 MDR-1000X,高呼Sony大法好~~
1.9 其他特性
1. 可以設定 Activity 支援廣色域;
2. 可以設定最大的螢幕寬高比;
3. 多螢幕支援,支援裝置外接一個顯示器;
4. 最新版本 emoji 支援,使用 EmojiCompat
類可以讓應用在老版本的應用上顯示新的 emoji;
5. 支援點選位置的捕捉;
6. 支援設定應用類別,這些類別用於將應用呈現給使用者的用途或功能相同的應用歸類在一起,例如按流量消耗、電池消耗和儲存消耗將應用歸類。
7. Smart Text Selection,這個功能有人可能在今年老羅的錘子手機發佈會上看到過,思想是很類似的,複製一段數字,就會出現直接撥打電話的選項,複製一段地址就會彈出進入地圖的選項,地圖 APP 可以一下這個地方能否成為一個很方便入口。
2 Android O 版本行為變更
這個列舉了當前可能會影響應用的幾個行為變更。
2.1 後臺執行限制
Android O 在當程序進入已快取狀態時,如果沒有活動的元件,系統將解除應用具有的所有喚醒鎖(已快取狀態指的是沒有前臺 Activity 或者正在執行的前臺 Service)。同時 Android O 上執行在後臺的應用將會有限制的使用後臺的 Service,並且應用也不能在 Manifest 中註冊一些不必要的隱式廣播用來進行自啟等操作:
- 在後臺執行的應用對後臺服務的訪問受到限制;
處於前臺時,應用可以自由建立和執行前臺服務與後臺服務。 進入後臺時,在某些情況下,在一個持續數分鐘的時間窗內,應用仍可以建立和使用服務,這些情況包括:
- 正在處理高優先級別的 FCM 訊息;
- 正在接收例如 SMS/MMS 的訊息廣播;
- 正在從通知處理 PendingIntent 訊息;
官方建議多使用 JobScheduler 來處理後臺任務,詳細的適配指南:後臺執行限制。
2.2 安全性
Android O 包含以下與安全性有關的變更:
- 不再支援 SSLv3;
- 應用的 WebView 物件將在多程序模式下執行。網頁內容在獨立的程序中處理,此程序與包含應用的程序相隔離,以提高安全性;
- 在與未正確實現 TLS 協議版本協商的伺服器建立 HTTPS 連線時,HttpsURLConnection 不再嘗試回退到之前的 TLS 協議版本並重試的權宜方法;
- Android O 將使用安全計算 (SECCOMP) 過濾器來過濾所有應用。允許的系統呼叫列表僅限於通過 bionic 公開的系統呼叫。此外,還提供了其他幾個後向相容的系統呼叫,但我們不建議使用這些系統呼叫。
2.3 網路連線和 HTTP(S) 連線
Android O 對網路連線和 HTTP(S) 連線行為做出了不少變更,其中包括無正文的 OPTIONS 請求現在有 Content-Length: 0 標頭;HttpURLConnection 在包含斜線的主機或頒發機構名稱後面附加一條斜線,將 http://example.com 轉化為 http://example.com/ ;通過 ProxySelector.setDefault() 設定的自定義代理選擇器的範圍變化;URI 不能包含空白標籤;如果之前執行的 connect() 方法失敗,send(java.net.DatagramPacket) 方法將會引發 SocketException;在回退到 TCP Echo 協議之前,InetAddress.isReachable() 會嘗試執行 ICMP;隧道 HTTP(S) 連線處理進行了一些變更。
變更內容比較繁多:網路連線和 HTTP(S) 連線。
2.4 許可權
在 Android O 之前,如果應用在執行時請求許可權並且被授予該許可權,系統會錯誤地將屬於同一許可權組並且在清單中註冊的其他許可權也一起授予應用。對於針對 Android O 的應用,此行為已被糾正。系統只會授予應用明確請求的許可權。然而,一旦使用者為應用授予某個許可權,則所有後續對該許可權組中許可權的請求都將被自動批准。
2.5 媒體變更
- 使用 AudioTrack 時,如果應用請求了足夠大的音訊緩衝區,則框架將嘗試使用深度緩衝區輸出(如果可用);
- 音訊流型別應僅用於音量控制;所有其他流型別的使用(例如 AudioTrack 建構函式)仍有效,但系統會將其作為錯誤記錄下來;
- 當用戶打電話時,活動的媒體流將在通話期間靜音;
- 所有與音訊相關的 API 均使用 AudioAttributes 來描述音訊播放用例;
- 框架會執行音訊閃避,進行 AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK 時,應用不會失去焦點。新的 API 適用於需要暫停而不是閃避的應用。不過,Android O 中未提供此行為。
2.6 Native libraries
在針對 Android O 的應用中,如果 Native libraries 包含任何可寫且可執行的程式碼段,則不會再載入 Native libraries,可寫和可執行必須是在新版本必須是互斥的,倘若某些應用的 Native libraries 包含不正確的載入程式碼段,則此變更可能會導致這些應用停止工作,官方文件:Writable and Executable Segments。
2.7 其他
1. ContentProvider 支援分頁,即獲取內容的選中區域的子集;
2. ContentProvider 和 ContentResolver 增加 refresh 方法,用來讓客戶端更容易的知道資料是不是最新;
3. JobScheduler 更新,讓應用更容易遵從後臺執行限制;
4. 集合的處理的變化,AbstractCollection.removeAll() 和 AbstractCollection.retainAll() 始終引發 NullPointerException;
5. 語言區域和國際化變化;
6. 聯絡人提供程式使用情況統計方法的變更;
7. 藍芽 ScanRecord.getBytes() 方法檢索的資料長度變更;
8. 輸入和導航;
3 Android O 版本 API 變更
3.1 WebView 新 API
Android O 預覽版本提供了幾個新的 API 用來管理 WebView:
- Version API 第一個是提供獲取 WebView 版本資訊的 API:
PackageInfo webViewPackageInfo = WebView.getCurrentWebViewPackage();
Log.d("MY_APP_TAG", "WebView version: " + webViewPackageInfo.versionName);
<manifest>
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
android:value="true" />
...
<application> ... </application>
</manifest>
Termination Handle API
一起搭配使用;
3.2 findViewById
findViewById 函式現在返回的是 <T extends View>,所以以後 findViewById 就不需要強轉了。
3.3 統一的 margins 和 padding
Android 引入了幾個新的 xml 屬性:
- `layout_marginVertical`,同時設定 `layout_marginTop` 和 `layout_marginTop` 屬性;
- `layout_marginHorizontal`,同時設定 `layout_marginLeft` 和 `layout_marginRight`屬性;
- `paddingVertical`,同時設定 `paddingTop` 和 `paddingBottom`屬性;
- `paddingHorizontal`,同時設定 `paddingLeft` 和 `paddingRight`屬性;
3.4 AnimationSet
Android O 中,AnimationSet API 現在支援了動畫的 seek 和動畫倒轉播放,seek 操作可以設定 AnimationSet 從指定的點開始播放,倒轉播放則將以前需要重複定義兩個相反的動畫操作簡化成只需要定義一個動畫即可。
3.5 提醒視窗
在 Android O 版本之前,應用如果不用 type_toast 顯示懸浮窗,一般正常情況下都會使用宣告 SYSTEM_ALERT_WINDOW 許可權 + 使用 TYPE_SYSTEM_ERROR 的形式來顯示懸浮窗,國內的第三方 ROM 也會對此有限制,Android 6.0 版本曾經對懸浮窗有過一次限制,必須要使用者手動開啟“在其他應用之上顯示”的許可權才能展示懸浮窗,在 Android O 之後 SYSTEM_ALERT_WINDOW 許可權的應用無法再使用以下視窗型別來在其他應用和系統視窗上方顯示提醒視窗:
- TYPE_PHONE
- TYPE_PRIORITY_PHONE
- TYPE_SYSTEM_ALERT
- TYPE_SYSTEM_OVERLAY
- TYPE_SYSTEM_ERROR
相反,應用必須使用名為 TYPE_APPLICATION_OVERLAY 的新視窗型別,在使用 TYPE_APPLICATION_OVERLAY 視窗型別顯示應用的提醒視窗時,也增加了一下限制:
- 應用的提醒視窗始終顯示在狀態列和輸入法等關鍵系統視窗的下面;
- 系統可以移動使用 TYPE_APPLICATION_OVERLAY 視窗型別的視窗或調整其大小,以改善螢幕顯示效果;
- 通過開啟通知欄,使用者可以訪問設定來阻止應用顯示使用 TYPE_APPLICATION_OVERLAY 視窗型別顯示的提醒視窗。