作者:fundroid
這篇文章偏閱讀一些,大家可以了解下 Android 的一些最新動(dòng)向。
每年9/10月份 google 都會(huì)舉行約為期2天的 Android Dev Summit,在活動(dòng)上 Google 的技術(shù)專家們會(huì)分享 Android 的最新技術(shù)動(dòng)向及開發(fā)心得。

今年 Summit 的 Slogan 是 “Excellent Apps,across devices” , 即使用 Jetpack 等 MAD Skill (Moden Android Development) 開發(fā)出更優(yōu)秀的應(yīng)用,并通過 Android 系統(tǒng)落地到更多種類的智能設(shè)備。本次活動(dòng)圍繞這一主旨做了 30 多場技術(shù)分享(視頻),涉及多個(gè)方向:
https://developer.android.com/events/dev-summit
- Android 12
- 12L
- Building across screens
- Kotlin
- Jetpack
- Jetpack Compose
- Android Studio
- AGP
一、Android 12
Material You
Android12 在10月進(jìn)行了正式推送。Android12 的最大亮點(diǎn)就是基于 Material You 設(shè)計(jì)語言對原生系統(tǒng) UI 進(jìn)行了重新設(shè)計(jì)。Material You 是 Material Design 的第3個(gè)版本,距離上一代 M2 已經(jīng)過去了4年。

跟上一代 M2 相比 M3 的元素面積更大、更便于用戶點(diǎn)擊;同時(shí)圓角的角度更大使得并排的元素之間的間隔更清晰。個(gè)性化是 M3 最大的特點(diǎn),這也是 "You" 的命名來源。Android12 遵循了 M3 的 Dynamic Color 設(shè)計(jì)原則,系統(tǒng)可以從用戶的壁紙中抓取顏色,然后色階化應(yīng)用到你開發(fā)的應(yīng)用中,應(yīng)用跟隨主題的不同和變換顏色,千人千面。
Stretch Overscroll
https://developer.android.com/training/gestures/scroll#implement-stretch-overscroll
Android12 中加入了 Stretch overscroll effect ,相對于以前的水波紋效果,滾動(dòng)反饋更加真實(shí)自然。開發(fā)者可以使用新增的 getDistance() 和onPullDistance()API 來控制 OverScoll 的強(qiáng)度,當(dāng)然你也可以通過 XML 中設(shè)置 android:overScrollMode="never" 來屏蔽此效果。
App Splash Screen
https://developer.android.com/guide/topics/ui/splash-screen/migrate
Android12 增加了 Splash Screen API,可以在進(jìn)入 App 主頁之前自動(dòng)插入開屏頁,當(dāng)然它的目的是為了讓應(yīng)用減少白屏的等待時(shí)間而非廣告植入。Spash Screen 默認(rèn)使用 App 的 Icon 作為開屏圖案,開發(fā)者也可以使用系統(tǒng)提供的 API 自定義開屏圖案甚至動(dòng)畫。如果在非 Android12 設(shè)備上也想使用Splash Screen功能,則可以使用 Jetpack 也提供了同名 SplashScreen 庫,適配到了低至 Android 6(APP 23)的設(shè)備。需要注意,如果你的項(xiàng)目中通過 android:windowBackground或者 Customactivity 的方式自定義了開屏頁,則需要進(jìn)行適配,避免在 Android12 中出現(xiàn)兩次開屏。
Foreground service restrictions
https://developer.android.com/guide/components/foreground-services#background-start-restrictions
Android8 出于隱私保護(hù)的考慮,禁止了 Service 的后臺(tái)啟動(dòng),本次 Android12 中的限制進(jìn)一步加強(qiáng),除了一些特殊情況外,F(xiàn)oreground Service 也不允許在后臺(tái)啟動(dòng),否則會(huì)拋出 ForegroundServiceStartNotAllowedException 異常。Service 的存在越來越雞肋,或?qū)⒅饾u被 WorkManager 所替代。
Compatibility Test
每一個(gè)新版本的 Android 系統(tǒng)升級都會(huì)帶來不少 API 的行為變動(dòng),Android12 也不例外。為了確保你的 APP 在這些變動(dòng)下行為正常,一般需要修改targetSDKVersion 進(jìn)行針對性的測試。Android11 起提供了兼容性測試工具,在不重新編譯 APK 的情況下可以針對變動(dòng)的 API 進(jìn)行測試、提高測試效率。
在 Developer options > App compatibility changes 中可以找到測試工具。
二、12L (Android 12 Large Screens)
https://developer.android.com/about/versions/12/12L
近年來,搭載 Android 系統(tǒng)的大屏設(shè)備增長迅速,除了平板類產(chǎn)品以外又出現(xiàn)了折疊屏手機(jī)這一新興門類,目前已經(jīng)有超過250萬部大屏幕設(shè)備上運(yùn)行著 Android 系統(tǒng)。為提高大屏設(shè)備的使用體驗(yàn)。Android12 即將推出一個(gè)專門為大屏優(yōu)化的版本,命名 12L。12L 針對大屏設(shè)備和折疊屏對界面進(jìn)行了優(yōu)化,例如當(dāng)屏幕寬度大于 600dp 時(shí)將默認(rèn)顯示兩列內(nèi)容、引入了類似 Chrome OS 的 Dock 欄等,同時(shí)支持拖拽分屏等功能,同時(shí)在不同窗口中啟動(dòng)多個(gè)應(yīng)用。

