MIUI Android P 适配指南

1. 综述

欢迎加入MIUI Android P适配计划。谷歌官方已于2018年8月7号发布了Android P,代号为Pie(馅饼) 。MIUI也于同天发布了基于Android P的MIUI系统(下文将简称为MIUI P)。本文档将介绍如何将您的应用适配到MIUI P,防止应用出现运行时错误而造成损失。

重要声明:

  • 若您的应用未适配MIUI P,用户仍可以在应用商店下载您的应用,但会收到应用未适配Android P的相关提示。为确保您的应用能够正常运行在MIUI P的版本上,请尽快完成适配。
  • 为确保您的应用能够在第一时间适配MIUI P,我们强烈建议您提前适配Android P,适配方法请参考Google官方文档。您的应用如果已适配Android P,原则上将不会在MIUI P上出现Android P兼容性问题。若仍存在,请尽快通过本文最后一节所述的方式将问题反馈给我们,我们会尽快解决。

2. MIUI P包含的内容

MIUI P是支持下一代Android系统的版本,它包含了最新的Android P API及相关系统组件。除此之外,还包括了MIUI为小米手机用户深度订制、精心打造的UI、系统功能、系统应用等等。具体内容请参考MIUI的主页

3. 获取MIUI P

3.1. 自动升级

MIUI P正式发布后,您即可通过我们推送的系统更新升级到MIUI P的版本。

3.2. ROM包升级

您可以在我们的官方网站上下载ROM包手动升级。具体操作步骤请参考升级手册

3.3. 原生Android P获取

您可以通过此Google官方文档获取到Android P,开始Android P的适配工作。

4. 迁移指南

MIUI P(Android API 级别 P)引入了行为变更以及您的应用中可加以利用的新功能和 API。本节概述了迁移指南。您可以通过以下步骤,将应用迁移到 MIUI P 。

4.1. 确保兼容 Android P

验证您的应用能够在Android P平台上全功能运行。在此阶段,您不需要使用新的 API,也不需要更改应用的 targetSdkVersion,但可能需要进行一些细微的更改。具体请参考Android P行为变更

4.2. 确保兼容 MIUI P

您也可以直接在MIUI P上验证您的应用。同样,在此阶段,您不需要使用新的 API,也不需要更改应用的 targetSdkVersion,但可能需要进行一些细微的更改。

若您的应用已经能够在Android P上全功能运行,原则上也可以在MIUI P上全功能运行。但您仍需测试验证。

4.3. 更新您的目标版本并使用 MIUI P 功能

当您准备好利用平台的新功能时,将 targetSdkVersion 更新至“28”,验证应用是否仍可按预期方式运行,然后开始使用新的 API。

5. 新功能和API

MIUI P为用户和开发者引入众多新特性和新功能,具体的功能和API的变化可点击这里

本文重点介绍面向开发者的新功能。要了解新API,请阅读 API 差异报告或访问Android API 参考 — 为醒目起见,将突出显示新API。 请务必查阅 Android P 行为变更以了解平台变更可能给您的应用带来哪些方面的影响。

6. 重点适配问题

为了解当前应用对MIUI P的适配情况,以便更好推进MIUI P的适配工作,我们已在内部进行了MIUI P的兼容性测试。我们选取了小米应用商店Top 1000的应用,对每个应用进行下载、安装、启动、monkey测试、遍历测试、卸载,并在整个过程中检测是否有FC/ANR问题发生。根据测试结果,我们强烈建议您关注以下问题。若您的应用存在以下情况,请尽快适配。

6.1. 使用了第三方加固工具

由于加固工具和系统耦合紧密,因此若您的应用使用了第三方加固工具,请尽快更新您所使用的加固工具以适配Android P。我们也会尽快推动加固厂商适配Android P。

在我们的测试中,存在兼容性问题的第三方加固工具有:

  • 梆梆加固
  • 360加固
  • 阿里聚安全
  • 百度加固

若您的应用使用了以上的加固工具,请务必关注相应厂商的适配进度,以便第一时间更新加固工具以适配Android P。若您使用的是其它加固工具,也请关注工具的Android P适配情况。

6.2. 依赖org.apache.http.legacy.boot.jar包

