文章目录
  1. 1. 在Android P上运行的所有应用
    1. 1.1. 后台应用中的输入和数据隐私
    2. 1.2. 设备安全性变更
    3. 1.3. 应用兼容性变更
    4. 1.4. ICU库更新
    5. 1.5. 不再支持Android安全加密文件(ASEC)
    6. 1.6. 测试库
    7. 1.7. Java UTF解码器
    8. 1.8. 使用证书的主机名验证
    9. 1.9. 网络地址查询可能会导致网络违规
    10. 1.10. 套接字标记
    11. 1.11. 应用无法再访问 xt_qtaguid 文件夹中的文件
    12. 1.12. 强制执行 FLAG_ACTIVITY_NEW_TASK 要求
    13. 1.13. 屏幕旋转变更
  2. 2. 针对Android P的应用
    1. 2.1. 前台服务
    2. 2.2. 设备序列号访问限制
    3. 2.3. 框架安全性变更
    4. 2.4. 视图焦点
    5. 2.5. 文档滚动标签

Android 9.0(Android P), Google对Android的控制加强了. 而且, 影响所有应用.

官网见这里

今后在Android P系统上运行的所有应用, 可能都会受到影响, 不管这个应用以什么API为TargetAPI.

我按照官网的区分方式来搬运内容, 分为针对所有API级别的应用针对Android P的应用

在Android P上运行的所有应用

后台应用中的输入和数据隐私

限制了后台应用访问用户输入和传感器数据的能力. 如果应用在后台运行, 系统限制:

  • 应用不能放问摄像头或麦克风. – 这意味着偷偷录音录像恐怕不行, 但是我们天才的开发人员可能会搞个1像素的前台应用来规避.
  • 使用连续报告模式的传感器(例如加速度计和陀螺仪)不会接收事件. – 大概无法在后台持续获取运动速度.
  • 使用发送变化时或一次性报告模式的传感器不会接收事件. – 大概无法在后台获取传感器变化.

如果要检测传感器事件, 需要使用前台服务.
但是如果你使用的是SensorManager的实例来调用flush()方法, 则不受影响.
这个变更可能会影响后台检测传感器数据的应用, 例如地图等.

设备安全性变更

提供密钥轮转和系统调用保护, 具体变更见安全行为变更.
加密算法实现发生变更, 部分加密算法参数(AES, DESEDE, OAEP, EC)的Bouncy Castle版本在Android P中已经弃用, 如果App的目标是Android 8.1 (API 27)及以下, 使用上述已弃用的算法实现, 会收到警告信息, 如果目标是28及以上会引发NoSuchAlgorithmException异常.

应用兼容性变更

对某些非SDK函数和字段的使用进行了限制. 这个就是盛传的禁用非公开API的限制. 无论是直接访问还是通过反射或JNI方式访问, 这些限制都适用. 在Developer Preview 1版本中, 访问这些API或字段, 平台会通过toast和日志方式提醒你注意. 官方的说明文档详细解释了非SDK接口的定义以及警告的方式.
这个变更, 最有可能影响到的就是通过反射调用私有接口的一系列操作, 特别是热修复/插件化/Xposed等. 关于这点, 360的技术团队已经替我们走了一遍代码, 具体见Android P调用隐藏API限制原理突破限制的方法.

ICU库更新

ICU是International Components for Unicode, 它本是一个单独的项目Android官网说明, Android引用了它来完成国际化支持, 例如拾取, emoji, 文本等. 它的公开API在android.icu包下.
现在它的版本更新到了60.
由于它被平台内部使用, 所以即便我们没有直接用到icu包内的API, 也要注意我们引用的其他API可能对它有间接引用, 从而受到影响.
特别是: 用到java.text.SimpleDateFormatjava.text.DateFormatSymbols.getZoneStrings()中关于时区的表示形式已经发生变更.

不再支持Android安全加密文件(ASEC)

