展望2022:Android 开发最新技术动向

简介: 展望2022:Android 开发最新技术动向

每年9/10月份 Google 都会举行为期约2天的 Android Dev Summit,在活动上 Google 的技术专家们会分享一些 Android 领域的技术动向以及开发心得。

Android Dev Summit 2021: developer.android.com/events/dev-…

今年的活动在线上如期举行。今年的 Slogan 是 “Excellent apps,across devices” , 即使用 Jetpack 等 MAD Skill (Modern Android Development) 开发出更优秀的应用,并通过 Android 系统落地到更多种类的智能设备。本次活动围绕这一主旨做了 30 多场技术分享(视频),涉及多个方向:

  • Android 12
  • 12L
  • Building across screens
  • Kotlin
  • Jetpack
  • Jetpack Compose
  • Android Studio
  • AGP


Android 12


Material You

Android12 在10月进行了正式推送。Android12 的最大亮点就是基于 Material You 设计语言对原生系统 UI 进行了重新设计。 Material You 是 Material Design 的第3个版本,距离上一代 M2 已经过去了4年

image.png

跟上一代 M2 相比 M3 的元素面积更大、更便于用户点击;同时圆角的角度更大使得并排的元素之间的间隔更清晰。个性化是 M3 最大的特点,这也是 "You" 的命名来源。Android12 遵循了 M3 的 Dynamic Color 设计原则,系统可以从用户的壁纸中抓取颜色,然后色阶化应用到你开发的应用中,应用跟随主题的不同和变换颜色,千人千面。

Stretch OverScroll

developer.android.com/training/ge…

Android12 中加入了 Stretch OverScroll Effect ,相对于以前的水波纹效果,滚动反馈更加真实自然。开发者可以使用新增的 getDistance()onPullDistance() API 来控制 OverScoll 的强度,当然你也可以通过 XML 中设置 android:overScrollMode="never" 来屏蔽此效果。

image.png

App Splash Screen

developer.android.com/guide/topic…

Android12 增加了 Splash Screen API,可以在进入 App 主页之前自动插入开屏页,当然它的目的是为了让应用减少白屏的等待时间而非广告植入。Spash Screen 默认使用 App 的 Icon 作为开屏图案,开发者也可以使用系统提供的 API 自定义开屏图案甚至动画。如果在非 Android12 设备上也想使用Splash Screen功能,则可以使用 Jetpack 也提供了同名 SplashScreen 库,适配到了低至 Android 6(APP 23)的设备。需要注意,如果你的项目中通过 android:windowBackground 或者 CustomActivity 的方式自定义了开屏页,则需要进行适配,避免在 Android12 中出现两次开屏

Foreground service restrictions

developer.android.com/guide/compo…

Android8 出于隐私保护的考虑,禁止了 Service 的后台启动,本次 Android12 中的限制进一步加强,除了一些特殊情况外,Foreground Service 也不允许在后台启动,否则会抛出 ForegroundServiceStartNotAllowedException 异常。 Service 的存在越来越鸡肋,或将逐渐被 WorkManager 所替代

Compatibility Test

每一个新版本的 Android 系统升级都会带来不少 API 的行为变动,Android12 也不例外。为了确保你的 APP 在这些变动下行为正常,一般需要修改 targetSDKVersion 进行针对性的测试。 Android11 起提供了兼容性测试工具,在不重新编译 APK 的情况下可以针对变动的 API 进行测试、提高测试效率。

Developer options > App compatibility changes 中可以找到测试工具

image.png

12L (Android 12 Large Screens)


developer.android.com/about/versi…

近年来,搭载 Android 系统的大屏设备增长迅速,除了平板类产品以外又出现了折叠屏手机这一新兴门类,目前已经有超过250万部大屏幕设备上运行着 Android 系统。为提高大屏设备的使用体验。 Android12 即将推出一个专门为大屏优化的版本,命名 12L。12L 针对大屏设备和折叠屏对界面进行了优化,例如当屏幕宽度大于 600dp 时将默认显示两列内容、引入了类似 Chrome OS 的 Dock 栏等,同时支持拖拽分屏等功能,同时在不同窗口中启动多个应用

image.png

WindowManager

medium.com/androiddeve…

