热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

详解Android版本适配:9.0Pie

一、前言 本文主要是从官方文档中筛选出一些常见的适配项,若有任何纰漏或需要补充的,欢迎大家在评论区指出。 二、版本适配 1. 限制 H

一、前言

本文主要是从官方文档中筛选出一些常见的适配项,若有任何纰漏或需要补充的,欢迎大家在评论区指出。

二、版本适配

1. 限制 HTTP 网络请求

Android 9.0 中限制了 HTTP(明文传输)网络请求,若仍继续使用HTTP请求,则会在日志中提示以下异常(只是无法正常发出请求,不会导致应用崩溃):

java.net.UnknownServiceException: CLEARTEXT communication to xxx not permitted by network security policy

适配的方法如下:

第一种

在资源目录中新建一个 xml 文件作为网络安全配置文件,例如 xml/network_security_config.xml,然后在文件中填写以下内容:

<&#63;xml version="1.0" encoding="utf-8"&#63;>

 


 在AndroidManifest.xml进行配置:


 ...

第二种(感谢 AllenChiang 同学的提醒)

Android 6.0 中引入了是否允许网络使用明文传输的配置:

原来默认为 true,但在 Android 9.0 中默认值改为了 false,因此将配置手动设为 true 即可解决明文传输被限制的问题

2. 弃用 Apache HTTP Client

由于官方在 Android 9.0 中移除了所有 Apache HTTP Client 相关的类,因此我们的应用或是一些第三方库如果使用了这些类,就会抛出找不到类的异常:

java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/conn/scheme/SchemeRegistry;

若需要继续使用 Apache HTTP Client ,可通过以下方法进行适配:

在 AndroidManifest.xml 中添加以下内容:

或者在应用中直接将 Apache HTTP Client 相关的类打包并进行引用

3. 限制非 SDK 接口的调用

3.1 简述

一直以来,官方提供的接口分为了 SDK 接口和非 SDK 接口。SDK 接口即官方支持的接口,开发者可以直接调用不会有任何限制。一般而言,SDK 接口都记录在官方的接口索引中,没有记录的就视为非 SDK 接口,例如一些使用了 @hide 标注的方法。

以往开发者对于非 SDK 接口的调用通常是利用反射或者JNI间接调用的方式进行,但这样的调用方式如果处理不当会比较容易出现一些未知的错误。为了提升用户体验和降低应用发生崩溃的风险,Android 9.0 对应用能使用的非 SDK 接口实施了限制,具体的限制手段请见下表:

此外,为了开发者能够顺利过渡到 Android 9.0,官方对非 SDK 接口进行了分类,共分为三类,light-greylist(浅灰名单)、dark-greylist(深灰名单)以及blacklist(黑名单):

  1. light-greylist(浅灰名单):对于此名单中的非 SDK 接口,官方暂未找到可替代的 SDK 接口,因此开发者仍可继续访问(如果 targetSdkVersion 大于等于28时会出现警告)。
  2. dark-greylist(深灰名单):targetSdkVersion 小于28时仍可继续使用此名单中的接口,但会出现警告提示;大于等于28时,这些接口将会限制访问。
  3. blacklist(黑名单):无论 targetSdkVersion 为多少,只要应用运行在 Android 9.0 平台上,访问此名单中的接口都会受限

3.2 如何测试应用是否使用非 SDK 接口

可以通过以下方式进行测试(详情请至官方文档):

  1. 使用 Android 9.0 或更高版本的设备调试应用
  2. 使用 StrictMode API 进行测试
  3. 使用 veridex 工具对应用进行扫描

建议使用第三种方式,该工具的扫描结果会列出应用对于三个限制名单中的接口的调用细节。

 4. 前台服务权限

在 Android 9.0 中,应用在使用前台服务之前必须先申请 FOREGROUND_SERVICE 权限,否则就会抛出 SecurityException 异常。

此外,由于 FOREGROUND_SERVICE 权限只是普通权限,因此开发者只需在 AndroidManifest.xml 中注册此权限即可,系统会自动对此权限进行授权:

5. 强制执行 FLAG_ACTIVITY_NEW_TASK 要求

在 Android 7.0(API 级别 24)之前,若开发者需要通过非 Activity context 启动 Activity,就必须设置 Intent 标志 FLAG_ACTIVITY_NEW_TASK,否则会启动失败并抛出以下异常

android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want&#63;

但这个要求在更新 Android 7.0 以后由于系统问题被临时取消了,开发者即使不设置标志也可以正常启动 Activity。而在 Android 9.0 中官方修复了这个问题,这个要求重新开始强制执行,因此开发者在适配 Android 9.0 时需要注意这个问题。

 6. 不允许共享 WebView 数据目录

Android 9.0 中为了改善应用稳定性和数据完整性,应用无法再让多个进程共用同一 WebView 数据目录。此类数据目录一般存储 COOKIE、HTTP 缓存以及其他与网络浏览有关的持久性和临时性存储。

如果开发者需要在多进程中使用 WebView,则必须先调用 WebView.setDataDirectorySuffix() 方法为每个进程设置用于存储 WebView 数据的目录。若多进程 WebView 之间需要共享数据,开发者需自己通过 IPC 的方式实现。

此外,若开发者只想在一个进程中使用 WebView,并且希望严格执行这个规则,可以通过在其他进程中调用 WebView.disableWebView() 方法,这样其他进程创建 WebView 实例就会抛出异常。

7. 其他 API 方面的修改

7.1 Region.Op 相关

Android 9.0 中如果在使用绘图裁剪功能时设置了除 Region.Op.INTERSECT 或 Region.Op.DIFFERENCE 以外的类型,就会抛出以下异常:

 java.lang.IllegalArgumentException: Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed

具体原因是官方废弃了那几个具有 Region.Op 参数的裁剪方法,如 clipRect(@NonNull RectF rect, @NonNull Region.Op op) :

 

/**
 * Modify the current clip with the specified rectangle.
 *
 * @param rect The rect to intersect with the current clip
 * @param op How the clip is modified
 * @return true if the resulting clip is non-empty
 *
 * @deprecated Region.Op values other than {@link Region.Op#INTERSECT} and
 * {@link Region.Op#DIFFERENCE} have the ability to expand the clip. The canvas clipping APIs
 * are intended to only expand the clip as a result of a restore operation. This enables a view
 * parent to clip a canvas to clearly define the maximal drawing area of its children. The
 * recommended alternative calls are {@link #clipRect(RectF)} and {@link #clipOutRect(RectF)};
 *
 * As of API Level API level {@value Build.VERSION_CODES#P} only {@link Region.Op#INTERSECT} and
 * {@link Region.Op#DIFFERENCE} are valid Region.Op parameters.
 */
@Deprecated
public boolean clipRect(@NonNull RectF rect, @NonNull Region.Op op) {
 checkValidClipOp(op);
 return nClipRect(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom,
   op.nativeInt);
}

private static void checkValidClipOp(@NonNull Region.Op op) {
 if (sCompatiblityVersion >= Build.VERSION_CODES.P
   && op != Region.Op.INTERSECT && op != Region.Op.DIFFERENCE) {
  throw new IllegalArgumentException(
    "Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed");
 }
}

对于这个问题,可以通过以下方法进行适配:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
 canvas.clipPath(path);
} else {
 canvas.clipPath(path, Region.Op.XOR);// REPLACE、UNION 等类型
}

7.2 Build.SERIAL 被弃用

Android 9.0 之前,开发者可以使用 Build.SERIAL 获取设备的序列号。现在这个方法被弃用了,Build.SERIAL 将始终设置为 "UNKNOWN" 以保护用户的隐私。
适配的方法为先请求 READ_PHONE_STATE 权限,然后调用 Build.getSerial() 方法。

以上所述是小编给大家介绍的Android版本适配9.0 Pie详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


推荐阅读
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 本文将详细介绍如何在ThinkPHP6框架中实现多数据库的部署,包括读写分离的策略,以及如何通过负载均衡和MySQL同步技术优化数据库性能。 ... [详细]
  • 在使用Maven进行项目构建时,由于依赖库的下载速度慢常常让人感到沮丧,这直接影响了开发效率和学习热情。幸运的是,阿里云提供了一个快速的国内镜像服务,能够显著提升Maven项目的构建速度。 ... [详细]
  • 深入解析BookKeeper的设计与应用场景
    本文介绍了由Yahoo在2009年开发并于2011年开源的BookKeeper技术。BookKeeper是一种高效且可靠的日志流存储解决方案,广泛应用于需要高性能和强数据持久性的场景。 ... [详细]
  • 本文探讨了SSDP(简单服务发现协议)和WSD(Web服务发现)协议,特别是SSDP如何通过固定多播地址239.255.255.250:1900实现局域网内的服务自发现功能。文中还详细介绍了SSDP协议的关键操作类型及其应用场景。 ... [详细]
  • 本文探讨了大型服务端开发过程中常见的几个误区,包括异步任务处理不当、日志同步模式使用、网络操作未设置超时、缓存命中率及响应时间未统计、单一缓存模式、分布式缓存加锁不当以及团队管理上的误区,旨在帮助开发者避免这些常见错误。 ... [详细]
  • 在Linux系统上构建Web服务器的详细步骤
    本文详细介绍了如何在Linux系统上搭建Web服务器的过程,包括安装Apache、PHP和MySQL等关键组件,以及遇到的一些常见问题及其解决方案。 ... [详细]
  • 本文详细介绍了如何在Android应用中使用GridView组件以网格形式展示数据(如文本和图像)。通过行列布局,实现类似矩阵的数据展示效果。 ... [详细]
  • 本文探讨了浏览器的同源策略限制及其对 AJAX 请求的影响,并详细介绍了如何在 Spring Boot 应用中优雅地处理跨域请求,特别是当请求包含自定义 Headers 时的解决方案。 ... [详细]
  • 本文介绍了在Android项目中实现时间轴效果的方法,通过自定义ListView的Item布局和适配器逻辑,实现了动态显示和隐藏时间标签的功能。文中详细描述了布局文件、适配器代码以及时间格式化工具类的具体实现。 ... [详细]
  • Android中实现复合旋转动画效果
    本文将探讨如何在Android应用中实现动态且吸引人的旋转动画。通过结合多种动画类型,如透明度变化、旋转、缩放和位移,可以创造出更为复杂的视觉效果。我们将从XML布局和Java代码两个方面进行详细介绍。 ... [详细]
  • MapReduce原理是怎么剖析的
    这期内容当中小编将会给大家带来有关MapReduce原理是怎么剖析的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1 ... [详细]
  • Android商城应用开发指南(第二部分):创建启动欢迎页
    大多数商城应用程序在启动时会显示一个欢迎页面,以提升用户体验。本文将指导您如何实现一个基本的欢迎页,该页面会在用户打开应用后短暂展示,随后自动跳转至主界面。 ... [详细]
  • 本文详细介绍了如何使用 PHP 编程语言输出 99 乘法表,包括使用不同的循环结构如 do-while、for 循环等方法,并提供了具体的代码示例。 ... [详细]
  • 本文探讨了使用Filter作为控制器的优势,以及Servlet与Filter之间的主要差异。同时,详细解析了Servlet的工作流程及其生命周期,以及ServletConfig与ServletContext的区别与应用场景。 ... [详细]
author-avatar
沉鈺发忠谦琪伦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有