Android Runtime虚拟机实例初始化时会加载init.environ.rc中配置的jar包。Android P中init.environ.rc已移除了/system/framework/org.apache.http.legacy.boot.jar,该jar包内的类将不会被加载。如果您的应用使用了Apahce Http Client的类,且没有手动加载该jar包,则应用会报ClassNotFoundException异常,无法正常运行。因此,若您的应用依赖此包,请务必尽早适配。也请关注您使用的第三方SDK是否有依赖该jar包,如果有,请关注SDK的适配情况,并在SDK适配后第一时间更新SDK。

6.3. 使用了第三方SDK

一些第三方SDK也存在Android P的兼容性问题,导致应用无法运行。在我们的测试中,存在兼容性问题的SDK有:

  • 联通支付SDK
  • 腾讯广点通SDK

若您的应用使用了包括这两款在内的SDK,请务必关注相应厂商的适配进度,以便第一时间更新SDK以适配Android P。

小米开发平台 刘海屏、水滴屏、挖孔屏 Android P/Q 适配

小米开发平台 刘海屏、水滴屏、挖孔屏 Android P/Q 适配

1. 背景

  • 小米 8 等刘海设备上市时运行的是 Android O 设备,但由于 Android O 没有标准接口,所以当时适配的规则和接口仅在 MIUI 系统生效。关于小米 Android O 的规则,详见https://dev.mi.com/console/doc/detail?pId=1293
  • 后来 Android P 中新增了刘海屏适配的API,为了与行业标准一致,MIUI 也决定在运行 Android P 的设备上完全采用 Android P 的接口。
  • 但由于 Android P 的接口定义得比较晚,导致 MIUI 接口无法与其完全兼容,开发者需要针对 Android P 的小米设备重新适配。

该文档将结合小米的情况给大家简要介绍 Android P 的刘海屏适配规则及 API,更详细的内容可以直接查看官方文档 https://developer.android.com/guide/topics/display-cutout/

2. 部分小米水滴屏/刘海屏/挖孔屏设备信息如下

机型modeldevice分辨率Notch高度Notch宽度DPI
小米8MI 8dipper1080*224889560440
小米8 SEMI 8 SEsirius1080*224485540440
小米8 透明探索版MI 8 Explorer Editionursa1080*224889560440
小米8 屏幕指纹版MI 8 UDequuleus1080*224889560440
小米8 青春版MI8Liteplatina1080*228082296440
小米POCO F1POCO F1beryllium1080*224686588440
红米6 ProRedmi 6 Prosakura1080*228089352440
红米Note 7Redmi Note 7lavender1080*234079116440
小米CC9 ProMi CC9 Protucana1080*2340​71146​​440
Redmi K30​​Redmi K30​phoenix​1080*2400​92179​440

注意事项:

  • 以上设备,由于MIUI调整了 DPI 值,因此DP值与像素值的转换关系是 1dp = 2.75 px ;
  • 用原生api DisplayCutout就可以直接获取​设备屏幕尺寸和异形的位置大小等信息,以上仅做参考,之后新机将不再罗列。​

3. 概念说明

为了方便讨论,我们明确下以下概念:

上述两种屏幕都可以统称为刘海屏,不过对于右侧较小的刘海,业界一般称为水滴屏或美人尖。为便于说明,后文提到的「刘海屏」「刘海区」都同时指代上图两种屏幕。

4. Android P/Q 刘海屏水滴屏挖孔屏的适配规则 

Android P 提供了 3 种显示模式供开发者选择,分别是:

  • 默认模式(LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT)
  • 刘海区绘制模式( LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)
  • 刘海区不绘制模式(LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER)

如果开发者未作任何声明,则会按默认模式处理。以下将具体介绍这三种模式的表现。

4.1. 默认模式(LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT)

为了在不影响操作的情况下,尽可能利用刘海屏的显示区域,有以下表现:

非全屏(normal mode)全屏(fullscreen mode)
竖屏(portrait mode)使用耳朵区禁用耳朵区
横屏(landscape mode)禁用耳朵区禁用耳朵区

注:所谓全屏(fullscreen mode),是指隐藏状态栏(status bar),即通过 SYSTEM_UI_FLAG_FULLSCREEN 实现的效果。

默认模式的截图效果如下:

4.2. 刘海区绘制模式(LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)

如上所述,默认模式下某些场景会禁用耳朵区,那是因为这些场景下,系统无法判断开发者是否会把控件放置在耳朵区,所以只好默认禁用。如果开发者想要在那些场景下使用耳朵区,需要主动声明,即使用 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 来主动声明。

