查看原文
其他

2024 Google I/O Android 相关内容

鸿洋
2024-08-24

The following article is from GSYTech Author 恋猫de小郭

本次 Google I/O 的核心虽然是 AI ,但是 Android 也是作为主要议题出现, Android 部分可以简单分为产品和开发相关内容,接下来主要介绍这两部分的相关更新。

重点开始开发相关,内容不少

产品

Gemini

Android 端的 Gemini 将升级支持,让 Gemini 可以更好地理解屏幕上的内容,帮助用户分析工作、生活数据,从而提供更有用的建议。

另外用户目前将 Gemini 设为默认辅助工具之后,还能总结或回答有关网页或截图的问题,判断屏幕上是否有视频,并根据你提出相关问题,Gemini 会基于视频的字幕来寻找答案,另外还支持分析 PDF 文件等等。

谷歌预告推出安卓 15 Beta 2 更新

AI 检测诈骗电话

对于在通话中提醒可能存在的诈骗行为,使用 Gemini Nano 在通话过程中去检测到诈骗相关的对话模式时,会提供实时警报,例如,如果 “银行代表” 要求紧急转账、使用礼品卡付款或要求提供卡 PIN 码或密码等个人信息,用户就会收到提醒,这种保护全部发生在设备上,因此用户的对话也会是私密的。

谷歌开源安卓版 Gameface

谷歌开源了 https://github.com/google/project-gameface ,它是支持用户通过表情控制光标,目前支持 Window 和 Android 平台,可以在游戏中控制鼠标光标,目标用户是选择使用面部控制和头部运动进行游戏的人。

开发

Android Studio

在本次 I/O 之前 Android Studio 就发布了Jellyfish | 2023.3.1  正式版,里面就着重介绍了 Gemini AI 的能力,本次 I/O 发布了 Android Studio Koala | 2024.1.1 Beta 1 ,现在你可以在 Android Studio Koala 中使用 Gemini 提供自定义提示以生成代码建议,可以通过 View > Tool Windows > Gemini 启用后,右键通过 Gemini > Transform selected code 查看提示字段。

另外 Gemini 还会提供关于崩溃报告的建议,还提供了模板 Gemini API 的集成支持等等。

目前在 Android Studio 中的 Gemini 预览阶段,暂时向所有用户免费提供 Gemini 1.0 Pro ,Gemini 1.5 Pro 型号将于今年晚些时候登陆 Android Studio。

另外相关支持还有:

  • Android 远程流媒体设备支持,可以连接到 Google 数据中心托管的远程物理 Android 设备

  • Android Studio Koala Feature Drop 现在可以轻松区分低性能 USB 和高性能 USB

  • Android Studio Profiler 改进

  • Glance 预览,Android Studio Koala Feature Drop 可以直接在 IDE 中预览 Jetpack Compose Glance (1.1.0-rc01)

  • 默认启用 Compose 实时编辑,Android Studio Koala 下实时编辑默认在手动模式下启用,并提高了稳定性和更强大的更改检测,包括对导入语句的支持。


  • Compose 预览屏幕截图测试插件,Compose 预览屏幕截图测试插件的第一个 alpha 版本作为单独的插件提供,可与 AGP 8.5.0-beta01 或更高版本一起使用

更多详细可见:https://android-developers.googleblog.com/2024/05/google-io-2024-whats-new-in-android-development-tools.html

Kotlin Multiplatform

Kotlin Multiplatform 由 JetBrains 开发,通过将 Kotlin 编译为平台原生二进制文件,提供了一种跨平台共享代码的新颖方法

核心:Kotlin Multiplatform 的是 JetBrains 主导,Android 提供支持。

目前许多库都提供对 Kotlin Multiplatform 的内置支持,从而简化跨平台开发体验,例如:

  • Ktor 通过处理 REST 服务消耗来简化网络任务,
  • kotlinx.serialization 将数据转换为 JSON 等格式
  • Okio 管理基本的文件 I/O
  • SKIE 适配了类型和协程在 iOS 上的使用
  • CocoaPods 集成支持使用 iOS 特定的依赖项

