android 15适配

2026-09-03 17:00:00

新系统又来搞事情了!每次安卓大版本更迭,做客户端的小伙伴估计都要脱一层皮 😵‍💫。虽然官方文档堆成了山,但真正落实到项目里,坑往往藏在那些看似不起眼的改动里。

这次系统的重头戏不少,把几个最容易踩雷的硬核变动拎出来,结合真实踩坑体验,聊聊到底该怎么调。

1. 强制“真沉浸”:你的 UI 还在被状态栏挡住吗?🎨

要说感知最明显的改变,绝对是 全屏边到边(Edge-to-Edge)显示 强制打响了!

以往我们写布局,状态栏和导航栏大多需要单独去设个背景色或者 padding,不少项目图省事直接顶在屏幕最上方。结果放到新系统上直接傻眼——由于系统强制把内容延伸到屏幕最边缘,顶部按钮直接撞上了状态栏,底部的提交按钮也被手势横条盖得死死的 🤦‍♂️。

 

❌ 没处理前的惨状:
┌─────────────────────────┐
│ 状态栏 [搜索框] <--- 被遮挡 │
│                         │
│       页面主体内容        │
│                         │
│ [确认提交] <--- 手势条覆盖 │
└─────────────────────────┘

 

👉 怎么破?

全面拥抱 WindowInsets!用 ViewCompat.setOnApplyWindowInsetsListener 去动态监听内边距,把状态栏和导航栏的高度实时拿出来加到 View 的 padding 上,或者在 Jetpack Compose 里直接用 safeDrawing 边界。不要硬编码高度,才能真正无缝适配各种刘海屏、打孔屏。

2. Native 层的核弹级升级:16KB 页面大小 💥

如果应用里用了 C/C++ 写的 NDK 库(比如音频解码、图像处理、游戏引擎等),这块一定要打起十二分精神!

系统底层的内存页尺寸从传统的 4KB 开始向 16KB 迁移。听起来好像只是底层改了改数字,性能变好了(应用启动速度提高,耗电还变少了),但对于依赖 .so 动态库的应用来说,如果不重新编译做对齐,直接就是启动即闪退!

真实案例:前两天测试打了个包,在开启了 16KB 模式的测试机上跑,只要一调到某个第三方老旧的语音 SDK,整个进程直接崩溃,报错提示就是典型的动态库加载段未对齐 💀。

👉 怎么破?

  1. 建议将 AGP (Android Gradle Plugin) 升级到相对较新的版本。

  2. 在 NDK 构建配置里添加对齐参数:-Wl,-z,max-page-size=16384。

  3. 赶紧联系项目里用到的那些几年没更新过的第三方 SDK 厂商,让他们提供支持 16KB 对齐的新 .so 包!

3. 前台服务(FGS)再次收紧:后台别想长久挂着 ⏳

曾经“一劳永逸”的前台服务,限制越来越苛刻了。特别是声明了 dataSync(数据同步)和 mediaProcessing(媒体处理)这类型的 FGS,系统加了一个 24小时内最多跑 6 小时 的硬性指标!

一旦超时,系统会触发 Service.onTimeout()。如果你的代码没在这个回调里及时调用 stopSelf() 自杀,系统就会直接抛异常挂掉应用。

👉 怎么破?

能不用 Foreground Service 就别用!对于文件上传、数据同步等后台任务,全面换成 WorkManager 才是正道。非要用前台服务的,记得一定要重写 onTimeout 方法,做好优雅收尾的准备,别让应用崩在用户背后。

4. 预测性返回动画变成了默认:手势交互别乱抢 👈

用户侧的预测性返回手势(滑动时能预览上一级界面)现在变成了默认开启状态。

这对于遵从标准 Activity/Fragment 栈的应用是好事情,但如果以前代码里喜欢自己重写 onBackPressed(),或者拦截手势处理了一些自定义弹窗逻辑,很容易出现手势拖到一半页面卡死或者动画错乱的问题 😵。

👉 怎么破?

彻底弃用废弃的 onBackPressed(),全面替换为 OnBackPressedDispatcher 和 OnBackPressedCallback。只有在确实需要拦截返回(比如未保存表单弹窗提醒)时才激活 Callback,处理完后及时将回调设为未激活状态,把控制权还给系统。

5. 应用被“强行停止”后,PendingIntent 直接失效 🛑

这是一个很容易忽略的安全/机制调整:一旦用户在系统设置里点了“强行停止”你的应用,系统不仅会杀死进程,还会取消该应用所有处于挂起状态的 PendingIntent!

这意味着桌面小组件(Widgets)会直接变灰无法交互,通过定时器或者通知栏预埋的跳转动作也会失效,直到用户下一次手动点击图标重新拉起应用为止。

👉 怎么破?

逻辑上不要过分依赖长期存活的 PendingIntent 来做核心业务唤醒。对于需要保障的通知和定时逻辑,确保在用户重新启动应用时,有兜底机制去重新注册和刷新状态。

1 of 6