由于各个厂商的刘海或者凹口形状、位置不一, 开发者可以通过 WindowInsets.getDisplayCutout()  来获得 DisplayCutout object,里面包含了几个有用的方法:

开发者根据业务内容,自行判断是否需要根据不同的刘海形状做不同的布局调整。以小米8(刘海高度89px)为例,当开发者选用 SHORT_EDGES 模式时,以上接口会返回以下值:

竖屏横屏(刘海在左边)
getBoundingRects()(201, 0 – 879, 90)(0, 201 – 90, 879)
getSafeInsetLeft() 090
getSafeInsetTop()900
getSafeInsetRight() 00
getSafeInsetBottom()00

上述接口的返回值代表:

  • 小米8有一个刘海,竖屏时,这个刘海所在的矩形区域的左上角、右下角的坐标分别为 (201, 0) 和 (879, 90) —— 左上角为 (0, 0) 原点;横屏时,这个刘海所在的矩形区域的左上角、右下角的坐标分别为 (0, 201) 和 (90, 879) —— 左上角为 (0, 0) 原点。
  • 对于小米8,如果开发者需要将内容避开刘海区域,竖屏时就需要从顶部向下偏移 90 px,左、右和下无需要偏移。

又以红米Note 7(水滴屏设备) 为例,当开发者选用 SHORT_EDGES 模式时,以上接口会返回以下值:

竖屏横屏(水滴在左边)
getBoundingRects()(450, 0 – 630, 80)(0, 450 – 80, 630)
getSafeInsetLeft() 080
getSafeInsetTop()800
getSafeInsetRight() 00
getSafeInsetBottom()00

上述接口的返回值代表:红米Note 7 有一个刘海(水滴),竖屏时,这个刘海所在的矩形区域的左上角、右下角的坐标分别为 (450, 0) 和 (630, 80) ;横屏时,这个刘海所在的矩形区域的左上角、右下角的坐标分别为 (0, 450) 和 (80, 630) 。

又以Redmi K30 (挖孔屏设备)为例子,当开发者选用 SHORT_EDGES 模式时,以上接口会返回以下值:

 竖屏横屏(摄像头在左边)
getBoundingRects()(844, 0 – 1080, 95)](0, 0 – 95, 236)
getSafeInsetLeft()095
getSafeInsetTop()950
getSafeInsetRight()00
getSafeInsetBottom()00

上述接口的返回值代表:

Redmi K30有刘海/水滴/挖孔,竖屏是,这个刘海在手机的左上角,右下角的坐标分别为 (844,0)和 (1080, 95);左上角为(0,0);横屏时,这个刘海对应的值为(0,0)和(95,236)。对于Redmi K30,如果开发者需要将内容避开挖孔区域,竖屏就需要从顶部向下偏移95px,左、右和下无需偏移。

4.3. 刘海区不绘制模式(LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER )

开发者选用这个模式后,意味着不绘制内容到耳朵区。如非必需,我们不建议采用这种模式,因为那样会浪费不少屏幕空间,用户体验不佳。

当开发者选用 NEVER 模式时, DisplayCutout object 的以下方法都会返回空值,因为 Google 认为既然开发者不使用耳朵区,就不需要关心刘海的大小了。

竖屏横屏(刘海在左边)
getBoundingRects()nullnull
getSafeInsetLeft() null null
 getSafeInsetTop()nullnull
getSafeInsetRight() nullnull
getSafeInsetBottom()nullnull

5. 其他注意事项

5.1. 避免写死状态栏的值

由于 Notch 设备的状态栏高度与正常机器不一样,因此在需要使用状态栏高度时,不建议写死一个值,而应该改为读取系统的值。

以下是获取当前设备状态栏高度的方法:

int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");

if (resourceId > 0) {

result = context.getResources().getDimensionPixelSize(resourceId);

}

5.2. 处理好同一页面,进入与退出全屏模式(fullscreen mode)的过渡

因为在默认模式 / LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT 下,系统针对全屏与非全屏的页面,耳朵区的显示逻辑不一样。如果开发者没有处理好,容易出现页面可用区域跳变的问题。针对这种页面,我们建议开发者主动声明是否使用耳朵区,以避免跳变。

6. 常见问题

6.1. 如何测试

有两种方法:

  • 使用小米设备测试,如小米8系列(含标准版、探索版、屏幕指纹版),然后升级至 Android P 的 MIUI 版本,下载地址为:https://www.miui.com/download-345.html
  • 使用运行原生 Android 9 的设备,然后前往「开发者选项 – 模拟“刘海屏”」,选择任一刘海选项。 

