天天看點

I/O 前沿 | Android 更新一覽(Day1)

大家好,我是朱濤。

又到了一年一度的 I/O 大會,今年仍然是線上直播的形式,Day1:主要是一些主題演講、産品釋出,還有 Codelab。Day2:則是一些技術領域的 Session。

以下内容是我看完 Day1 内容後,梳理出的 Android 開發者相關的資訊,主要包括:Android 13 更新、Android Studio 更新、Jetpack 更新。

一、Android 13 的重要變更

Android 13 有許多令人振奮的新特性,這裡我隻列了跟 Android 開發者相關的變更。

隔離 WiFi 與地理位置權限

在 Android13 之前,我們為了擷取使用者在室内的精确位置,地圖 SDK 往往需要擷取 WiFi 相關的權限。這一行為對于開發者而言是能了解的,但使用者卻會覺得十分可疑。

是以,Android 13 引入了一個新的權限:

NEARBY_WIFI_DEVICES      

詳細的介紹大家可以看這個​​文檔​​。

作者備注:這真的很貼心!其實,Android12 也有類似的行為變更,Android 12 隔離了藍牙與地理位置權限。使用者不必為了地理位置權限而開放藍牙權限了。

省電神器:前台服務管理器

在 Android 13 當中,使用者可以通過前台服務管理器(Foreground Services (FGS) Task Manager),管理目前系統運作的所有前台服務。

I/O 前沿 | Android 更新一覽(Day1)
作者備注:從前,對于沒有通知權限的應用,它的前台服務可能無法展示在通知欄,使用者自然也就無法注意到。這一點在 Android 13 不再是問題。

更細顆粒度的存儲權限

對于存儲權限,想必大家都對 ​

​READ_EXTERNAL_STORAGE​

​​、​

​WRITE_EXTERNAL_STORAGE​

​ 十分熟悉。但是,在 Android 13 當中,對讀取權限被劃分成了更加細的顆粒度。

檔案類型 對應權限
圖檔 READ_MEDIA_IMAGES
視訊 READ_MEDIA_VIDEO
音頻 READ_MEDIA_AUDIO
<manifest ...>
    <!-- 隻在 Android 13 使用. -->
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO"
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO"

    <!-- 相容Android 13 之前的系統. -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
                     android:maxSdkVersion="32"
    <application ...>
        ...
    </application>
</manifest>      

另外,Android 13 還提供了類似 iOS 的“系統級别的”圖檔選擇器。如果你隻需要通路圖檔與視訊,Photo Picker 将會是一個不錯的選擇。

其他變更

以下是一些對開發者不那麼重要的變更,大家感興趣的可以點選連結看詳細内容。

  • ​​阻止不比對的 Intent-filter​​
  • ​​電量管理變更​​
  • ​​音樂播放體驗優化​​

二、Android Studio 更新

全新的​​Android Studio 版本​​:海豚、鳗魚。

I/O 前沿 | Android 更新一覽(Day1)

其中,海豚版本,已經進入 Beta 管道了,而鳗魚版本則是 Canary build,兩者都提供了許多實用的特性,尤其是:對 Compose 的支援!

I/O 前沿 | Android 更新一覽(Day1)

三、Jetpack 重要變更

首先,Jetpack 在 Android 生态當中的使用率進一步提升了,可以說 Jetpack 越來越受歡迎,地位也越來越重要了。

I/O 前沿 | Android 更新一覽(Day1)

性能優化: JankStats

今年的 I/O 大會,Jetpack 格外關注性能優化,它同時推出了兩個新的庫:​​JankStats​​​、​​Baseline Profiles​​,而且,也更新了去年新推出的 Macrobenchmark。

JankStats,顧名思義,就是為了監測掉幀、卡頓的。

I/O 前沿 | Android 更新一覽(Day1)

大緻用法如下:

class JankLoggingActivity : AppCompatActivity() {

    private lateinit var jankStats: JankStats

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        // metrics state holder can be retrieved regardless of JankStats initialization
        val metricsStateHolder = PerformanceMetricsState.getForHierarchy(binding.root)

        // initialize JankStats for current window
        jankStats = JankStats.createAndTrack(
            window,
            Dispatchers.Default.asExecutor(),
            jankFrameListener,
        )

        // add activity name as state
        metricsStateHolder.state?.addState("Activity", javaClass.simpleName)
        // ...
    }

    override fun onResume() {
        super.onResume()
        jankStats.isTrackingEnabled = true
    }

    override fun onPause() {
        super.onPause()
        jankStats.isTrackingEnabled = false      

性能優化黑科技:Baseline Profiles

​​Baseline Profiles​​​是一個被編譯進 APK 當中的檔案,具體路徑在:​

​assets/dexopt/baseline.prof​

​。我們開發者可以将一些高優先級的方法打進去,友善 Android 虛拟機去做特定的優化。

當應用首次安裝的時候,ART 虛拟機可以根據 baseline.prof 當中的方法,進行 AOT 編譯優化,這樣就可以讓我們這些特殊關心的方法運作的更快。

I/O 前沿 | Android 更新一覽(Day1)

通過 Baseline,我們開發者從某種程度可以跟 ART 虛拟機交流,去決定哪些方法可以進行 AOT 編譯。可以想象,這一技術運用到冷啟動優化當中是會帶來不菲收益的。

以下是它的相容性描述。

I/O 前沿 | Android 更新一覽(Day1)
作者備注:另外,Baseline 可以跟 Macrobenchmark 搭配使用,更多内容請閱讀​​Macrobenchmark 官方文檔​​​、​​Baseline Profiles 的官方文檔​​。

四、Jetpack Compose 更新

今年的 Jetpack Compose 更新,其實分為兩個部分,一個是工具支援,也就是前面提到過的 Android Studio 更新,為我們開發者帶來更好的開發體驗。另外一個部分,則是API 層面的更新。

Lazy Layout

首先 Compose 在 1.2 版本中進一步優化了它的​​Lazy Layout​​的性能,包括 LazyColumn、LazyRow、LazyVerticalGrid(實驗性)。

I/O 前沿 | Android 更新一覽(Day1)

嵌套滑動

另外,則是進一步完善了 Compose 當中的​​嵌套滑動​​。

實作 Compose 的嵌套滑動,在大部分情況下,是可以自動實作的。比如說這個例子:

val gradient = Brush.verticalGradient(0f to Color.Gray, 1000f to Color.White)
Box(
    modifier = Modifier
        .background(Color.LightGray)
        .verticalScroll(rememberScrollState())
        .padding(32.dp)
) {
    Column {
        repeat(6) {
            Box(
                modifier = Modifier
                    .height(128.dp)
                    .verticalScroll(rememberScrollState())
            ) {
                Text(
                    "Scroll here",
                    modifier = Modifier
                        .border(12.dp, Color.DarkGray)
                        .background(brush = gradient)
                        .padding(24.dp)
                        .height(150.dp)
                )
            }
        }
    }
}      

其他更新

  • ​​視訊:What's new in Android​​
  • ​​視訊:What's new in Jetpack​​