Android安全加密文件(ASEC)在API 8引入, 用于支持原始的SD卡加载应用功能. Android 6.0(API 23)替换并弃用了ASEC, 引入了”可采用的SD卡”功能.
Android 8.0(API 26)禁止在ASEC中安装新应用, 本预览版则完全移除了ASEC功能.
这个功能既然是为SD卡加载应用而生的, 那么这个功能的移除也是可以理解: 越来越多的手机已经不支持外置SD卡了.
用到ASEC这个技术的应用(例如虚拟桌面等app), 特别是自定义rom的厂商, 需要注意.

测试库

测试套件TestSuiteBuilder被弃用.
Android P框架中移除了内置的测试类, 以让开发者能更灵活地应用其他测试框架和测试库. 原测试库作为可选依赖项使用. 尽管平时可能用的比较少, 仍然建议大家看一下Android上测试应用.

Java UTF解码器

Android P中的UTF-8解码器更加严格, 其遵循Unicode标准:

  • 非最短形式的 UTF-8(例如 <C0, AF>)现在被视为格式不正确.
  • 替代形式的 UTF-8(例如 U+D800..U+DFFF)现在被视为格式不正确.
  • 最大的子部分被单个 U+FFFD 取代. 例如, 在字节序列41 C0 AF 41 F4 80 80 41中, 最大子部分为C0AFF4 80 80.其中“F4 80 80”可以是F4 80 80 80的初始子序列, 但“C0”不能是任何形式正确的代码单位序列的初始子序列. 因此, 输出应为A\ufffd\ufffdA\ufffdA.
  • 要在 Android P 中解码修改后的 UTF-8/CESU-8 序列, 请使用 DataInputStream.readUTF() 函数或 NewStringUTF() JNI 函数.

使用证书的主机名验证

使用subjectAltName(SAN)扩展程序中的可用名称进行对照证书匹配域名. 不再回退到commonName(CN).

网络地址查询可能会导致网络违规

要求名称解析的网络地址查询可能会产生网络I/O, 当这种情况发生在主线程就可能导致停顿或卡顿.
StrictMode现在可以检测以上这种情况的网络违规.
解析数字IP地址不被视为阻塞性操作.

套接字标记

在 Android P 以前的平台版本上, 如果使用 setThreadStatsTag() 函数标记某个套接字, 则当使用带 ParcelFileDescriptor 容器的binder IPC 将其发送给其他进程时, 套接字会被取消标记.(我感觉是个bug)

从 Android P 开始, 利用 binder IPC 将套接字发送至其他进程时, 其标记将得到保留. 此变更可能影响网络流量统计, 例如, 使用queryDetailsForUidTag() 函数时.
您可以通过先调用 untagSocket() 然后再将套接字发送至其他进程, 以此来保持行为跟以前一致.

在调用 shutdownInput() 函数后调用 available() 函数会返回 0.

从 Android P 开始, 当 VPN 调用 setUnderlyingNetworks() 函数时, Android 系统将会合并任何底层网络的传输和能力并返回 VPN 网络的有效网络能力作为结果.

自 Android P 开始, 已经检查 NET_CAPABILITY_NOT_METERED 的应用开发者将收到关于 VPN 网络能力和底层网络的信息.

应用无法再访问 xt_qtaguid 文件夹中的文件

不允许应用直接读取 /proc/net/xt_qtaguid 文件夹中的文件. 因为有些设备在发布时运行ANdroid P, 但没有提供这些文件.

强制执行 FLAG_ACTIVITY_NEW_TASK 要求

在Android P中, 除非设置了FLAG_ACTIVITY_NEW_TASK标志, 否则不能从非Activity的环境中启动Activity. 启动失败时会输出日志.
在Android N之前, 标志一直是被强制执行的, Android N中的一个错误会临时阻止实施标志要求. (我感觉这是一个系统bug).

屏幕旋转变更