为应对更多种类屏幕的出现,Jetpack 提供了 WindowManager 库,便于 App 更好地适配不同屏幕的尺寸。多窗口模式下的 App 不能再依赖 Display.getRealMetrics() 获取窗口尺寸,当屏幕状态变化导致,OnConfigurationChanged 发生时,使用 WindowManager 的 WindowMetrics 获取准确的窗口尺寸,再根据 WindowSizeClass 以最合适的布局显示当前 UI。

image.png

Jetpack Compose 能更好地以响应式的方式处理 OnConfigurationChanged 时的 UI 变化,非常适合配合在 12L 的设备上使用。

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
}

本次活动中分享的不少新技术都第一时间适配了 Compose ,这也反映出 Android 将 Compose 作为首选的 UI 解决方案的决心。

Activity embedding

除了可以多窗口中打开多个应用,12L 还可以借助 XML 的配置或者调用 WindowManager 提供的 API 实现同一应用下多个 Activity 的并排显示。image.png

Building across screens


Android Ware

Compose 技术栈采用了分层设计的思想,只要替换局部组件就可以迁移到不同平台中使用,例如 WareOs 中只需要替换 Material 和 Navigation 的便可以实现穿戴设备 UI 的开发。

image.png

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 提供了两套车机系统 Android Auto 以及 Android Automotive OS。

  • Android Auto 提供了针对驾驶员优化的应用体验,用户在 Android Auto 上创建连接手机的服务,手机应用可以以更优化的界面显示在车机上。
  • Android Automotive OS 是一款基于 Android 的车载信息娱乐系统。车载系统是专为提升驾驶体验而优化的独立 Android 设备。相对于 Android Auto,它无需借助手机,用户可以将应用直接安装到车载系统上。

开发者可以跨平台的工程结构开发车机应用:

image.png

  • car_app_common 是共享部分
  • automotive_osandorid_auto 是两个 build target


Kotlin


Kotlin Flow

medium.com/androiddeve…

Kotlin方面,本次活动上重点推荐了 Kotlin Flow 在 MVVM 架构中的应用。基于 Jetpack 的 lifecycle-ktx 扩展库 Flow 可以转变为一个 lifeycle-aware 组件,较好地替代现有的 LiveData 的使用场景。

你可以只在 Model 层使用 Flow,在 View 层仍然使用 LiveData,通过 Flow.asLiveData 将 Flow 转换为 LiveData:

// import androidx.lifecycle.asLiveData
class MessagesViewModel(repository: MessageRepository) : ViewModel() {
     val userMessage = repository.userMessage.asLiveData()
     ...   
}

当然 View 层也可以直接使用 Flow,在 lifecycleScope.launch { }lifecycleScope.launchWheStart { } 中收集 Flow 的数据避免泄露,但是从性能出发更推荐使用 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)
                }
            }
        }
    }
} 

当 MessagesActivity 离开 STARTED 时,协程及时取消节省资源。

image.png

此外使用 stateIn 可以将 Flow 转化为一个 StateFlow 以热流的形式确保数据的下游共享。 活动期间有网友在直播中询问是否还有 Flow 无法取代 LiveData 的场景,官方的回答是 LiveData 除了 API 更简单以外(相应的功能也比较弱),已经完全可以被 Flow 替代。

KSP

android-developers.googleblog.com/2021/09/acc…

KSP (Kotlin Symbol Processing) 于9月份发布了 1.0 正式版。相比较于 KAPT 需要生成 Java Stub 后再基于 APT 处理注解的流程,KSP 底层基于基于 Kotlin Compiler Plugin ,省去了 Java Stub 的生成,编译速度可以提高2倍以上,未来在 Kotlin Multiplatform Project 中也可使用,如果你的项目代码已经迁移到 Kotlin,那么未来的注解处理应该首选 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 的配置非常简单,目前已经有包括 Room 在内的许多常见框架对 KSP 进行了支持,未来 Dagger,Hilt 等也将接入 KSP 以加速注解处理。


Jetpack


Room

medium.com/androiddeve…

10月份 Room 发布 2.4.0 Beta 01,主要新增了 Auto MigratioinsMulti-map Relations 两个新 Features,同时支持使用 KSP 进行注解处理。