WindowManager
為應(yīng)對更多種類屏幕的出現(xiàn),Jetpack 提供了 WindowManager 庫,便于 App 更好地適配不同屏幕的尺寸。多窗口模式下的 App 不能再依賴Display.getRealMetrics() 獲取窗口尺寸,當(dāng)屏幕狀態(tài)變化導(dǎo)致,OnConfigurationChanged 發(fā)生時(shí),使用 WindowManager 的WindoeMetrics 獲取準(zhǔn)確的窗口尺寸,再根據(jù) windowsizeClass 以最合適的布局顯示當(dāng)前 UI。

Jetpack Compose 能更好地以響應(yīng)式的方式處理 OnConfigurationChanged時(shí)的 UI 變化,非常適合配合在 12L 的設(shè)備上使用。
enum class WindowSizeClass { COMPACT, MEDIUM, EXPANDED }
@Composable
fun Activity.rememberWindowSizeClass() {
val configuration = LocalConfiguration.current
val windowMetrics = remember(configuration) {
WindowMetricsCalculator.getOrCreate()
.computeCurrentWindowMetrics(this)
}
val windowDpSize = with(LocalDensity.current) {
windowMetrics.bounds.toComposeRect().size.toDpSize()
}
val widthWindowSizeClass = when {
windowDpSize.width < 600.dp -> WindowSizeClass.COMPACT
windowDpSize.width < 840.dp -> WindowSizeClass.MEDIUM
else -> WindowSizeClass.EXPANDED
}
val heightWindowSizeClass = when {
windowDpSize.height < 480.dp -> WindowSizeClass.COMPACT
windowDpSize.height < 900.dp -> WindowSizeClass.MEDIUM
else -> WindowSizeClass.EXPANDED
}
// Use widthWindowSizeClass and heightWindowSizeClass
}
本次活動(dòng)中分享的不少新技術(shù)都第一時(shí)間適配了 Compose ,這也反映出 Android 將 Compose 作為首選的 UI 解決方案的決心。
Activity embeding
除了可以多窗口中打開多個(gè)應(yīng)用,12L 還可以借助 XML 的配置或者調(diào)用WindowManager 提供的 API 實(shí)現(xiàn)同一應(yīng)用下多個(gè) Activity 的并排顯示。
三、Building across screens
Android Ware
Compose 技術(shù)棧采用了分層設(shè)計(jì)的思想,只要替換局部組件就可以遷移到不同平臺(tái)中使用,例如 WareOs 中只需要替換 Material 和 Navigation 的便可以實(shí)現(xiàn)穿戴設(shè)備 UI 的開發(fā)。
以一個(gè)卡片為例,除了新增個(gè)別 Composable 以外,與手機(jī)端的寫法別無二致。
AppCard(
appImage = {
Image(painter = painterResource(id = R.drawable.ic_message), ... )
},
appName = { Text("Messages") },
time = { Text("12m") },
title = { Text("Kim Green") },
onClick = { ... },
content = {
Column(modifier = Modifier.fillMaxWidth()) {
Text("On my way!")
}
},
)
Android for Cars
Android 提供了兩套車機(jī)系統(tǒng) Android Auto 以及 Android Automotive OS。
- Android Auto 提供了針對駕駛員優(yōu)化的應(yīng)用體驗(yàn),用戶在 Android Auto 上創(chuàng)建連接手機(jī)的服務(wù),手機(jī)應(yīng)用可以以更優(yōu)化的界面顯示在車機(jī)上。
- Android Automotive OS 是一款基于 Android 的車載信息娛樂系統(tǒng)。車載系統(tǒng)是專為提升駕駛體驗(yàn)而優(yōu)化的獨(dú)立 Android 設(shè)備。相對于 Android Auto,它無需借助手機(jī),用戶可以將應(yīng)用直接安裝到車載系統(tǒng)上。
開發(fā)者可以跨平臺(tái)的工程結(jié)構(gòu)開發(fā)車機(jī)應(yīng)用:
- car_app_common 是共享部分。
- automotive_os 和 andorid_auto 是兩個(gè) build target。
四、Kotlin
Kotlin Flow
https://medium.com/androiddevelopers/migrating-from-livedata-to-kotlins-flow-379292f419fb
Kotlin方面,本次活動(dòng)上重點(diǎn)推薦了 Kotlin Flow 在 MVVM 架構(gòu)中的應(yīng)用。基于 Jetpack 的 lifecycle-ktx 擴(kuò)展庫 Flow 可以轉(zhuǎn)變?yōu)橐粋€(gè) lifeycle-aware 組件,較好地替代現(xiàn)有的 LiveData 的使用場景。
你可以只在 Model 層使用 Flow,在 View 層仍然使用 LiveData,通過Flow.asLiveData 將 Flow 轉(zhuǎn)換為 LiveData:
// import androidx.lifecycle.asLiveData
class MessagesViewModel(repository: MessageRepository) : ViewModel() {
val userMessage = repository.userMessage.asLiveData()
...
}
當(dāng)然 View 層也可以直接使用 Flow,在 lifecycleScope.launch { } 或lifecycleScope.launchWheStart { } 中收集 Flow 的數(shù)據(jù)避免泄露,但是從性能出發(fā)更推薦使用 repeatOnLifecycle:
//imprort androidx.lifecycle.repeatOnLifecycle
class MessagesActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState:Bundle?) {
...
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.userMessages.collect { messages ->
listAdapter.submitList(messages)
}
}
}
}
}
當(dāng) MessagesActivity 離開 STARTED 時(shí),協(xié)程及時(shí)取消節(jié)省資源。

