大家好,我叫八两,来自37手游安卓团队。
前不久,9月21号,谷歌更新了 Android 12 Beta5 版本的说明,Beta5 也会是 Android 12 正式版本前的最后一个 Beta 测试版本。
恰巧9月27号,有幸参加金标联盟的第一次线下活动,也聊到了Android 12 的适配。
那么 Android 12 到底会给我们带来什么样的改变,作为一名从业者,我们又该分配多少资源以及如何去对我们的产品进行适配呢。
适配
通常我们说的适配,严格来讲分成两个阶段。
第一部分是通配性问题, 即使我不对我的项目进行任何修改,不修改 TargetSdkVersion 也需要进行关注, 个人喜欢把它叫通配性问题。
第二部分则是全面适配问题, 即 TargetSdkVersion 等于 31 才需要去关注的问题.
这里主要和大家讲讲通配性问题。
如果大家需要迁移到 Android 12, 设置 TargetSdkVersion 成 31, 可以根据自身产品使用的东西并参考 官方文档 来进行迁移。
通配性问题
通配性问题,咱的定义是,无论你使用哪个版本的 TargetSdkVersion, 只要跑在 Android 12 上,你都需要关注。这里个人节选了几个比较重要的,一起来看看吧.
Splash Screen
Android 12 增加了系统默认的 APP 启动页,该 APP 启动页会使用APP定义的主题和ICON生成。这可能对很多开发者来说是一个比较大的困恼,如果不做任何适配,产生的结果可能如下:
- 如果你原本使用
android:windowBackground
实现了启动页,你的实现会被默认的启动页样式替换。 - 如果你使用了一个额外的 Activity 作为启动页,则会先弹出系统默认启动页,再弹出你实现的启动页,用户有幸可以享受两次闪屏了。
目前谷歌的适配方案只提供了设置主题的方式,至于原本使用额外 Activity 作为启动页的方式,谷歌爸爸和蔼的和我们说,你可以选择不管或者去掉 Activity并使用设置主题方式来兼容.
具体方法如下:
- 设置
compileSdkVersion
和引入库
build.gradle
android {
compileSdkVersion 31
...
}
dependencies {
...
implementation 'androidx.core:core-splashscreen:1.0.0-alpha01'
}
- 创建闪屏主题,继承
Theme.SplashScreen
, 设置postSplashScreenTheme
和windowSplashScreenAnimatedIcon
, 其他字段可选.如:
<style name="Theme.App.Starting" parent="Theme.SplashScreen">
// Set the splash screen background, animated icon, and animation duration.
<item name="windowSplashScreenBackground">@color/...</item>
// Use windowSplashScreenAnimatedIcon to add either a drawable or an
// animated drawable. One of these is required.
<item name="windowSplashScreenAnimatedIcon">@drawable/...</item>
<item name="windowSplashScreenAnimationDuration">200</item> # Required for
# animated icons
// Set the theme of the Activity that directly follows your splash screen.
<item name="postSplashScreenTheme">@style/Theme.App</item> # Required.
</style>
- Manifest 使用对应的主题
<manifest>
<application android:theme="@style/Theme.App.Starting">
<!-- 或者 -->
<activity android:theme="@style/Theme.App.Starting">
...
- 代码中,在
setContentView
前调用installSplashScreen
, 以 Java 为:
public class SplashScreenSampleActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Handle the splash screen transition.
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
setContentView(R.layout.main_activity);
}
}
installSplashScreen
会返回闪屏对象,其本身也可以进行一些属性设置, 至此,如上就是谷歌推荐的 SplashScreen 的适配方法
OverScroll 滚动动画增加
Android 12 修改了 OverScroll 的效果动画,从原来的拉到底部显示蓝光,修改成了拉到变形弹弹弹的动画。如下图
如果你需要特别处理 OverScroll 的动画或者动作,谷歌增加了float getDistance()
和 float onPullDistance(float deltaDistance, float displacement)
两个 API 来处理 OverScroll 行为, 需要在 onTouchEvent
中使用如上两个 API,再自定义对应行为.
如果你不喜欢这个动画的话,你也可以通过 xml 中设置 android:overScrollMode="never"
或者使用代码设置 recyclerview.setOverScrollMode(View.OVER_SCROLL_NEVER);
来屏蔽默认的滚动动画。
引入限制域概念(官方翻译: 限制性应用待机模式存储分区)
Android 12 引入了 APP 限制域, 限制域不但会定义应用的优先级(是否容易被系统杀死),处于低限制域的应用还会被限制一些比较消耗系统资源的行为。而限制域优先级的划分,很大程度上取决于你应用的使用频率以及当前是否在被前台使用。
想获取 APP 当前的限制域可以使用 getAppStandbyBucket
方法得到,示范:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
UsageStatsManager manager = (UsageStatsManager) getSystemService(USAGE_STATS_SERVICE);
if(manager != null) manager.getAppStandbyBucket();
}
如果需要测试 APP 在严格限制域的表现,谷歌也提供了相对应的命令来进行模拟:
adb shell am set-standby-bucket PACKAGE_NAME restricted
这个只需要做充分的测试即可,毕竟你也做不了什么,避免被限制的方法很简单,让用户停在你的APP界面以及更经常的使用你的 APP, 这应该是所有应用开发者一直在研究的问题吧。
Display.getRealSize() & Display.getRealMetrics() 废弃
继 Android 11 废弃了 Display.getSize()
和 Display.getMetrics()
后,Android 12 上进一步废弃了 Display.getRealMetrics()
和 Display.getRealSize()
. 现在推荐使用 WindowMetrics
, 并且谷歌提供了一个兼容到 Android 4.0 的 WindowManager
兼容库。
通常情况可以使用如下代码代替以前计算屏幕宽高,:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
metrics = activity.getWindowManager().getCurrentWindowMetrics();
int width = metrics.getBounds().width();
int height = metrics.getBounds().height();
}
如果你的应用还在使用如上 API, 赶紧替换掉吧。
非可信触摸事件会被屏蔽
Android 12 开始,如果 APP 被其他UI遮挡覆盖或者在APP上绘制了其他UI,用户所有的触摸(touch)事件不再会传递下来了,你的 APP 将无法响应这些触摸事件, 当然APP被如下特殊情况的窗口遮挡, 触摸事件可以正常传递:
- 不可见的窗口,窗口都不见了,也挡不住用户去摸了。
- 完全透明的窗口,和上一条如出一辙,完全透明的衣服等于没穿。(alpha 值是 0)
- 部分半透明窗口,遮不遮的住取决于透明度,目前版本最大 opacity 值 0.8 以下,依然可以传递触摸事件。不过将来正式版本这个值可能被修改。
- 遮挡的 UI 本身由你的APP创建,且只在你的 APP 内显示交互时.
- 遮挡你APP的是可信的遮挡UI,包括但不限于如下:
- 软键盘或其他系统输入
- 系统助手悬浮窗
- 使用了
TYPE_ACCESSIBILITY_OVERLAY
标志的窗口
...
这一条个人认为,也是谷歌爸爸对现应用动不动喜欢搞个系统级的悬浮窗的一种限制,对绝大多数应用应该影响不大。
除了上述问题外,还存在一些其他细节修改,就不一一赘述,感兴趣的亲们可以仔细阅读通配性问题谷歌文档
适配优先级
作为一个技术,不聊 DeadLine 来谈优先级,简直就是耍流氓。对于通配性问题,建议所有开发者在 Android 12 正式版本发布后第一时间进行测试,来确认是否会影响自家产品和业务。
对于全面更新适配 Android 12(TargetSdkVersion 升级到 31), 目前 Android 12 还在进行 Beta5 测试,但尚未完成完全兼容测试(Compatibility Test Suite),按照以往的速度,快则个把月,慢则几个月。Android 12 正式版本会与大家见面,而从发布到用户真正能使用也需要一段时间。对于应用开发者,在Android 12正式版本发布后的任何时候,都可以开始考虑进行适配工作。 等到各大国产厂商开始推送 Android 12 时,再进行适配,可能就被友商卷下去了。
而对于游戏开发者,联运渠道SDK本身适配也需要一段时间,考虑到绝大多数渠道目前还只要求TargetSdkVersion 26, 只上联运的话,会有非常充裕的适配时间,等各大联运渠道通知即可,估摸着2023年吧。
如果发海外 GooglePlay, 通常新系统出来后半年内需要进行适配,之后再过小半年,GooglePlay 就要开始强制要求适配了,发海外 GooglePlay 也是越快适配越好的行情。
如果贵司纯靠买量投放与自有流量导入,那花一上午简单在 Android 12 上测试一下功能,啥时候高兴啥时候适配。
Android 12 已知问题
最后,聊聊谷歌目前 Android 12 的几个高频已知问题,如果你遇上了,不要慌,谷歌已经知道有这些问题了,反正你不需要去纠结。大概率(看谷歌心情)正式版本会被修复的。
- 通过 设置->账户密码添加账户时,系统会黑屏.
- 下滑通知栏,有时通知栏无法正常显示通知.190269314 锁屏时有时无法正常显示通知189173895
- 连着 USB 调试时,使用谷歌地图或者视频播放软件,Android 系统会崩溃.189515336
- 使用虚拟键盘时,如果有通知进来,虚拟键盘会被自动最小化,且划掉通知前,无法正常使用键盘.193920125
如果想详细了解 Android 12 的已知问题,请参阅 https://developer.android.com/about/versions/12/top-issues
总结
总体来说,对绝大多数产品, Android 12 的更新并不会像 Android 11 与 Android 10 复杂,且目前 Android 12 正式版本还未推出,部分内容各大手机硬件厂商也在与谷歌商讨,所以,对于绝大多数应用开发者,我的建议是,Android 12 发布后,针对文章提到的点进行一次兼容性测试就可以了。