谷歌与 JetBrains 和 Kotlin 开发者社区合作,为许多 Jetpack 库添加了 Kotlin 多平台支持,并在某些情况下提供 iOS 平台目标,而在其他情况下,JetBrains 和社区提供多平台发行版。

如今,Annotations、Collections 和 DataStore 库都在稳定版本中支持 Kotlin Multiplatform,另外还添加了对验证 iOS 平台目标的二进制兼容性的支持,使其与 Android 的标准保持一致。

除了上面的库之外,目前还在致力于为 Room、 Lifecycle 和 ViewModels 提供 Kotlin 多平台支持,并且现已提供 alpha 版本。

可以说 Kotlin Multiplatform 持续投入的力度还是不错的。

Android 与 JetBrains 合作开发的 Kotlin 编译器,提高了 Kotlin/Native(适用于 iOS 和桌面操作系统)的运行时性能,编译器基准测试显示运行时性能提高了 18%,此外,Android 团队还为 Kotlin Native 编译器的构建时间性能提升做出了贡献,速度提升了 2 倍。

最后 Android Gradle 插件现在正式支持 Kotlin Multiplatform,可以使用简洁的构建定义将 Android 设置为共享代码的平台目标,如下所示:

plugins {
    id("org.jetbrains.kotlin.multiplatform")
    id("com.android.library")
}

kotlin {
    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "11"
            }
        }
    }  
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "Shared"
            isStatic = true
        }
    }    
    sourceSets {
        commonMain.dependencies {
            // put your Multiplatform dependencies here
        }
    }

Android 官方也 Github 上了一个 Samples 仓库,使用 Kotlin Multiplatform Room、DataStore 和 Ktor 库来获取、存储和显示数据:https://github.com/android/kotlin-multiplatform-samples

更多可见:https://android-developers.googleblog.com/2024/05/android-support-for-kotlin-multiplatform-to-share-business-logic-across-mobile-web-server-desktop.html

Compose Preview Screenshot Testing

上面介绍 Android Studio Koala 的时候就提到了 Compose 预览屏幕截图测试插件,屏幕截图测试是一种自动化测试,它会截取一段 UI 的屏幕截图,然后将其与之前批准的参考图像进行比较,如果图像不匹配,测试就会失败,并生成 HTML 报告来帮助比较并找出差异。

更多可见:https://developer.android.com/studio/preview/compose-screenshot-testing

Jetpack Compose 的新增功能

共享元素转换

现在 Modifier.sharedElement() 和 Modifier.sharedBounds() 已添加到 Compose 支持中,它们支持在屏幕之间创建漂亮的过渡,并且比视图系统支持更精细的控制。

将 AnimatedContent composables 嵌套在 SharedTransitionLayout 中,然后将 Modifier.sharedElement()或 Modifier.sharedBounds() 添加到想要在屏幕之间共享的内容上 然后 Compose 会将找到具有匹配键的 composables ,并在它们之间平滑过渡。

var showDetails by remember {
    mutableStateOf(false)
}
SharedTransitionLayout {
    AnimatedContent(
        showDetails,
        label = "basic_transition"
    ) { targetState ->
        if (!targetState) {
            MainContent(
                onShowDetails = {
                    showDetails = true
                },
                animatedVisibilityScope = this@AnimatedContent,
                sharedTransitionScope = this@SharedTransitionLayout
            )
        } else {
            DetailsContent(
                onBack = {
                    showDetails = false
                },
                animatedVisibilityScope = this@AnimatedContent,
                sharedTransitionScope = this@SharedTransitionLayout
            )
        }
    }
}

另外,Android 15 中的导航和预测性返回动画,也可以与共享元素过渡顺利配合,更多可见:https://developer.android.com/develop/ui/compose/animation/shared-elements

惰性列表项动画

