Android O 适配详细指南

news2024/11/26 6:07:16

NotificationChannel channel = new NotificationChannel(mChannelId, name, NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
}
}
// 创建通知传入channelId
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NotificationBarManager.getInstance().getChannelId());

developer.android.com/about/versi…

2. 后台执行限制

如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用 startService() 函数,则该函数将引发一个 IllegalStateException。

我们无法得知系统如何判断是否允许应用创建后台服务,所以我们目前只能简单 try-catch startService(),保证应用不会 crash,示例代码:

Intent intent = new Intent(getApplicationContext(), InitializeService.class);
intent.setAction(InitializeService.INITIALIZE_ACTION);
intent.putExtra(InitializeService.EXTRA_APP_INITIALIZE, appInitialize);
ServiceUtils.safeStartService(mApplication, intent);

public static void safeStartService(Context context, Intent intent) {
try {
context.startService(intent);
} catch (Throwable th) {
DebugLog.i(“service”, "start service: " + intent.getComponent() + "error: " + th);
ExceptionUtils.printExceptionTrace(th);
}
}

developer.android.com/about/versi…

3. 允许安装未知来源应用

针对 8.0 的应用需要在 AndroidManifest.xml 中声明 REQUEST_INSTALL_PACKAGES 权限,否则将无法进行应用内升级。

4. 主题的 Activity 设置屏幕方向

针对 8.0 的应用,设置了透明主题的Activity,再设置屏幕方向,代码如下:


将会抛出以下异常:

java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation

大概意思是:只有不透明的全屏Activity可以自主设置界面方向

即使满足上述条件,该异常也并非一定会出现,为什么这么说,看下面两种表现:

  • targetSdk=26,满足上述条件,API 26 手机没问题,API 27 手机没问题
  • targetSdk=27,满足上述条件,API 26 手机Crash,API 27 手机没问题

有点摸不清 Google 的套路了……

可知,targetSdk=26 时,API 26 和 27 都没有问题,所以这个坑暂时放在适配 API 27 时再填吧。

5. 桌面图标适配

针对 8.0 的应用如果不适配桌面图标,则应用图标在 Launcher 中将会被添加白色背景:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

适配方法:一起来学习Android 8.0系统的应用图标适配吧

适配后的效果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6. 隐式广播

由于 Android 8.0 引入了新的广播接收器限制,因此您应该移除所有为隐式广播 Intent 注册的广播接收器。将它们留在原位并不会在构建时或运行时令应用失效,但当应用运行在 Android 8.0 上时它们不起任何作用。

显式广播 Intent(只有您的应用可以响应的 Intent)在 Android 8.0 上仍以相同方式工作。

这个​
新增限制有一些例外情况。如需查看在以 Android 8.0 为目标平台的应用中仍然有效的隐式广播的列表,请参阅隐式广播例外。

developer.android.com/about/versi…

我对隐式广播的理解:

未指定广播接收器类名,通过 Action 发送。如有不妥,还请指教。

需要检查应用静态注册的隐式广播,需要改为动态注册。

7. 网络连接和 HTTP(S) 连接