当数据库表结构发生变化时,需要通过数据库迁移保证数据的不丢失,例如字段名变化之类的变更,需要手写 SQL 才能完成升级,而基于 Auto Migrations 可以检测出两个表结构的区别,完成自动升级。

 @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 进行外键关联,为了避免多写 SQL 需要单独额外定义 Relatioin Class,其实对于 SQL 的态度没必要谈虎色变,适当地活用 SQL 有助于更简单地定义一对多的实体关系。

//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>> 这样的数据结构使用起来也更简单

WorkManager

medium.com/androiddeve…

image.png

WorkManager 已经不单单是一个简单的异步任务处理框架,更是一整套强大的任务调度方案,可以有效替代 Service,更可靠地运行长时间的任务。最低可以向后兼容到 6.0,覆盖了市场绝多大数的机型。

WorkManager 2.6 支持 Multi-Process,借助 RemoteListenableWorker 或者 RemoteCoroutineWorker 可以将任务运行在任意指定进程,实现跨进程的监听;为应对 Android12 的 Foreground Service 的启动限制,WorkManager 2.7 新增了 setExpedited API,可以高优的立即启动相关任务,不受后台启动的约束。

val request = OneTimeWorkRequestBuilder<HighPriorityWorker>()       
   .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)   
   .build() WorkManager.getInstance(context).enqueue(request)

由于 CoroutineWorker.setForeground()ListenableWorker.setForegroundAsync() 方法由 Foreground Service 提供支持,在一些禁止后台启动的场景中一旦被调用,会发生 ForegroundServiceStartNotAllowedException 异常,这是在开发中需要特别注意的。

More Components

此外,Jetpack 的其他一些库近期也都有新版本的发布。Navigation 2.4.0 beta 增加了多栈返回的支持,不同 NavHostFragment 的返回栈可以各自管理;DataStore 发布 1.0 可以更安全地替代 SharedPreferences 的使用;CameraX 1.1.0-alpha10 增加了 VideoCapture 视频截图和曝光补偿等实用功能; Benchmark 1.1.0-alpha11 增加了 Frame Timing,性能测试更加精准,并向后兼容到 API 23。


Jetpack Compose


Compose 新增 androidx.compose.material3 库,支持开发 Material You 主题风格的 UI。

Material3

Compose.M3 通过 ColorScheme 来自定义配色方案,支持了 Material You 的 color scheme 设计规范。

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,然后参数传递给 MaterialTheme

val darkTheme = isSystemInDarkTheme()
MaterialTheme(
    colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme
) {
    // M3 app content
}

Dynamic Color

Dynamic color 是 Material You 的最主要特色,在 Android12 及其后续设备可以通过设置 Dynamic ColoScheme 实现动态颜色切换:

// 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
}

image.png

如上,当应用了 Dynamic ColorScheme 后,选择红色或者蓝色墙纸后 App 的 UI 呈现对应的主题颜色


Android Studio


  • Android Studio Arctic Fox 正式版发布
  • Ancroid Studio Bumblebe 进入 Beta 阶段
  • 而最新的 Canary 版本是 Chipmunk。

这近几个版本的迭代中 Android Studio 面向如何提高开发者的编码和调试效率增加了一系列新功能。

Compose @preview

最近的 Andorid Studio 版本中对 Compose 的预览功能进行了多项强化:像原生视图那样,支持对 Compose UI 进行 3D 布局预览;对于一些字面值变量的修改无需重新编译即可实现预览的实时更新:

image.png

新增 Preview Configuration 面板,对 @Preview 注解中的参数修改更加快捷;

image.png

Jank Detection

在 Performance Profile 中新增了 Frames 视图,可以监控每一帧的耗时情况,更好地调试和发现 Jank 一类的问题。

image.png

此外,Android Studio 对模拟器进行了不少强化,模拟器模拟更多真实设备的使用场景,例如重力感应等。


AGP(Android Gradle Plugin)


Non-transitive R class

AGP 7.0 以来针对编译速度的提升下了不少功夫,例如对 KSP 以及 Non-transitive R class 的支持。 Non-transitive R class 通过显示指定资源文件的完整包名,避免了 R 文件的隐式传递依赖、提升了编译速度,AGP 配合新的 Androi Studio 可以对工程进行 Non-transitive R class 的一键重构

