Google I/O 又画饼了,Android 开发者怎么看
「Google I/O 又画饼了,Android 开发者怎么看」
每年五月的 Google I/O 大会,对 Android 开发者来说越来越像一场固定节目:凌晨爬起来看直播,截图发群聊,第二天技术媒体铺天盖地的"重磅更新"通稿,然后——就没有然后了。今年 I/O 2024 刚结束,我翻完所有 session 和官方博客之后的感受特别复杂,有些话不吐不快。
Gemini 全面入侵:Android 还是操作系统吗?
Google 今年把 Gemini 塞进了 Android 的每一个缝隙里,这个架势让我想起了 2016 年强行推 Google Assistant 的时候。当时 Assistant 独占 Home 键长按,现在 Gemini 直接替换了 Google Assistant 的品牌,甚至在 Android 15 的底层架构里预留了 AI 模型的常驻内存区域。
具体看代码层面的改动,AOSP 的 frameworks/base 里新增了 android.app.gemini 包名下的多个系统服务。GeminiService 以 system_server 权限运行,通过 AIDL 接口向第三方应用暴露 generateContent() 和 startChatSession() 等方法。这意味着什么?你的应用调用 Gemini API 不再需要走网络请求到 generativelanguage.googleapis.com,而是直接跟系统服务通信,延迟从几百毫秒降到几十毫秒。
| 听起来很美好对吧?但权限模型极其粗暴。`AndroidManifest.xml` 里需要声明 `android.permission.ACCESS_GEMINI_SERVICE`,而这个权限的 `protectionLevel` 是 `signature | privileged`。翻译成人话:只有系统签名应用和预装在 `/system/priv-app` 目录下的应用才能直接调用。普通应用?请继续走云端 API,按 token 付费。 |
|---|
这造成了一个我很难接受的分层。YouTube、Gmail、Google Photos 这些亲儿子应用可以享受零延迟、零成本的本地 AI 推理,而第三方开发者要么忍受网络延迟和配额限制,要么——Google 的文档里"贴心地"建议你"考虑与 OEM 合作预装应用"。这算什么开放生态?
更讽刺的是硬件门槛。Gemini Nano 模型要求设备至少有 8GB RAM,且 SoC 需要支持 INT4 量化推理。目前只有 Pixel 8 系列和少数搭载骁龙 8 Gen 3 的机型满足条件。我手边一台 Pixel 7 Pro,8GB RAM 够数,但 Tensor G2 的 NPU 不支持 INT4,结果被判定为"不支持 Gemini Nano"。Google 的文档里对此的解释是"为了最佳用户体验",实际上这就是逼你换机。
Android 15 的"隐私保护":谁在受益?
每年大版本更新,隐私和安全都是标准话术。Android 15 这次主推的 Privacy Sandbox on Android,把 Topics API、Protected Audience API 和 Attribution Reporting API 打包推进,名义上是替代第三方 Cookie 和广告 ID 的隐私方案。
我仔细读了 android.adservices 的实现代码,这个模块在系统里以独立 APK 形式存在,包名 com.google.android.adservices,拥有 android.permission.ACCESS_ADSERVICES_MANAGER 这个系统级权限。它的工作方式是:应用调用 AdServicesManager.getTopics(),系统返回一个基于过去三周浏览历史推断的兴趣主题列表,比如 /Sports/Running 或 /Finance/Investing。
问题在于这个推断过程完全黑箱。Topics 的分类体系是 Google 维护的,目前大约 469 个主题,更新频率和具体映射规则不公开。你的应用请求了 READ_TOPICS 权限,但拿到的是 Google 定义好的标签,不是原始数据。这对广告商来说意味着投放效率下降,对用户来说意味着"隐私保护"实际上是 Google 垄断了数据解释权,对开发者来说意味着又要适配一套只有 Google 能 fully control 的 API。
更隐蔽的是 SdkSandbox 机制。广告 SDK 现在必须运行在独立的沙箱进程中,通过 SdkSandboxManager 加载。技术上这确实隔离了恶意 SDK 的权限,但实现成本全转嫁给开发者。我尝试把 Mintegral 的 SDK 迁移到沙箱模式,结果初始化时间从 200ms 增加到 1.2s,因为每次调用都需要跨进程 Binder 通信。Google 的文档建议"预加载 SDK 到沙箱",但沙箱进程在应用后台超过 5 分钟后会被系统杀死,下次启动重新加载。这个 5 分钟的阈值写死在 SdkSandboxService.java 的 IDLE_TIMEOUT_MS 常量里,没有 API 可以调整。
Jetpack Compose 的"稳定"幻觉
I/O 上 Compose 的相关 session 数量比去年少了将近一半,但 Google 官方的说法是"Compose 已经进入成熟稳定期"。我对这个"稳定"要打个大问号。
Compose Compiler 1.5.10 配合 Kotlin 2.0.0 的兼容性,在实际项目里踩了不止一个坑。最典型的是 remember 和 derivedStateOf 在特定重组场景下的行为变化。Kotlin 2.0 引入了新的 IR 生成策略,导致 Compose Compiler 生成的 $composer.startRestartGroup() 调用位置与 1.9 时代有细微差异。这个差异在嵌套 LazyColumn + animateItemPlacement 的场景下会触发 IllegalStateException: Already started,堆栈指向 Composer.kt 的 第 3847 行。
我在 Compose 的 GitHub issue tracker 里找到了 #434 和 #512 两个相关 issue,Google 工程师的回复是"已知问题,将在 1.5.11 修复"。但 1.5.11 的发布日期从四月推迟到五月,又推迟到"与 Android Studio Koala 同步发布"。这种节奏对生产环境维护来说太难受了。
Compose Multiplatform 的情况更微妙。I/O 上完全没提这个框架,尽管 1.6.0 刚发布不久。我怀疑 Google 内部对 CMP 的定位有分歧——JetBrains 主导开发,Google 提供"技术指导",但 I/O 这种自家舞台都不给曝光,很难让人相信资源投入优先级有多高。实际用 CMP 做过跨平台项目的开发者都知道,iOS 端的 UIKitInterop 在复杂手势嵌套时还有内存泄漏,CFRelease 调用时机不对导致 UIViewController 无法释放的问题在 1.6.0 里依然存在,issue #4182 挂了三个月没动静。
Kotlin/Wasm:真的 ready 了吗?
I/O 上 Kotlin 团队高调展示了 Kotlin/Wasm 的进展,演示了一个 Compose 应用编译成 WebAssembly 在浏览器运行。现场掌声很热烈,但我注意到演示用的是 Chrome Canary 125,而且明确标注了"需要启用实验性标志"。
具体技术限制方面,Kotlin/Wasm 目前依赖 Wasm GC 提案,这个提案在 Chrome 119、Firefox 120、Safari 17.4 才获得支持。更麻烦的是垃圾回收的实现方式:Kotlin/Wasm 使用 Wasm 的 struct 类型和 anyref 体系,与 JavaScript 的互操作需要通过 js-interop 层的 JsAny 包装。每次跨边界调用都有额外的装箱开销,我在本地测了一个简单的 List<Int> 传递,序列化反序列化耗时是纯 JS 实现的 8 倍。
Google 把 Kotlin/Wasm 包装成"Web 开发的未来",但现阶段连基础的 DOM API 覆盖都不完整。kotlinx.browser 库里 document.createElement 有,document.querySelectorAll 没有,CSS 动画支持为零。这意味着你要用 Kotlin/Wasm 做 Web 应用,要么自己写 JS 胶水代码,要么等 JetBrains 慢慢补 API。这种"未来技术"的叙事,和当年 Flutter Web 的套路如出一辙。
Wear OS 5 的"电池优化":老用户的噩梦
Wear OS 5 跟着 I/O 发布,Google 强调"续航提升最多 20%"。我下载了模拟器镜像分析电源管理策略,发现这个提升主要来自更激进的后台限制。
WearPowerManagerService 里新增了一个 BACKGROUND_RESTRICTION_LEVEL_WEAR 常量,值为 3,对应 RESTRICT_BACKGROUND_FULLY。应用在后台超过 10 分钟就会被切断网络访问,AlarmManager 的精确闹钟被强制改为不精确,JobScheduler 的最小间隔从 15 分钟拉长到 1 小时。这些策略对系统应用和 Google 自有服务有白名单,第三方应用不在其中。
我的 Wear OS 应用用了 WorkManager 做周期性健康数据同步,在 Wear OS 4 上每 15 分钟跑一次,到 Wear OS 5 上变成每小时一次,用户投诉数据延迟。Google 的迁移指南建议"使用 Data Layer API 触发手机端同步",但这要求用户手机必须安装配套应用且保持蓝牙连接,覆盖率直接腰斩。
更离谱的是表盘开发。Wear OS 5 强制要求表盘使用新版的 WatchFaceService API,旧版 CanvasWatchFaceService 被标记 deprecated,但在 Wear OS 4 设备上仍然大量存在。这意味着开发者要维护两套表盘实现,或者放弃旧设备用户。Google Play 的表盘分类里,支持 Wear OS 5 的新表盘数量在发布后两周内增长了 300%——不是因为开发者积极适配,而是因为旧表盘被系统标记为"不兼容"下架了。
开发工具链:Android Studio Koala 的半成品感
| I/O 同步发布的 Android Studio Koala | 2024.1.1,版本号跳得很快,功能完成度却没跟上。 |
|---|
最影响日常体验的是 Compose Preview 的稳定性。Koala 引入了"Live Edit for Compose"的正式版,号称支持状态持久化。实际使用中,我在一个包含 ViewModel 和 Hilt 注入的屏幕里修改了一个 Text 组件的 fontSize,Live Edit 触发后整个 Preview 面板白屏,log 里抛出 IllegalStateException: Hilt ViewModel must be created by HiltViewModelFactory。这个问题在 Bumblebee 时代就存在,Koala 没修,只是加了条 known issue 说明:"Live Edit 目前不支持依赖注入框架"。
Gemini 在 Android Studio 里的集成倒是推进很快。tools.ai.codeGeneration 模块默认启用,快捷键 Ctrl+Shift+G 唤起"Gemini in Android Studio"。我试了几个场景:生成 RecyclerView Adapter 代码,结果用了已经 deprecated 的 kotlinx.android.synthetic;解释一个 crash 堆栈,把 NullPointerException 归因于"可能的线程安全问题",实际上原因是 lateinit 属性在 onCreateView 之前被访问。这种"AI 辅助"的质量,放在生产环境里就是埋雷。
Koala 的 build 速度相比 Jellyfish 没有明显改进。我的中型项目(约 15 个模块,8 万行 Kotlin)clean build 时间从 2 分 18 秒变成 2 分 12 秒,增量编译在修改公共模块的接口后仍然触发全量重编译。Gradle 的 configuration cache 在 Koala 默认开启,但遇到 buildSrc 里的自定义 plugin 就会失效,提示 "configuration cache is incompatible with buildSrc changes"。这个限制从 Gradle 7.0 存在到现在,Google 和 Gradle 团队互相踢皮球。
生态位挤压:Google 正在重新定义"Android 开发者"
把以上这些碎片拼起来看,Google 对 Android 生态的掌控策略越来越清晰。不是通过开源社区的民主协商,而是通过技术架构的层级设计,把利益往自己的服务收敛。
Gemini 的本地特权、Privacy Sandbox 的数据中介地位、Wear OS 的后台白名单、Kotlin/Wasm 的 Chrome 依赖——这些看似独立的技术决策,共同指向一个结构:Google 服务运行在系统层,第三方应用运行在用户层,中间通过 Google 控制的 API 网关通信。Android 越来越不像一个开放的操作系统平台,而像 Google 服务的运行时容器。
这对开发者的直接影响是职业技能的贬值曲线在加速。五年前精通 RecyclerView 优化和自定义 View 的工程师现在面临 Compose 的范式转换,三年前投入 Flutter 的团队发现 Google 的注意力在转移,去年 All in Kotlin Multiplatform 的开发者看着 I/O 的冷遇心里发虚。技术栈的半衰期在缩短,而每次转换的沉没成本在增加。
我并非反对技术演进。Jetpack Compose 的声明式 UI 确实比 View 体系更合理,Kotlin 协程比 AsyncTask 优雅得多。但演进的方向和节奏应该由实际工程需求驱动,而不是由 Google 的季度财报和股价叙事驱动。Gemini 在 Android 里的渗透深度,与终端用户的真实需求匹配度有多高?Privacy Sandbox 的复杂架构,对比直接限制广告跟踪的简单粗暴方案,收益是否值得全社会的开发成本?这些问题在 I/O 的舞台上不会被追问,因为答案可能不符合演讲稿的走向。
一个老开发者的困惑
我入行 Android 开发是在 2012 年,Eclipse + ADT 的时代,Fragment 还是新概念,Support Library 的版本号是个位数。那时候 Google I/O 发布的东西是真的能改变工作方式的:ActionBarSherlock 让兼容性开发有章可循,Volley 虽然后来被 Retrofit 取代但确实解决了当时的网络请求痛点,Material Design 的设计语言统一了整个生态的视觉认知。
现在的 I/O 更像产品发布会,技术深度让位于演示效果。Gemini 生成一段代码的动画在 keynote 上播放 30 秒,台下欢呼,但没人告诉你这段代码依赖的 API 还没进入 Beta 通道。Wear OS 的续航数字印在 PPT 上,脚注里的小字说"基于实验室环境,实际使用可能不同"。
这种落差让我怀疑,Google 的 Android 团队是否还把自己当作开发者平台的建设者,还是已经彻底转型为 Google 服务的部署渠道。如果是后者,"Android 开发者"这个身份的定义权,实际上已经不在开发者自己手里了。
Android 15 的 Beta 3 上周推送了,我更新了测试机,打开设置里的开发者选项,发现"OEM 解锁"的开关位置又换了。这个每年移动一次的小细节,像是个隐喻——规则在持续变化,而你只能跟着适应,没有协商的余地。
下次 I/O 你还打算凌晨爬起来看直播吗?