Android 15 的新功能與適配

前臺服務變化

前臺服務一直是比較損耗電池壽命的操作,在 Android 15 Beta 2 裏,**dataSync 和 mediaProcessing 的前臺服務類型現在有大約 6 小時的超時時間**,之後系統將調用 Android 15 新的 Service.onTimeout(int, int)方法,之後該服務就不會再被視爲前臺服務,如果服務沒有調用Service.stopSelf() 來響應超時,它會因未觸發失敗而停止。

Beta 2 還增加了應用在後臺運行時啓動前臺服務的新要求 :如果前臺服務依賴於 SYSTEM_ALERT_WINDOW 權限來豁免後臺啓動,則現在在面向 Android 15 時需要有可見的疊加層

支持 16 KB 頁面大小

Android 15 增加了對使用較大頁面大小的設備的支持,除了標準 4 KB 頁面之外,還支持 16 KB 頁面,如果你的應用直接或通過 SDK 間接使用任何 NDK 庫,那麼可能需要重構應用纔可以在 16 KB 頁面大小的設備上運行

PS:頁面大小指的是虛擬內存中的頁面(也稱爲頁)的大小,通常是 2 的整數次冪,比如2KB、4KB、8KB等

配置有 16KB 頁面大小的設備,對於 App 的啓動性能有着不錯的提升 ,並且在明年 Google Play 也將支持應用上傳到 Play 商店時支持 16 KB 頁面兼容性

Android 的 GPU 訪問

從 Android 7.0(API 級別 24)以來,Vulkan API 已經在 NDK 裏提供,使用 Vulkan API 可以更好接觸到 GPU 的底層能力。

Vulkan 現在是 Android 的首選 GPU 接口,而 Android 15 將 ANGLE 作爲可選層,用於在 Vulkan 之上運行 OpenGL ES,轉向 ANGLE 將使 Android OpenGL 實現標準化以提高兼容性,並在某些情況下可以提高性能。

對於開發者,可以使用 Android 15 中的 “開發者選項 → Experimental: Enable ANGL” 設置來測試 OpenGL ES 應用的穩定性和性能。

作爲簡化 GPU 堆棧的一部分,今後將會在更多新設備上將 ANGLE 作爲 GL 系統的驅動程序,未來預計 OpenGL/ES 將僅通過 ANGLE 提供。

現代圖形

Android 15 繼續對 Android Canvas 圖形系統進行新的改造:

  • Matrix44 提供了一個 4x4 矩陣用於轉換座標,當開發者想要以 3D 方式操作畫布時可以使用該矩陣。
  • ClipShader 將當前剪輯與指定着色器相交,而 clipOutShader 將剪輯設置爲當前剪輯與着色器的差值,每個將着色器視爲 alpha 遮罩,這個支持可以有效地繪製複雜形狀。

AV1軟件解碼

dav1d 是 VideoLAN 的 AV1 軟件解碼器,現在可以用於不支持 AV1 解碼硬件的 Android 設備,它的性能比傳統 AV1 軟件解碼器高出 3 倍,可爲更多用戶(包括一些中低端設備)提供高清 AV1 播放。

目前應用需要通過 “c2.android.av1-dav1d.decoder ” 調用來選擇使用 dav1d ,在後續更新中它將成爲默認的 AV1 軟件解碼器,另外這個支持已標準化並向後移植到接收 Google Play 系統更新的 Android 11 設備。

私人空間

私人空間允許用戶在其設備上創建一個單獨的空間,在額外的身份驗證層下,可以讓敏感應用得到隔離。

私人空間使用單獨的用戶配置文件,當用戶鎖定私人空間時,配置文件將處於暫停,同時 App 耶不再活動,用戶可以選擇使用設備鎖或單獨的鎖定來保護私人空間。

私人空間應用顯示在啓動器的單獨容器中,並且在私人空間鎖定時從最近的視圖、通知、設置和其他應用中隱藏。

用戶生成和下載的內容(媒體、文件)和帳戶在私人空間和主空間之間分開,當私人空間解鎖時,系統共享表和照片選擇器可用於讓應用訪問跨空間的內容。

照片選擇改進

現在,當 App 得到部分媒體權限時,應用可以僅突出顯示最近選擇的照片和視頻,這可以改善頻繁請求訪問照片和視頻的用戶體驗,詳細可以通過 ContentResolver 在 MediaStore 啓用時查詢 QUERY_ARG_LATEST_SELECTION_ONLY 參數來實現。