Android P对纵向旋转模式(现更名为”旋转锁定”)有重大变更. 当设备处于旋转锁定模式时, 用户可以将屏幕锁定到顶层可见Activity所支持的任何旋转(注: 就是说横屏锁定也可以了?), Activity不应假定它始终以纵向呈现. 如果顶层Activity可以支持屏幕旋转, 则应在旋转锁定模式下提供相同的选项, 根据Activity的screenOrientation设置, 允许存在一些例外情况.
请求特定屏幕方向(例如, screenOrientation=landscape)的 Activity 会忽略用户锁定首选项, 并且行为与 Android O 中的行为相同.
可在 Android 清单中, 或以编程方式通过 setRequestedOrientation(), 在 Activity 一级设置屏幕方向首选项.
旋转锁定模式通过设置WindowManager在处理Activity旋转时使用的用户旋转首选项来发挥作用. 用户旋转首选项可能在下列情况下发生变更:

  • 当用户接收旋转建议时, 旋转首选项变为建议方向
  • 当用户切换到强制纵向应用(包括锁定屏幕, 启动器等)时, 旋转首选项变为纵向

针对Android P的应用

如果你的应用是针对Android P或更高版本开发, 或者targetSdkVersion设置为Android P或更高版本, 那么需要注意以下变动.

前台服务

需要请求FOREGROUND_SERVICE权限. 这是普通权限, 系统会自动为请求权限的应用授予此权限.
如果创建前台服务但没有请求这个权限, 则系统抛出SecurityException异常.
开发者需要注意前台服务要请求这个权限.

设备序列号访问限制

Build.SERIAL字段在API 26被弃用, 在Android P中, 该变量的值始终为UNKNOWN, 以保护用户因私.
如果需要访问设备的硬件序列号, 需要请求READ_PHONE_STATE权限, 并调用getSerial()方法.
以前有用到或依赖Build.SERIAL的开发者需要注意.

框架安全性变更

系统会执行更严格的网络和文件系统安全保障, 详见以Android P为目标平台的应用的安全行为变更

视图焦点

0面积的视图(宽度或高度为0)再不能被聚焦.
此外, Activity不再隐式分配触摸模式下的初始焦点, 需要显式请求.
Android P支持4个和8个十六进制数字的CSS颜色.
Chrome自版本52以来一直支持CSS颜色模块级别4, 但目前WebView停用此功能, 因为现有Android应用中, 在处理32位十六进制颜色时, 被Android ARGB干扰, 会导致渲染错误. 比如颜色#80ff8080, 在以Android P以下的SDK为目标的应用中, 在WebView中先导部分(被Android解读为Alpha)被忽略, 会渲染成不透明浅红色#ff8080. 现在, 以Android P或更高为目标, 则它会被解读为50%透明浅绿的#80ff80.

文档滚动标签

在Android P之前的版本中, 滚动位置在body元素上设置, 根元素的滚动值为0. Android P支持符合标准的行为, 在这种行为中滚动元素是根源素.
此外, 直接访问document.body.scrollTop document.body.scrollLeft document.documentElement.scrollTopdocument.documentElement.scrollLeft会因为目标SDK的不同而具有不同的行为. 要访问视口(ViewPort)滚动值, 需要使用document.scrollingElement(若有).

文章目录
  1. 1. 在Android P上运行的所有应用
    1. 1.1. 后台应用中的输入和数据隐私
    2. 1.2. 设备安全性变更
    3. 1.3. 应用兼容性变更
    4. 1.4. ICU库更新
    5. 1.5. 不再支持Android安全加密文件(ASEC)
    6. 1.6. 测试库
    7. 1.7. Java UTF解码器
    8. 1.8. 使用证书的主机名验证
    9. 1.9. 网络地址查询可能会导致网络违规
    10. 1.10. 套接字标记
    11. 1.11. 应用无法再访问 xt_qtaguid 文件夹中的文件
    12. 1.12. 强制执行 FLAG_ACTIVITY_NEW_TASK 要求
    13. 1.13. 屏幕旋转变更
  2. 2. 针对Android P的应用
    1. 2.1. 前台服务
    2. 2.2. 设备序列号访问限制
    3. 2.3. 框架安全性变更
    4. 2.4. 视图焦点
    5. 2.5. 文档滚动标签