Lazy row 和 column 现在能够自动对项目的插入、删除和重新排序进行动画处理,你只需将Modifier.animateItem() 添加到列表里,操作的更改就会自动呈现动画,另外还可以通过提供不同的动画规范来自定义动画。

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier

var list by remember { mutableStateOf(listOf("A""B""C")) }
Column {
    Button(onClick = { list = list + "D" }) {
        Text("Add new item")
    }
    Button(onClick = { list = list.shuffled() }) {
        Text("Shuffle")
    }
    LazyColumn {
        items(list, key = { it }) {
            Text("Item $it", Modifier.animateItem())
        }
    }
}

更多可见:https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyItemScope#(androidx.compose.ui.Modifier).animateItem(androidx.compose.animation.core.FiniteAnimationSpec,androidx.compose.animation.core.FiniteAnimationSpec,androidx.compose.animation.core.FiniteAnimationSpec)

Text

Text 现在通过新的 AnnotatedString.fromHtml() 扩展支持内联链接和基本 HTML 格式,这会转换基本的 HTML 格式,包括指向 AnnotatedString 的链接,然后由 Compose 展示。

// First, download a string as a plain text using one of the resources' methods. At this stage
// you will be handling plurals and formatted strings in needed. Moreover, the string will be
// resolved with respect to the current locale and available translations.
val string = stringResource(id = R.string.example)

// Next, convert a string marked with HTML tags into AnnotatedString to be displayed by Text
val styledAnnotatedString = AnnotatedString.fromHtml(htmlString = string)

BasicText(styledAnnotatedString)

BasicTextField 配合 TextFieldState 的 overload,可以做到支持键盘 gif 等丰富内容,并且还可以从组件中提升并异步更新。

// Demonstrates how to use the decorator API on BasicTextField
val state = rememberTextFieldState("Hello, World!")
BasicTextField(
    state = state,
    decorator = { innerTextField ->
        // Because the decorator is used, the whole Row gets the same behaviour as the internal
        // input field would have otherwise. For example, there is no need to add a
        // `Modifier.clickable` to the Row anymore to bring the text field into focus when user
        // taps on a larger text field area which includes paddings and the icon areas.
        Row(
            Modifier
                .background(Color.LightGray, RoundedCornerShape(percent = 30))
                .padding(16.dp)
        ) {
            Icon(Icons.Default.MailOutline, contentDescription = "Mail Icon")
            Spacer(Modifier.width(16.dp))
            innerTextField()
        }
    }
)

注意:Material TextField 将在后续版本中更新为使用新的 BasicTextField,更多可见https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/package-summary#BasicTextField(androidx.compose.foundation.text.input.TextFieldState,androidx.compose.ui.Modifier,kotlin.Boolean,kotlin.Boolean,androidx.compose.foundation.text.input.InputTransformation,androidx.compose.ui.text.TextStyle,androidx.compose.foundation.text.KeyboardOptions,androidx.compose.foundation.text.input.KeyboardActionHandler,androidx.compose.foundation.text.input.TextFieldLineLimits,kotlin.Function2,androidx.compose.foundation.interaction.MutableInteractionSource,androidx.compose.ui.graphics.Brush,androidx.compose.foundation.text.input.OutputTransformation,androidx.compose.foundation.text.input.TextFieldDecorator,androidx.compose.foundation.ScrollState)

Contextual Flow Layouts

ContextualFlowRow 和 ContextualFlowColumn 适合惰性流布局,给定最大行数,流布局将组成尽可能多的适合的项目,然后为开发者提供渲染内容的上下文,有了这个上下文,就可以渲染一个自定义展开指示器,显示剩余项目的计数。