若适配中遇到问题,可以发邮件给相关工程师张定昌 zhangdingchang@xiaomi.com、喻伟 yuwei@xiaomi.com 或工程组 miuishell@xiaomi.com。

6.2. 适配过小米 Android O 的刘海屏接口,在小米的 Android P 设备上是否需要重新适配

需要。如文章开头所说,Android P 的接口今年6月才公布,我们在接口设计上和他们有一些出入,所以没法兼容。开发者仍然需要再针对 Android P 做适配,但好消息是,各大手机厂商都支持 Android P 的接口,所以大家只要适配一次就可以了。

6.3. MIUI Android O 的老接口在 Android P/Q设备上是否生效?

P和Q大部份用的是原生Andoid的API,MIUI的接口保留了O里面的Application级别的控制接口

<meta-data
 android:name="notch.config"
 android:value="portrait|landscape"/>

app如果用这个meta-data声明了横竖屏都绘制到耳朵区,相当于每个页面都设成了LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES模式。这就需要app确认自己的所有页面会不会被遮挡,特别是横屏和全屏页面。如果想单独修改某个页面,可以单独修改该页面Window的layoutInDisplayCutoutMode属性

6.4. 原生 Android P 的规则和 MIUI Android O 的规则有什么区别

双方在默认模式下的表现是完全一致的,区别主要体现在:

  • Android P 能通过 DisplayCutout object 获取刘海 / Notch / Cutout 的具体信息,但 MIUI Android O 只能获取刘海的高宽信息。
  • Android P 不能控制仅竖屏(或横屏)使用耳朵区,但 MIUI Android O 可以分别配置横竖屏对耳朵区的使用策略。 

Android P应用适配指南

一、如何体验升级android P

1.1 x21升级android P指导

请开发者更新到市场最新系统版本进行对应调试。

1.2 vivo远程真机服务

vivo云测平台已经提供关于vivo x21 androidP的远程真机服务,开发者可以直接通过以下链接进入远程真机进行试用体验:

https://vcl.vivo.com.cn/#/home/index

1.3 pixel升级android P

开发者持有Pixel系列的机器可以直接ota升级,或则下载镜像升级,具体见链接:

https://developers.google.com/android/images

二、AndroidP兼容性变化

2.1 对非 SDK 接口的限制

2.1.1 介绍

非sdk的接口存在着稳定性问题,随着android版本的变化随时都有可能被移除,AndroidP开始,为了更好的提升app的兼容性,正对隐藏的非sdk接口进行限制,通过名单控制进行使用限制,具体规则限制如下:

白名单SDK标准接口,不受限制
浅灰名单仍可以访问的非 SDK 函数/字段
深灰名单对于目标 SDK 低于 API 级别 28 的应用,允许使用深灰名单接口。对于目标 SDK 为 API 28 或更高级别的应用:行为与黑名单相同
黑名单受限,无论目标 SDK 如何。 平台将表现为似乎接口并不存在。 例如,无论应用何时尝试使用接口,平台都会引发 NoSuchMethodError/NoSuchFieldException,即使应用想要了解某个特殊类别的字段/函数名单,平台也不会包含接口

2.1.2 影响范围

所有运行在AndroidP系统上的应用

2.1.3 如何适配

(1)对于黑名单及深灰名单中的接口,应用及时调整新的方案进行适配;

(2)黑名单及灰名单是在源码构建的时候生成的,在此提供一份,文件下载链接:【黑名单】点此下载   | 【灰名单】点此下载

(3)应用可以直接adb logcat命令中过滤”Accessing hidden”查看当前应用使用非sdk的情况

2.2 刘海屏适配指导(cutout)

2.2.1 介绍

随着X21后各种刘海屏相继出现,但没有一致的接口,AndroidP开始提供规范化的接口,应用可以使用标准接口,获取当前是否有刘海,控制应用在刘海屏上的布局显示区域。AndroidP的设备支持模拟刘海效果,持有P的设备的可以打开“开发者选项”,找到“模拟巨有凹口的显示屏”进行模拟调试。

2.2.2 影响范围

所有运行在AndroidP系统上的应用,不分targetsdkversion

2.2.3 如何适配

■ 怎么判断是否刘海支持与否?