valexternalContentUri = MediaStore.Files.getContentUri("external")

val mediaColumns = arrayOf(
   FileColumns._ID,
   FileColumns.DISPLAY_NAME,
   FileColumns.MIME_TYPE,
)

val queryArgs = bundleOf(
   // Return only items from the last selection (selected photos access)
   QUERY_ARG_LATEST_SELECTION_ONLY to true,
   // Sort returned items chronologically based on when they were added to the device's storage
   QUERY_ARG_SQL_SORT_ORDER to "${FileColumns.DATE_ADDED} DESC",
   QUERY_ARG_SQL_SELECTION to "${FileColumns.MEDIA_TYPE} = ? OR ${FileColumns.MEDIA_TYPE} = ?",
   QUERY_ARG_SQL_SELECTION_ARGS to arrayOf(
       FileColumns.MEDIA_TYPE_IMAGE.toString(),
       FileColumns.MEDIA_TYPE_VIDEO.toString()
   )
)

val cursor = contentResolver.query(externalContentUri, mediaColumns, queryArgs, null)

對 content URI 的權限檢查

Android 15 引入了一組新的 API,用於對 content URI 執行權限檢查:

  • Context.checkContentUriPermissionFull :它對內容 URI 執行完整的權限檢查。
  • Activity manifest attribute requireContentUriPermissionFromCaller:它在 activity 啓動時對提供的 content URI 強制執行指定的權限。
  • Activity 調用者的 ComponentCaller :它代表啓動該 Activity 的應用。

安全的後臺 activity 啓動

從 Android 10 起後臺 activity 啓動就受到限制,而 Android 15 通過添加其他控制,來防止惡意後臺應用將其他應用帶到前臺。

在此之前,同一任務中的惡意應用可以啓動另一個應用的 activity ,然後將自己疊加在上面,從而造成是該應用的錯覺,這種“任務劫持”(task hijacking) 攻擊繞過了當前的後臺啓動限制,因爲它全部發生在同一個可見 task 中,爲了減輕這種風險, Android 15 添加了一個標誌,阻止與堆棧上頂部 UID 不匹配的應用啓動 activity

可以通過在 AndroidManifest.xml 文件中配置 allowCrossUidActivitySwitchFromBelow 屬性,指定任務的 activity 是否可以啓動其他 activity 或結束 task :

<application android:allowCrossUidActivitySwitchFromBelow="false" >

一旦應用全局配置了新的保護模式,一些特殊的 activity 也使用下面這個 API 來選擇退出:

public void onCreate(Bundle bundle) {
  super.onCreate(bundle);
  setAllowCrossUidActivitySwitchFromBelow(true);
  ...
}

更安全的 Intents

Android 15 引入了新的安全措施,使 intents 更安全和強大,這些更改旨在防止惡意應用利用潛在的漏洞,Android 15 中對 Intent 安全性的主要改進有兩個:

  • 匹配目標 intent-filters:針對特定組件的 intent 必須準確匹配目標的 intent-filters 規範,如果發送 intent 來啓動另一個應用的 activity ,則目標 intent 組件需要與接收 activity 聲明的 intent-filters 保持一致。
  • intent 必須有 action:沒有 action 的 intent 將不再匹配任何 intent-filters ,這意味着用於啓動 activity 或 service 的 intent 必須具有明確定義的 action。

這些改進將成爲 Strict Mode 的一部分:

public void onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        .detectUnsafeIntentLaunch()
        .build());
    ...

將最低 target SDK 版本從 23 增加到 24

Android 15 將安裝應用所需的最低 targetSdkVersion 從 23 增加到 24,如果嘗試安裝 target API 級別低於 24 的應用,會在 Logcat 中看到錯誤:INSTALL_FAILED_DEPRECATED_SDK_VERSION: App package must target at least SDK version 24, but found 7.

改進大屏幕多任務處理

Android 15 beta 2 爲用戶提供了在大屏幕設備上處理多任務的更好方法,例如用戶可以將任務欄固定在屏幕上,然後在應用之間快速切換,當然,這也代表了你的 App 需要具不同的屏幕適應能力。

 

Window Insets