Android 8.0 对网络连接和 HTTP(S) 连接行为做出了以下变更:

  • 无正文的 OPTIONS 请求具有 Content-Length: 0 标头。之前,这些请求没有 Content-Length 标头。

  • HttpURLConnection 在包含斜线的主机或颁发机构名称后面附加一条斜线,使包含空路径的网址规范化。例如,它将 example.com 转化为 example.com/。

  • 通过 ProxySelector.setDefault() 设置的自定义代理选择器仅针对所请求的网址(架构、主机和端口)。因此,仅可根据这些值选择代理。传递至自定义代理选择器的网址不包含所请求的网址的路径、查询参数或片段。

  • URI 不能包含空白标签。 之前,平台支持一种权宜方法,即允许主机名称中包含空白标签,但这是对 URI 的非法使用。此权宜方法只是为了确保与旧版 libcore 兼容。开发者如果对 API 使用不当,将会看到一条 ADB 消息:“URI example…com 的主机名包含空白标签。此格式不正确,将不被未来的 Android 版本所接受。”Android 8.0 废除了此权宜方法;系统对格式错误的 URI 会返回 null。

  • Android 8.0 在实现 HttpsURLConnection 时不会执行不安全的 TLS/SSL 协议版本回退。

  • 对隧道 HTTP(S) 连接处理进行了如下变更: 在通过连接建立隧道 HTTP(S) 连接时,系统会在 Host 行中正确放置端口号 (:443) 并将此信息发送至中间服务器。之前,端口号仅出现在 CONNECT 行中。 系统不再将隧道连接请求中的 user-agent 和 proxy-authorization 标头发送至代理服务器。 在建立隧道时,系统不再将隧道 Http(s)URLConnection 中的 proxy-authorization 标头发送至代理。相反,由系统生成 proxy-authorization 标头,在代理响应初始请求发送 HTTP 407 后将其发送至此代理。

同样地,系统不再将 user-agent 标头由隧道连接请求复制到建立隧道的代理请求。相反,库为此请求生成 user-agent 标头。

  • 如果之前执行的 connect() 函数失败,send(java.net.DatagramPacket) 函数将会引发 SocketException。 如果存在内部错误,DatagramSocket.connect() 会引发 pendingSocketException。对于 Android 8.0 之前的版本,即使 send() 调用成功,后续的 recv() 调用也会引发 SocketException。为确保一致性,现在这两个调用均会引发 > SocketException。
  • 在回退到 TCP Echo 协议之前,InetAddress.isReachable() 会尝试执行 ICMP。 对于某些屏蔽端口 7 (TCP Echo) 的主机(例如 google.com),如果它们接受 ICMP Echo 协议,现在也许能够访问它们。 对于确实无法访问的主机,此项变更意味着调用需要两倍的时间才能返回结果。

developer.android.com/about/versi…

这点应用一般无需适配

8. 视图焦点

可点击的 View 对象现在默认也可以成为焦点。如果您希望 View 对象可点击但不可成为焦点,请在包含 View 的布局 XML 文件中将 android:focusable 属性设置为 false,或者将 false 传递至应用界面逻辑中的 setFocusable()。

developer.android.com/about/versi…

这点基本无需适配

9. 权限

在 Android 8.0 之前,如果应用在运行时请求权限并且被授予该权限,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。

对于针对 Android 8.0 的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。

例如,假设某个应用在其清单中列出 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE。应用请求 READ_EXTERNAL_STORAGE,并且用户授予了该权限。如果该应用针对的是 API 级别 24 或更低级别,系统还会同时授予 > WRITE_EXTERNAL_STORAGE,因为该权限也属于同一 STORAGE 权限组并且也在清单中注册过。如果该应用针对的是 Android 8.0,则系统此时仅会授予 READ_EXTERNAL_STORAGE;不过,如果该应用后来又请求 > WRITE_EXTERNAL_STORAGE,则系统会立即授予该权限,而不会提示用户。

developer.android.com/about/versi…

考拉中的权限都是按需申请的,不需要修改。

10. Tinker

特别是在Android N之后,由于混合编译的inline策略修改,对于市面上的各种方案都不太容易解决。而Tinker热补丁方案不仅支持类、So以及资源的替换,它还是2.X-8.X(1.9.0以上支持8.X)的全平台支持。

github.com/Tencent/tin…

经测试,Tinker在8.0上功能正常。

总结

随着 Android 版本的不断迭代,Android 系统的体验已经越来越好了。
Android 系统的绚烂多彩离不开广大的 Android 开发者,我们作为开发者,我们应该尽快适配 Android 新版本,让我们的应用拥有最好的体验。
本篇介绍了 Android O 的适配要点,如有不足,还请指教
下一篇将会介绍 Android P 的适配,敬请期待
参考:

Android 绿色应用公约
统一推送联盟

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取
望能够帮助到想自学提升又不知道该从何学起的朋友。**

[外链图片转存中…(img-6t8Hdu4j-1719078194778)]一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1851932.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux详解】缓冲区优化 | 进度条的实现 | Linux下git 的上传

目录 一. 缓冲区 1. 缓冲区概念 2. 缓冲区作用 2.1 提升读写效率 2.2 减少等待时间 3. 缓冲区刷新策略 3.4 特殊策略 4. 缓冲区存储位置 5. 总结 二. 实现进度条 引入:倒计时 process.c 三. Linux下git的上传 sum 一. 缓冲区 1. 缓冲区概念 缓冲区是…

C++实现自动生成c++类中的属性的get和set方法

目录 应用场景 运行准备 代码展示 结果显示 应用场景 当我们在编写类的属性时,需要对该属性进行封装,需要一系列的get和set的方法。例如下面是天气类的成员属性。可以看到属性很多,而写get和set都是一些固定的操作,因此可以直…

Swift 中的动态数组

Swift 的 Array 类型是一种强大而灵活的集合类型,可以根据需要自动扩展或缩减其容量。 动态数组的基本概念 Swift 中的数组是基于动态数组(dynamic array)的概念实现的。动态数组能够根据需要自动调整其容量,以容纳新增的元素&a…

51单片机STC89C52RC——6.3 定时器/计数器 实现计时功能(定时器+中断系统+LCD1602液晶显示器)

目录 目的/效果 一,STC单片机模块 二,定时器 中断系统LCD1602显示 三,创建Keil项目 四,代码 五,代码编译、下载到51单片机 ​ 目的/效果 用定时器实现系统中断,计时信息显示在LCD1602上。效果如下 …

计算机组成原理----指令系统课后习题

对应的知识点: 指令系统 扩展操作码的计算: 公式: 对扩展操作码而言,若地址长度为n,上一层留出m种状态,下一层可扩展出 mx2^n 种状态 1.设计某指令系统时,假设采用 16 位定长指令字格式&#…

文件上传漏洞-下篇

一、白名单绕过 目录路径检测绕过 00截断 简介: 0x00是字符串的结束标识符,攻击者可以利用手动添加字符串标识符的方式来将后面的内容进行截断,而后面的内容又可以帮助我们绕过检测。 饶过条件 利用操作:Pass-12 要求&#xff…

“论微服务架构及其应用”写作框架,软考高级,系统架构设计师

论文真题 论微服务架构及其应用近年来,随着互联网行业的迅猛发展,公司或组织业务的不断扩张,需求的快速变化以及用户量的不断增加,传统的单块(Monolithic)软件架构面临着越来越多的挑战,已逐渐…

前端 CSS 经典:backface-visibility 属性

前言&#xff1a;backface-visibility 属性可以使反转 180deg 的元素隐藏&#xff0c;使用这个属性实现卡片翻转效果 效果 代码实现 <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" /><meta http-equiv"X-…

以太坊==MetaMask获取测试币最新网址

估算分数https://community.infura.io/t/unable-to-receive-sepolia-eth-from-faucet/7715 Gitcoin Passport 水龙头地址&#xff0c;填入自己的测试地址 水龙头项目地址 GitHub - pk910/PoWFaucet: Modularized faucet for EVM chains with different protection methods (…

51单片机STC89C52RC——6.1 中断系统

一&#xff0c;文字层面理解 反正我看下面的几段文字时脑壳没有正常运转。一个头几个大 中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。 当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求&#xff0c;要求CPU暂停当前的工作&#xff0c;转而去处理这…

接口自动化拓展:Flask框架安装、介绍及工作中的应用!