View.getRootWindowInsets().getDisplayCutout()

返回DisplayCutout对象,为刘海的描述信息,不支持则返回空

■ 怎么获取刘海信息?

DisplayCutout.getSafeInsets() 返回安全区域Rect

DisplayCutout.getBounds()  返回刘海的区域的Region

■ 如何控制应用的布局显示?

通过控制窗口布局的layoutInDisplayCutoutMode属性可以达到控制应用在刘海屏下布局区域,具体可以设置以下值

LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT

没有设置的情况下默认此标记,只有状态栏区域可见的情况下,才意味着加了FLAG_FULLSCREEN or SYSTEM_UI_FLAG_FULLSCREEN标记的应用窗口都会被切边放在刘海以下

LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES

此flag下不进行应用窗口的限制,窗口可以显示到刘海区域

LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER

此flag下应用窗口一直被限制在刘海区域以下

应用也可以通过theme来达到同样的效果

<item name=”android:windowLayoutInDisplayCutoutMode”>default</item>

对应LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT

<item name=”android:windowLayoutInDisplayCutoutMode”>shortEdges</item>

对应LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES

<item name=”android:windowLayoutInDisplayCutoutMode”>never</item>

对应LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER

应用遇到窗口显示被限制在刘海以下区域的可以调整

layoutInDisplayCutoutMode 设置为

LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES,再通过获取

DisplayCutout 关于刘海区域信息,调整UI达到更好的满屏体验。

2.3 应用待机分组策略

2.3.1 介绍

应用待机分组为AndroidP上新的电源管理功能,它将应用归为五类,没有采用不同的限制策略,来控制应用的访问资源的能力。

具体分以下五类:

活跃如果用户当前正在使用应用,应用将被归到“活跃”群组中,例如:
应用已启动一个 Activity
应用正在运行前台服务
应用的同步适配器与某个前台应用使用的 content provider 关联
用户在应用中点击了某个通知
工作集如果应用经常运行,但当前未处于活跃状态,它将被归到“工作集”群组中。 例如,用户在大部分时间都启动的某个社交媒体应用可能就属于“工作集”群组。 如果应用被间接使用,它们也会被升级到“工作集”群组中。
常用如果应用会定期使用,但不是每天都必须使用,它将被归到“常用”群组中。 例如,用户在健身房运行的某个锻炼跟踪应用可能就属于“常用”群组。
极少使用如果应用不经常使用,那么它属于“极少使用”群组。 例如,用户仅在入住酒店期间运行的酒店应用就可能属于“极少使用”群组。
从未使用安装但是从未运行过的应用会被归到“从未使用”群组中,此类应用不具备运行条件。

限制策略如下:

分类jobs*Alarns NetworkFirebase Cloud Messaging
活跃无限制无限制无限制无限制
工作集2小时每次6分钟每次无限制无限制
常用 8小时每次30分每次无限制High priority: 10/day
极少使用24小时每次2小时每次24小时每次High priority: 5/day
1. jobs在限制的情况下,只有10分钟窗口时间执行,超出十分钟将被停止
2. alarms在限制的情况下,只有10s中的执行时间
3. 网络被限制的情况下,每次10分钟的窗口时间访问网络资源

2.3.2 影响范围

所有运行在AndroidP系统上的应用,不分targetsdkversion,受此影响为主要为应用的后台行为受限制,特别如闹钟,地图导航,后台下载,健康类应用。

2.3.3 如何适配

■ 应用根据Android的限制策略,点检应用的后台行为是否被限制。

■ 如何确认是否因为应用待机分组导致的后台行为限制?

(1)先确认应用的待机分组

            adb shell am get-standby-bucket [packagename]  //查下当前应用的分组情况;

(2)如果不在活跃组(active)

            adb shell am set-standby-bucket packagename active  //强制切换应用到活跃分组;

确认在此情况下用户的行为是否依然受限制,如果是的话,才确认为待机分组策略导致的后台行为限制。

■ 应用可以通过

            adb shell am set-standby-bucket packagename active|working_set|frequent|rare 在不同分组见强制进行切换,调试自身应用。

■ 对于由于后台分组策略导致的后台限制,应用需要进行相关策略上的调整详细见:https://developer.android.com/about/versions/pie/power

2.4 Crypto JCA 提供程序已被移除,弃用 Bouncy Castle 加密

2.4.1 介绍