除了 edge-to-edge enforcement 的強制執行之外 , Configuration.screenWidthDp 和 screenHeightDp 中針對 SDK 35+ 時,現在還包括系統欄的深度,雖然這些值還是可以用於資源選擇(例如 res/layout-h500dp),但不鼓勵使用它們進行佈局計算:

畫中畫

Android 15 引入了畫中畫 (PiP) 的新變化,確保進入 PiP 模式時的過渡更加平滑,這對於 UI 元素覆蓋在其主 UI 之上(進入畫中畫)的應用可以看到對應的效果。

目前 onPictureInPictureModeChanged 用於定義切換重疊 UI 元素的可見性的邏輯,當畫中畫進入或退出動畫完成時會觸發此回調。

從 Android 15 開始,我們在 PictureInPictureUiState 類中引入了一個新狀態,一旦 PiP enter animation 開始,並且應用可以隱藏覆蓋的 UI 元素, 就會使用 isTransitioningToPip() 調用 onPictureInPictureUiStateChanged 回調。

override fun onPictureInPictureUiStateChanged(pipState: PictureInPictureUiState) {
    if (pipState.isTransitioningToPip()) {
       // Hide UI elements
        }
    }

override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
    if (isInPictureInPictureMode) {
       // Unhide UI elements
        }
    }

這種 UI 不相關(對於畫中畫窗口)的快速可見能力,可以讓畫中畫動畫切換更平滑且不閃爍。

通過生成的預覽提供更豐富的 Widget 預覽

通過顯示個性化預覽讓 Widget 脫穎而出,針對 Android 15 的應用可以向 Widget Picker 提供 Remote Views,從而讓它們可以更新 picker 中的內容,讓用戶將看到他們更想看到的內容。

應用可以使用  AppWidgetManager  setWidgetPreview、getWidgetPreview和 removeWidgetPreview 方法來使用最新的個性化信息更新 Widget 的外觀。

Predictive Back

Predictive back 在使用手勢導航的同時提供了更流暢、更直觀的導航體驗,利用內置動畫告知用戶他們的操作將把他們帶到哪裏,以減少意外結果。

在 Android 15 中,Predictive Back 將不再是開發者選項,對於已正確遷移的應用,將出現返回主頁、跨任務和跨活動等系統動畫。

爲通知通道設置 VibrationEffect

Android 15 beta 2 現在支持使用 NotificationChannel.setVibrationEffect ,按通道爲傳入通知設置豐富的振動,這樣用戶就無需查看設備即可區分不同類型的通知。

“選擇你的稱呼方式”系統偏好設置

用戶可以根據語法性別偏好自定義 Android 系統如何稱呼他們,新設置可以在系統語言設置中找到:Settings → System → Languages & Input → System languages → Choose how you’re addressed

CJK 可變字體

從 Android 15 開始,中文、日文和韓文的字體文件 NotoSansCJK 會是可變字體,可變字體爲 CJK 語言的創意排版開闢了新的可能性。

新日語 Hentaigana 字體

在 Android 15 中,默認捆綁了舊日語平假名(稱爲 Hentaigana)的新字體文件,半假名字符的獨特形狀可以爲藝術品或設計增添獨特的風格,同時也有助於保存對古代日本文獻的準確傳播和理解。

避免剪切文本

某些具有複雜形狀的草書字體或語言字符可能會在上一個或下一個字符的區域中繪製字母,這些字母可能會在開始或結束位置被剪裁,從 Android 15 開始,TextView 爲此類字母分配額外的寬度,並在左側添加額外的填充。

由於這會改變 TextView 決定寬度的方式,因此如果應用面向 Android 15 或更高版本,則默認情況下 TextView 會分配更多寬度,可以通過在 TextView 上調用 setUseBoundsForWidth API來啓用或禁用它

由於添加左內邊距可能會導致現有佈局錯位,因此即使面向 Android 15 或更高版本,默認情況下也不會添加內邊距。

要添加額外的填充以防止剪切,請調用 setShiftDrawingOffsetForStartOverhang。

<TextView
    android:fontFamily="cursive"
    android:text="java" />

<TextView
    android:fontFamily="cursive"
    android:text="java"
    android:useBoundsForWidth="true"
    android:shiftDrawingOffsetForStartOverhang="true" />

參考原文 :https://android-developers.googleblog.com/2024/05/the-second-beta-of-android-15.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章