@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun SuggestedSnacks(
   snacks: List<Snack>,
   onSnackClick: (Snack) -> Unit,
   modifier: Modifier = Modifier
)
 {
   var maxLines by remember { mutableIntStateOf(1) }
   ContextualFlowRow(
       maxLines = maxLines,
       overflow = ContextualFlowRowOverflow.expandIndicator {
           val remainingItems = totalItemCount - shownItemCount
           MyOverflowIndicator(
               remainingItems = remainingItems,
               modifier = Modifier
                   .clickable {
                       // Expand the max lines on click
                       maxLines += 1
                   }
           )
       },
       itemCount = snacks.size
   ) { index ->
       val snack = snacks[index]
       SnackItem(snack, onSnackClick)
   }
}

性能改进

与 1 月份的版本相比, Jetsnack 的首次像素基准测试时间缩短了 17%,下图显示了 Jetsnack 在每个 Compose 版本中的改进,自 2023 年 8 月版本以来, Jetsnack 首次绘制像素的时间几乎减少了一半:

Indication API 已被重写,从而支持延迟创建 ripples,这对于滚动性能非常重要,对于大多数应用来说应该不需要进行任何更改,但如果你有自定义 Indication ,升级可能会带来重大更改。

更多可见 :https://developer.android.com/develop/ui/compose/touch-input/user-interactions/migrate-indication-ripple?hl=zh-cn

Strong skipping mode

Strong skipping mode 现在正式投入生产,在即将发布的 2.0.20 编译器版本将默认启用此功能。

Strong skipping mode 允许跳过具有不稳定参数的可组合项,从而简化了 composable 的 skipped,这意味着会有更多的 composable 将自动跳过,从而减少手动将类注释为稳定的需要。

Now In Android 示例在启用 Strong skipping mode 时,主屏幕重组时间缩短了 20%,更多可见:https://developer.android.com/develop/ui/compose/performance/stability/strongskipping?hl=zh-cn

Compose 编译器移至 Kotlin 存储库

Compose 编译器将从 Kotlin 2.0 开始托管在 Kotlin 存储库中,这意味着开发者不再需要等待匹配的 Compose 编译器发布来升级的 Kotlin 版本。

Compose adaptive layouts

使用 Compose adaptive layouts 构建全新的自适应布局,让 App 设计适应手机之外的应用,包括Compose for TV 和 Compose for Wear OS ,详细可见:https://developer.android.com/develop/ui/compose/layouts/adaptive


Navigation Compose 类型安全

从 Jetpack Navigation 2.8.0-alpha08 开始,导航组件具有基于 Kotlin 序列化的完整类型安全支持,可以用于在使用 Kotlin DSL 时定义导航图,旨在与 Navigation Compose 等集成完美配合。

现在,可以将导航目的地和参数定义为可序列化对象,将导航目的地和参数定义为可序列化对象。

// Define a home destination that doesn't take any arguments
@Serializable
object Home

// Define a profile destination that takes an ID
@Serializable
data class Profile(val id: String)
NavHost(navController, startDestination = Home) {
    composable<Home> {
        HomeScreen(onNavigateToProfile = { id ->
            navController.navigate(Profile(id))
        })
     }
     composable<Profile> { backStackEntry ->
         val profile: Profile = backStackEntry.toRoute()
         ProfileScreen(profile)
     }
}

CameraX 合成

针对 Compose 将会有一个特定的 CameraX 库,称为 camera-viewfinder-compose,在第一个 alpha 版本中,可以使用新的取景器在屏幕上显示相机预览,无论调整窗口大小、展开设备还是更改显示或方向,该预览始终显示正确的宽高比和旋转。

它还可以正确处理相机和 surface 的生命周期,还支持在相机坐标系中进行复杂的交互,这样可以让开发者轻松实现点击对焦或捏合缩放等手势。


最后推荐一下我做的网站,玩Android: wanandroid.com ,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!


推荐阅读

Apk安装之谜

Android 描边动画实现母亲节祝福效果

那么多的ViewModel创建方式都有何不同?


扫一扫 关注我的公众号

如果你想要跟大家分享你的文章,欢迎投稿~


┏(^0^)┛明天见!

继续滑动看下一个
鸿洋
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存