Crypto JCA 提供程序已被移除。调用 SecureRandom.getInstance(“SHA1PRNG”,”Crypto”) 将会引发 NoSuchProviderException,调用Bouncy Castle 提供程序的 getInstance(),会生成 NoSuchAlgorithmException 错误。

2.4.2 影响范围

(1)Crypto JCA 提供程序已被移除,此影响所有运行AndriodP系统的所有应用;

(2)Bouncy Castle 提供程序异常的问题,影响所有targetsdkversion>=28的应用;

2.4.3 如何适配

模块应该在getInstance()的时候不指派提供程序,采用默认实现即可

2.5 FLAG_ACTIVITY_NEW_TASK被强制要求

AndroidP上,从非 Activity 环境中启动 Activity,除非传递 Intent 标志 FLAG_ACTIVITY_NEW_TASK。 如果尝试在不传递此标志的情况下启动 Activity,则该 Activity 不会启动,此限制对所有运行AndroidP的应用生效。

2.6 禁止空闲应用访问相机、麦克风和传感器

Android 9 限制后台应用访问用户输入和传感器数据的能力。 如果您的应用在运行 Android 9 设备的后台运行,系统将对您的应用采取以下限制:

(1)应用不能访问麦克风或摄像头。

(2)使用连续报告模式的传感器(例如加速度计和陀螺仪)不会接收事件。

(3)使用变化或一次性报告模式的传感器不会接收事件。

2.7 前台服务的应用必须请求 FOREGROUND_SERVICE 权限

targetsdkversion>=28的应用在使用前台服务的都需要进行必须请求 FOREGROUND_SERVICE 权限。 这是普通权限,因此,系统会自动为请求权限的应用授予此权限。

<uses-permission ndroid:name=”android.permission.FOREGROUND_SERVICE”/>

2.8 默认情况下启用网络传输层安全协议

AndroidP上,对应targetsdkversion>=28的应用需要为特定域名启用明文,必须在应用的网络安全性配置中针对这些域名将 cleartextTrafficPermitted 显式设置为 true,默认情况下明文传输会直接抛出“java.io.IOException: Cleartext HTTP traffic to xxx.com not permitted”异常。

2.9 Apache HTTP 客户端弃用,bootclasspath 中已移除

AndroidP开始org.apache.http.legacy.jar这个包不在打包进bootclasspath,对于targetsdkversion>=28的,继续引用此包的应用将直接出现NoClassDefFoundError,对于targetsdkversion低于28的,系统会将此包加载到应用的classloader中,如果应用采用系统的classloader加载应用,将同样会出现NoClassDefFoundError,建议模块使用 HttpURLConnection 类,更加高效。

2.10 移除对 Build.serial 的直接访问

Build.SERIAL字段已经被废弃,AndroidP上值一直为“UNKNOWN”, 如果您的应用需要访问设备的硬件序列号,您应请求 READ_PHONE_STATE 权限,然后调用 getSerial()。

2.11 不允许共享 WebView 数据目录

targetsdkversion>=28的应用不允许在不同进程之间共享一个 WebView 数据目录。如果应用有多个进程使用 WebView、CookieManager 或 android.webkit 软件包中的任何其他 API,则在第二个进程调用 WebView 函数时,应用将会崩溃。

2.12 应用禁止访问xt_qtagui目录的文件

AndroidP后,不再允许应用直接读取 /proc/net/xt_qtaguid 文件夹中的文件。 这样做是为了确保与某些根本不提供这些文件的设备保持一致。应用应该采用标准 API TrafficStats 和 NetworkStatsManager 进行访问,此限制对所有运行AndroidP系统上的应用生效。

2.13 SELinux 禁止访问应用的数据目录

对于targetsdkversion>=28的应用,系统强制每个应用的 SELinux 沙盒对每个应用的私有数据目录强制执行逐个应用的 SELinux 限制。现在,不允许直接通过路径访问其他应用的数据目录。应用可以继续使用进程间通信 (IPC) 机制(包括通过传递 FD)共享数据,例如可以采用FileProvider

三、参考链接

(1)AndroidP所有应用行为变更:https://developer.android.com/about/versions/pie/android-9.0-changes-all

(2)AndroidP targetSDK 28应用行为变更:https://developer.android.com/about/versions/pie/android-9.0-changes-28

(3)AndroidP 电源管理:https://developer.android.com/about/versions/pie/power

(4)pixles系列镜像升级:https://developers.google.com/android/images