android12适配记录

Posted 张学涛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android12适配记录相关的知识,希望对你有一定的参考价值。

适配

通常我们说的适配,严格来讲分成两个阶段。
第一部分是通配性问题, 即使我不对我的项目进行任何修改,不修改 TargetSdkVersion 也需要进行关注, 个人喜欢把它叫通配性问题。
第二部分则是全面适配问题, 即 TargetSdkVersion 等于 31 才需要去关注的问题.
这里主要和大家讲讲通配性问题。
如果大家需要迁移到 Android 12, 设置 TargetSdkVersion 成 31, 可以根据自身产品使用的东西并参考 官方文档 来进行迁移。

通配性问题

通配性问题,咱的定义是,无论你使用哪个版本的 TargetSdkVersion, 只要跑在 Android 12 上,你都需要关注。这里个人节选了几个比较重要的,一起来看看吧.

Splash Screen

Android 12 增加了系统默认的 APP 启动页,该 APP 启动页会使用APP定义的主题和ICON生成。这可能对很多开发者来说是一个比较大的困恼,如果不做任何适配,产生的结果可能如下:

  1. 如果你原本使用 android:windowBackground 实现了启动页,你的实现会被默认的启动页样式替换。
  2. 如果你使用了一个额外的 Activity 作为启动页,则会先弹出系统默认启动页,再弹出你实现的启动页,用户有幸可以享受两次闪屏了。

目前谷歌的适配方案只提供了设置主题的方式,至于原本使用额外 Activity 作为启动页的方式,谷歌爸爸和蔼的和我们说,你可以选择不管或者去掉 Activity并使用设置主题方式来兼容.
具体方法如下:

  • 设置 compileSdkVersion 和引入库
build.gradle

android 
   compileSdkVersion 31
   ...

dependencies 
   ...
   implementation \'androidx.core:core-splashscreen:1.0.0-alpha01\'

  • 创建闪屏主题,继承 Theme.SplashScreen, 设置 postSplashScreenThemewindowSplashScreenAnimatedIcon, 其他字段可选.如:
<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,再自定义对应行为.

 
pull-stretch-overscroll.gif

 

如果你不喜欢这个动画的话,你也可以通过 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被如下特殊情况的窗口遮挡, 触摸事件可以正常传递:

  1. 不可见的窗口,窗口都不见了,也挡不住用户去摸了。
  2. 完全透明的窗口,和上一条如出一辙,完全透明的衣服等于没穿。(alpha 值是 0)
  3. 部分半透明窗口,遮不遮的住取决于透明度,目前版本最大 opacity 值 0.8 以下,依然可以传递触摸事件。不过将来正式版本这个值可能被修改。
  4. 遮挡的 UI 本身由你的APP创建,且只在你的 APP 内显示交互时.
  5. 遮挡你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 的几个高频已知问题,如果你遇上了,不要慌,谷歌已经知道有这些问题了,反正你不需要去纠结。大概率(看谷歌心情)正式版本会被修复的。

  1. 通过 设置->账户密码添加账户时,系统会黑屏.
  2. 下滑通知栏,有时通知栏无法正常显示通知.190269314 锁屏时有时无法正常显示通知189173895
  3. 连着 USB 调试时,使用谷歌地图或者视频播放软件,Android 系统会崩溃.189515336
  4. 使用虚拟键盘时,如果有通知进来,虚拟键盘会被自动最小化,且划掉通知前,无法正常使用键盘.193920125

如果想详细了解 Android 12 的已知问题,请参阅 https://developer.android.com/about/versions/12/top-issues

总结

总体来说,对绝大多数产品, Android 12 的更新并不会像 Android 11 与 Android 10 复杂,且目前 Android 12 正式版本还未推出,部分内容各大手机硬件厂商也在与谷歌商讨,所以,对于绝大多数应用开发者,我的建议是,Android 12 发布后,针对文章提到的点进行一次兼容性测试就可以了。

 

作者:张学涛

-------------------------------------------

我不是代码的生产者,只是代码的搬运工

以上是关于android12适配记录的主要内容,如果未能解决你的问题,请参考以下文章

Android 12.0 适配——应用启动动画

Android 12 蓝牙适配

Android 12 exported自动适配

全面适配 Android12

Android 12 蓝牙适配

Android 12 蓝牙适配 Java版