image.png

Incremental Lint

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

image.png

Configuration cache

medium.com/androiddeve…

AGP 通过 Gradle 配置缓存的开启,可以显著提升各种情况下的编译速度

image.png

在 Android Studio 的 gradle.properties 中增加一下配置即可启动 Configuration Cache

org.gradle.unsafe.configuration-cache=true

Summary


Android Dev Summit 的分享主题涉及了 Android 领域的方方面面,开发者无需了解,更重要的是从这些分享中洞察到未来的技术的发展趋势,比如未来的 App 可能需要适配更多而屏幕尺寸、Jetpack Compose 在 UI 开发上的先进性正逐渐凸显;Kotlin Flow 对 LiveData 以及 WorkManager 对 Service 的替代趋势也逐渐清晰。。

目录
相关文章
|
18天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
12 0
|
1月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
92 0
|
1月前
|
设计模式 人工智能 开发工具
安卓应用开发:构建未来移动体验
【2月更文挑战第17天】 随着智能手机的普及和移动互联网技术的不断进步,安卓应用开发已成为一个热门领域。本文将深入探讨安卓平台的应用开发流程、关键技术以及未来发展趋势。通过分析安卓系统的架构、开发工具和框架,本文旨在为开发者提供全面的技术指导,帮助他们构建高效、创新的移动应用,以满足不断变化的市场需求。
18 1
|
9天前
|
XML 开发工具 Android开发
构建高效的安卓应用:使用Jetpack Compose优化UI开发
【4月更文挑战第7天】 随着Android开发不断进化,开发者面临着提高应用性能与简化UI构建流程的双重挑战。本文将探讨如何使用Jetpack Compose这一现代UI工具包来优化安卓应用的开发流程,并提升用户界面的流畅性与一致性。通过介绍Jetpack Compose的核心概念、与传统方法的区别以及实际集成步骤,我们旨在提供一种高效且可靠的解决方案,以帮助开发者构建响应迅速且用户体验优良的安卓应用。
|
18天前
|
Android开发
Android开发小技巧:怎样在 textview 前面加上一个小图标。
Android开发小技巧:怎样在 textview 前面加上一个小图标。
10 0
|
18天前
|
Android开发
Android 开发 pickerview 自定义选择器
Android 开发 pickerview 自定义选择器
10 0
|
25天前
|
Java Android开发
Android开发系列全套课程
本系列课程面向有java基础,想进入企业从事android开发的计算机专业者。学习搭配实战案例,高效掌握岗位知识。
17 1
|
26天前
|
数据可视化 测试技术 Android开发
安卓应用开发:打造高效用户界面的五大技巧
【2月更文挑战第30天】在竞争激烈的应用市场中,一个流畅且直观的用户界面(UI)对于安卓应用的成功至关重要。本文将探讨五个关键的UI设计技巧,这些技巧旨在提升用户体验并优化性能。我们将深入分析布局优化、资源管理、动画效果、响应式设计和测试流程等方面,并提供实用的代码示例和最佳实践,帮助开发者构建既美观又高效的安卓应用。
|
27天前
|
监控 算法 Android开发
安卓应用开发中的内存优化策略
【2月更文挑战第30天】随着移动设备性能的不断提升,用户对应用程序的体验要求越来越高。在安卓应用开发中,内存管理是影响应用性能和用户体验的关键因素之一。本文将探讨针对安卓平台的内存优化技巧,包括避免内存泄漏、合理使用数据结构和算法、优化图片资源处理等策略,旨在帮助开发者提升应用性能和稳定性。
19 1
|
27天前
|
编解码 测试技术 Android开发
安卓应用开发:构建高效用户界面的实用指南
【2月更文挑战第29天】在移动应用开发的世界中,创建一个流畅、直观且响应迅速的用户界面(UI)对于吸引和保持用户至关重要。本篇文章旨在向安卓开发者展示如何通过优化布局设计、使用现代UI框架以及利用Android Studio提供的工具来构建高效的用户界面。我们将深入探讨如何减少内存消耗、提升渲染性能,并确保应用在不同设备和屏幕尺寸上的兼容性。跟随本文的指导,你将能够提高应用的整体用户体验,从而在竞争激烈的市场中脱颖而出。

相关实验场景

更多