Flask是一个轻量级的Python Web框架&#xff0c;用于构建Web应用程序和API。它简洁而灵活&#xff0c;容易上手&#xff0c;并且非常适合用于开发小型到中型规模的应用程序。在接口自动化测试中&#xff0c;Flask可以作为服务器框架&#xff0c;用于搭建测试接口。 本文将从零…

Android:知道类加载过程面试还是卡壳?干货总结,一网打净“类”的基础知识!

多线程进行类的初始化会出问题吗&#xff1f; 类的实例化触发时机。 <clinit>()方法和<init>()方法区别。 在类都没有初始化完毕之前&#xff0c;能直接进行实例化相应的对象吗? 类的初始化过程与类的实例化过程的异同&#xff1f; 一个实例变量在对象初始化…

Docker(数据卷、自定义镜像、网络)

数据卷 数据卷&#xff08;volume&#xff09;是一个虚拟目录&#xff0c;是容器内目录与宿主机目录之间映射的桥梁。 命令 说明 docker volume create 创建数据卷 docker volume ls 查看所有数据卷 docker volume rm 删除指定数据卷 docker volume inspect 查看某个…

视觉新纪元:解码LED显示屏的视角、可视角、最佳视角的最终奥秘

在璀璨夺目的LED显示屏世界里&#xff0c;每一个绚烂画面的背后&#xff0c;都离不开三个关键概念&#xff1a;视角、可视角与最佳视角。这些术语不仅是衡量显示效果的重要标尺&#xff0c;也是连接观众与精彩内容的桥梁。让我们一起走进这场视觉盛宴&#xff0c;探索那些让LED…

keepalived高可用,nginx+keepalived+apache架构的实现

目 录 一、概述&#xff1a; 二、实验架构图如图所示&#xff1a; 三、实验环境&#xff1a; 四、实现效果&#xff1a; 五、实验解析及步骤&#xff1a; 六、具体实现&#xff1a; 6.1 先关闭防火墙和核心防护&#xff1a;两条命令&#xff1a; 6.2 后端apache服务…

SSL/TLS握手

文章目录 SSL/TLSTLS历史发展层次结构SSL/TLS握手协议TLS1.2 Vs TLS1.3 安全通信协议是一类用于保护计算机网络上数据传输安全的协议。这些协议通过加密、身份验证和数据完整性机制来防止数据被窃听、篡改或伪造。以下是一些主要的安全通信协议&#xff1a;SSL/TLS, IPsec, SSH…

Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案

初始化数据 */ private void initData(Bundle savedInstanceState) { if (savedInstanceState ! null) mDatas savedInstanceState.getStringArrayList(“mDatas”); if (mDatas null) { mLoadingDialog new LoadingDialog(); mLoadingDialog.show(getFragmentMana…

CSS的 text-decoration

text-decoration text-decoration CSS 简写属性设置文本上的装饰性线条的外观。它是 text-decoration-line、text-decoration-color、text-decoration-style 和较新的 text-decoration-thickness 属性的缩写。 MDN text-decoration text-decoration 可以设置1到4个参数, 允许…

Type-C连接器厂商对检测实验室的要求及重要性解析

Type-C连接器厂商对检测实验室的要求与重要性 Type-C连接器作为一种高速、全功能的接口标准&#xff0c;被广泛应用于各类电子产品中。作为Type-C连接器的制造商&#xff0c;对于产品的质量和性能要求是至关重要的。为了确保产品符合规范并满足市场需求&#xff0c;Type-C连接…

Redis—Set数据类型及其常用命令详解

文章目录 一、Redis概述Set类型1 SADD:向集合&#xff08;Set&#xff09;中添加一个或多个成员2 SCARD:获取集合&#xff08;Set&#xff09;中成员数量3 SDIFF:获取多个集合之间的差集4 SDIFFSTORE:计算多个集合之间的差集&#xff0c;并将结果存储在指定的目标集合中5 SMEMB…