此外使用 stateIn 可以將 Flow 轉(zhuǎn)化為一個(gè) StateFlow 以熱流的形式確保數(shù)據(jù)的下游共享。活動(dòng)期間有網(wǎng)友在直播中詢問是否還有 Flow 無法取代 LiveData 的場景,官方的回答是 LiveData 除了 API 更簡單以外(相應(yīng)的功能也比較弱),已經(jīng)完全可以被 Flow 替代。
KSP
https://android-developers.googleblog.com/2021/09/accelerated-kotlin-build-times-with.html
KSP (Kotlin Symbol Procesing) 于9月份發(fā)布了 1.0 正式版。相比較于 KAPT 需要生成 JAVA Stub 后再基于 APT 處理注解的流程,KSP 底層基于基于 Kotlin Compiler Plugin ,省去了 Java Stub 的生成,編譯速度可以提高2倍以上,未來在 Kotlin Multiplatform Project 中也可使用,如果你的項(xiàng)目代碼已經(jīng)遷移到 Kotlin,那么未來的注解處理應(yīng)該首選 KSP。
apply plugin: 'com.google.devtools.ksp'
dependencies {
...
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
ksp "androidx.room:room-compiler:$room_version"
}
將 KAPT 替換為 KSP 的配置非常簡單,目前已經(jīng)有包括 Room 在內(nèi)的許多常見框架對 KSP 進(jìn)行了支持,未來 Dagger,Hilt 等也將接入 KSP 以加速注解處理。
五、Jetpack
Room
https://medium.com/androiddevelopers/room-auto-migrations-d5370b0ca6eb
10月份 Room 發(fā)布 2.4.0 Beta 01,主要新增了 Auto Migratioins 和 Multi-map Relations 兩個(gè)新 Features,同時(shí)支持使用 KSP 進(jìn)行注解處理。
當(dāng)數(shù)據(jù)庫表結(jié)構(gòu)發(fā)生變化時(shí),需要通過數(shù)據(jù)庫遷移保證數(shù)據(jù)的不丟失,例如字段名變化之類的變更,需要手寫 SQL 才能完成升級,而基于 Auto Migrations 可以檢測出兩個(gè)表結(jié)構(gòu)的區(qū)別,完成自動(dòng)升級。
@Database(
version = MusicDatabase.LATEST_VERSION,
entities = { Song.class, Artist.class },
autoMigrations = {
@AutoMigration (
from = 1,
to = 2
)
},
exportSchema = true
)
public abstract class MusicDatabase extends RoomDatabase {
...
}
之前的版本中 Room 使用 @Relatioin 進(jìn)行外鍵關(guān)聯(lián),為了避免多寫 SQL 需要單獨(dú)額外定義 Relatioin Class,其實(shí)對于 SQL 的態(tài)度沒必要談虎色變,適當(dāng)?shù)鼗钣?SQL 有助于更簡單地定義一對多的實(shí)體關(guān)系。
//Room Relations
data class ArtistAndSongs(
` @Embedded
val artist:Artist,
@Relation(...)
val songs:List<Song>
)
@Query("SELECT * FROM Artist")
fun getArtistAndSongs(): List<ArtistAndSongs>
//Room Multimap
@Query("SELECT * FROM Artist JOIN Song ON Artist.artistName = Song.songArtistName")
fun getAllArtistAndTheirSongsList(): Map<Artist, List<Song>>
Map<Artist, List<Song>> 這樣的數(shù)據(jù)結(jié)構(gòu)使用起來也更簡單。
WorkManager
https://medium.com/androiddevelopers/using-workmanager-on-android-12-f7d483ca0ecb

WorkManager 已經(jīng)不單單是一個(gè)簡單的異步任務(wù)處理框架,更是一整套強(qiáng)大的任務(wù)調(diào)度方案,可以有效替代 Service,更可靠地運(yùn)行長時(shí)間的任務(wù)。最低可以向后兼容到 6.0,覆蓋了市場絕多大數(shù)的機(jī)型。
WorkManager 2.6 支持 Multi-Process,借助 RemoteListenableWorker或者 RemoteCoroutineWorker 可以將任務(wù)運(yùn)行在任意指定進(jìn)程,實(shí)現(xiàn)跨進(jìn)程的監(jiān)聽;為應(yīng)對 Android12 的 Foreground Service 的啟動(dòng)限制,WorkManager 2.7 新增了 setExpedited API,可以高優(yōu)的立即啟動(dòng)相關(guān)任務(wù),不受后臺(tái)啟動(dòng)的約束。
val request = OneTimeWorkRequestBuilder<HighPriorityWorker>()
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build() WorkManager.getInstance(context).enqueue(request)
由于
CoroutineWorker.setForeground() 和
ListenableWorker.setForegroundAsync() 方法由 Foreground Service 提供支持,在一些禁止后臺(tái)啟動(dòng)的場景中一旦被調(diào)用,會(huì)發(fā)生
ForegroundServiceStartNotAllowedException 異常,這是在開發(fā)中需要特別注意的。
More Components
此外,Jetpack 的其他一些庫近期也都有新版本的發(fā)布。Navigation 2.4.0 beta 增加了多棧返回的支持,不同 NavHostFragment 的返回棧可以各自管理;DataStore 發(fā)布 1.0 可以更安全地替代 SharedPreferences 的使用;CameraX 1.1.0-alpha10 增加了 VideoCapture 視頻截圖和曝光補(bǔ)償?shù)葘?shí)用功能;Benchmark 1.1.0-alpha11 增加了 Frame Timing,性能測試更加精準(zhǔn),并向后兼容到 API 23。
六、Jetpack Compose
Compose 新增 androidx.compose.material3 庫,支持開發(fā) Material You 主題風(fēng)格的 UI。
Mateiral3
Compose.M3 通過 ColorScheme 來自定義配色方案,支持了 Material You 的 color scheme 設(shè)計(jì)規(guī)范。
private val Blue40 = Color(0xff1e40ff)
private val DarkBlue40 = Color(0xff3e41f4)
private val Yellow40 = Color(0xff7d5700)
// Remaining colors from tonal palettes
private val LightColorScheme = lightColorScheme(
primary = Blue40,
secondary = DarkBlue40,
tertiary = Yellow40,
// error, primaryContainer, onSecondary, etc.
)
private val DarkColorScheme = darkColorScheme(
primary = Blue80,
secondary = DarkBlue80,
tertiary = Yellow80,
// error, primaryContainer, onSecondary, etc.
)
如上,定義 light 和 dark 兩種 scheme,然后參數(shù)傳遞給 MaterialTheme。
val darkTheme = isSystemInDarkTheme()
MaterialTheme(
colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme
) {
// M3 app content
}
Dynamic Color
Dynamic color 是 Material You 的最主要特色,在 Android12 及其后續(xù)設(shè)備可以通過設(shè)置 Dynamic ColoScheme 實(shí)現(xiàn)動(dòng)態(tài)顏色切換:
// Dynamic color is available on Android 12+
val dynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
val colorScheme = when {
dynamicColor && darkTheme -> dynamicDarkColorScheme(LocalContext.current)
dynamicColor && !darkTheme -> dynamicLightColorScheme(LocalContext.current)
darkTheme -> DarkColorScheme
else -> LightColorScheme
}

如上,當(dāng)應(yīng)用了 Dynamic ColorScheme 后,選擇紅色或者藍(lán)色墻紙后 App 的 UI 呈現(xiàn)對應(yīng)的主題顏色。
七、Android Studio
Android Studio Arctic Fox 正式版發(fā)布,Bumblebe 進(jìn)入 Beta 階段,而最新的 Canary 版本是 Chipmunk。這近幾個(gè)版本的迭代中 Android Studio 面向如何提高開發(fā)者的編碼和調(diào)試效率增加了一系列新功能。
Compose @review
最近的 Andorid Studio 版本中對 Compose 的預(yù)覽功能進(jìn)行了多項(xiàng)強(qiáng)化:像原生視圖那樣,支持對 Compose UI 進(jìn)行 3D 布局預(yù)覽;對于一些字面值變量的修改無需重新編譯即可實(shí)現(xiàn)預(yù)覽的實(shí)時(shí)更新:
新增 Preview Configuration 面板,對 @Preview 注解中的參數(shù)修改更加快捷;
Jank Detection
在 Performance Profile 中新增了 Frames 視圖,可以監(jiān)控每一幀的耗時(shí)情況,更好地調(diào)試和發(fā)現(xiàn) Jank 一類的問題。

此外,Android Studio 對模擬器進(jìn)行了不少強(qiáng)化,模擬器模擬更多真實(shí)設(shè)備的使用場景,例如重力感應(yīng)等。
八、AGP(Android Gradle Plugin)
Non-transitive R class
AGP 7.0 以來針對編譯速度的提升下了不少功夫,例如對 KSP 以及 Non-transitive R class 的支持。Non-transitive R class 通過顯示指定資源文件的完整包名,避免了 R 文件的隱式傳遞依賴、提升了編譯速度,AGP 配合新的 Androi Studio 可以對工程進(jìn)行 Non-transitive R class 的一鍵重構(gòu)。

Incremental Lint
AGP 7.0 引入 Lint 增量檢查,大幅提升了 Lint 的檢查速度。

Configuration cache
https://medium.com/androiddevelopers/configuration-caching-deep-dive-bcb304698070
AGP 通過 Gradle 配置緩存的開啟,可以顯著提升各種情況下的編譯速度。

在 Android Studio 的 gradle.properties 中增加一下配置即可啟動(dòng) Configuration Cache。
org.gradle.unsafe.configuration-cache=true
九、Summary
我們在本次 Android Dev Summit 中可以洞察到當(dāng)前 Android 技術(shù)的一些發(fā)展趨勢。
- 智能設(shè)備的多樣性要求 App 需要在屏幕適配上考慮更多;
- Jetpack Compose 在 UI 開發(fā)上的優(yōu)勢已經(jīng)逐漸凸顯;
- Flow 對 LiveData 以及 WorkManager 對 Service 替換的時(shí)機(jī)已經(jīng)成熟;
- ......
這些趨勢將為我們未來的學(xué)習(xí)以及技術(shù)選型指明方向。
最后
在這里還分享一份由大佬親自收錄整理的學(xué)習(xí)PDF+架構(gòu)視頻+面試文檔+源碼筆記,高級架構(gòu)技術(shù)進(jìn)階腦圖、Android開發(fā)面試專題資料,高級進(jìn)階架構(gòu)資料
這些都是我現(xiàn)在閑暇時(shí)還會(huì)反復(fù)翻閱的精品資料。里面對近幾年的大廠面試高頻知識(shí)點(diǎn)都有詳細(xì)的講解。相信可以有效地幫助大家掌握知識(shí)、理解原理,幫助大家在未來取得一份不錯(cuò)的答卷。
當(dāng)然,你也可以拿去查漏補(bǔ)缺,提升自身的競爭力。
真心希望可以幫助到大家,Android路漫漫,共勉!