Android7.0 之 行为变更

我只是Google的搬运工......

行为变更

本文内容

  1. 性能提升

    1. 低电耗模式
    2. 后台优化
  2. 权限更改
  3. 应用间共享文件
  4. 无障碍改进
    1. 屏幕缩放
    2. 设置向导中的视觉设置
  5. NDK 应用链接至平台库
  6. Android for Work
  7. 注解保留
  8. 其他重要说明

另请参阅

  1. Android N API 概览

Android N 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更。 本文重点介绍您应该了解并在开发应用时加以考虑的一些重要变更。

如果您之前发布过 Android 应用,请注意您的应用可能受到这些平台变更的影响。

电池和内存



Android N 包括旨在延长设备电池寿命和减少 RAM 使用的系统行为变更。 这些变更可能会影响您的应用访问系统资源,以及您的系统通过特定隐式 Intent 与其他应用互动的方式。

低电耗模式

Android 6.0(API 级别 23)引入了低电耗模式,当用户设备未插接电源、处于静止状态且屏幕关闭时,该模式会推迟 CPU 和网络活动,从而延长电池寿命。而 Android N 则通过在设备未插接电源且屏幕关闭状态下、但不一定要处于静止状态(例如用户外出时把手持式设备装在口袋里)时应用部分 CPU 和网络限制,进一步增强了低电耗模式。

图 1. 低电耗模式如何应用第一级系统活动限制以延长电池寿命的图示。

当设备处于充电状态且屏幕已关闭一定时间后,设备会进入低电耗模式并应用第一部分限制: 关闭应用网络访问、推迟作业和同步。 如果进入低电耗模式后设备处于静止状态达到一定时间,系统则会对 PowerManager.WakeLockAlarmManager 闹铃、GPS
和 Wi-Fi 扫描应用余下的低电耗模式限制。 无论是应用部分还是全部低电耗模式限制,系统都会唤醒设备以提供简短的维护时间窗口,在此窗口期间,应用程序可以访问网络并执行任何被推迟的作业/同步。

图 2. 低电耗模式如何在设备处于静止状态达到一定时间后应用第二级系统活动限制的图示。

请注意,激活屏幕或插接设备电源时,系统将退出低电耗模式并取消这些处理限制。 此项新增的行为不会影响有关使您的应用适应 Android 6.0(API 级别 23)中所推出的旧版本低电耗模式的建议和最佳实践,如低电耗模式和应用待机模式优化中所讨论。
您仍应遵循这些建议(例如使用 Google Cloud Messaging (GCM) 发送和接收消息)并开始安排更新计划以适应新增的低电耗模式行为。

Project Svelte:后台优化

Android N 删除了三项隐式广播,以帮助优化内存使用和电量消耗。 此项变更很有必要,因为隐式广播会在后台频繁启动已注册侦听这些广播的应用。 删除这些广播可以显著提升设备性能和用户体验。

移动设备会经历频繁的连接变更,例如在 Wi-Fi 和移动数据之间切换时。 目前,可以通过在应用清单中注册一个接收器来侦听隐式CONNECTIVITY_ACTION 广播,让应用能够监控这些变更。
由于很多应用会注册接收此广播,因此单次网络切换即会导致所有应用被唤醒并同时处理此广播。

同理,应用可以注册接收来自其他应用(例如相机)的隐式 ACTION_NEW_PICTURE 和 ACTION_NEW_VIDEO 广播。
当用户使用相机应用拍摄照片时,这些应用即会被唤醒以处理广播。

为缓解这些问题,Android N 应用了以下优化措施:

  • 面向 Android N 开发的应用不会收到 CONNECTIVITY_ACTION 广播,即使它们已有清单条目来请求接受这些事件的通知。
    在前台运行的应用如果使用BroadcastReceiver 请求接收通知,则仍可以在主线程中侦听 CONNECTIVITY_CHANGE
  • 应用无法发送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 广播。此项优化会影响所有应用,而不仅仅是面向
    Android N 的应用。

如果您的应用使用任何 Intent,您仍需要尽快移除它们的依赖关系,以正确适配 Android N 设备。 Android 框架提供多个解决方案来缓解对这些隐式广播的需求。 例如,JobScheduler API
提供了一个稳健可靠的机制来安排满足指定条件(例如连入无限流量网络)时所执行的网络操作。 您甚至可以使用JobScheduler 来适应内容提供程序变化。

如需了解有关 Android N 中后台优化以及如何改写应用的详细信息,请参阅后台优化

权限更改



Android N 做了一些权限更改,这些更改可能会影响您的应用。

系统权限更改

为了提高私有文件的安全性,面向 Android N 或更高版本的应用私有目录被限制访问 (0700)。 此设置可防止私有文件的元数据泄漏,如它们的大小或存在。 此权限更改有多重副作用:

应用间共享文件



对于面向 Android N 的应用,Android 框架执行的 StrictMode API
政策禁止向您的应用外公开 file:// URI。 如果一项包含文件 URI 的 Intent 离开您的应用,应用失败,并出现 FileUriExposedException 异常。

若要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。 进行此授权的最简单方式是使用 FileProvider 类。
如需有关权限和共享文件的更多信息,请参阅共享文件

无障碍改进



为提高平台对于视力不佳或视力受损用户的可用性,Android N 做出了一些更改。这些更改一般并不要求更改您的应用代码,不过您应仔细检查并使用您的应用测试这些功能,以评估它们对用户体验的潜在影响。

屏幕缩放

Android N 支持用户设置显示尺寸,以放大或缩小屏幕上的所有元素,从而提升设备对视力不佳用户的可访问性。用户无法将屏幕缩放至低于最小屏幕宽度sw320dp,该宽度是
Nexus 4 的宽度,也是常规中等大小手机的宽度。

图 3. 右侧屏幕显示的是一台运行 Android N 系统映像的设备增大显示尺寸后的效果。

当设备密度发生更改时,系统会以如下方式通知正在运行的应用:

  • 如果是面向 API 级别 23 或更低版本系统的应用,系统会自动终止其所有后台进程。 这意味着如果用户切换离开此类应用,转而打开“Settings”屏幕并更改 Display size 设置,则系统会像处理内存不足的情况一样终止该应用。 如果应用具有任何前台进程,则系统会如处理运行时变更中所述将配置变更通知给这些进程,就像对待设备屏幕方向变更一样。
  • 如果是面向 Android N 的应用,则其所有进程(前台和后台)都会收到有关配置变更的通知,如处理运行时变更中所述。

大多数应用并不需要进行任何更改即可支持此功能,不过前提是这些应用遵循 Android 最佳实践。具体要检查的事项:

  • 在屏幕宽度为 sw320dp 的设备上测试您的应用,并确保其充分运行。
  • 当设备配置发生变更时,更新任何与密度相关的缓存信息,例如缓存位图或从网络加载的资源。当应用从暂停状态恢复运行时,检查配置变更。

    注:如果您要缓存与配置相关的数据,则最好也包括相关元数据,例如该数据对应的屏幕尺寸或像素密度。 保存这些元数据便于您在配置变更后决定是否需要刷新缓存数据。
  • 避免用像素单位指定尺寸,因为像素不会随屏幕密度缩放。应改为使用与密度无关像素 (dp)
    单位指定尺寸。

设置向导中的视觉设置

Android N 在“Welcome”屏幕中加入了“Vision Settings”,用户可以在新设备上设置以下无障碍功能设置: Magnification gestureFont sizeDisplay
size
 和 TalkBack。 此项变更增强了与不同屏幕设置相关的错误的可见性。 要评估此功能的影响,您应在启用这些设置的状态下测试应用。 您可以在Settings > Accessibility 中找到这些设置。

NDK 应用链接至平台库



Android N 做了一些命名空间更改,以阻止加载非公开 API。 如果您使用 NDK,则只能使用 Android 平台提供的公开 API。 在下一个官方发布的 Android 版本上使用非公开 API 会导致应用崩溃。

为提醒您使用了非公开 API,在 Android N 设备上运行的应用会在有应用调用非公开 API 时在日志消息输出中生成一个错误。 此错误还会作为消息显示在设备屏幕上,以帮助增强您对此情况的认识。 您应检查应用代码以删除使用非公开平台 API,并使用预览版设备或模拟器全面测试应用。

如果您的应用依赖平台库,则请参见 NDK 文档,了解使用公开 API 等效项替换普通私有 API 的典型修复。 您还可以链接至平台库,而无需实现此应用,如果应用使用的库是平台的一部分(例如 libpng),但不属于 NDK,则更可如此。 此情况下,请确保您的 APK 包含您打算链接到的所有 .so 文件。

注意:有些第三方库可能会链接至非公开 API。 如果您的应用使用这些库,那么当您的应用在下一个官方发布的 Android 版本上运行时可能会出现崩溃现象。

应用不应依赖或使用不属于 NDK 的原生库,因为这些库可能会发生更改或从一个 Android 版本迁移至另一版本。 例如,从 OpenSSL 切换至 BoringSSL 即属于此类更改。 此外,不同的设备可能提供不同级别的兼容性,因为不属于 NDK 中的平台库没有兼容性要求。 如果您必须在较旧设备上访问非 NDK 库,则请依据 Android API 级别进行加载。

为帮助您诊断此类问题,下面列举了一些在您试图使用 Android N 开发应用时可能遇到的 Java 和 NDK 错误:

Java 错误示例:

java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/lib/libcutils.so"
    is not accessible for the namespace "classloader-namespace"

NDK 错误示例:

dlopen failed: cannot locate symbol "__system_property_get" referenced by ...

以下是遇到这类错误的应用的一些典型修复:

  • 可以使用标准 JNI 函数来替代使用 libandroid_runtime.so 中的 getJavaVM 和 getJNIEnv:

    AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h>
    AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
    JavaVM::AttachCurrentThread from <jni.h>.
    
  • 可以使用公开 alternative __system_property_get 来替代使用 libcutils.so 中的 property_get 符号。如需这样做,请使用__system_property_get 及以下
    include 函数:

    #include <sys/system_properties.h>
  • 应使用应用本地版本来替代使用 libcrypto.so 中的 SSL_ctrl 符号。例如,您应在 .so 文件中静态链接 libcyrpto.a,或者在应用中包含您自己的来自
    BoringSSL 或 OpenSSL 的动态 libcrypto.so

Android for Work



Android N 包含一些针对面向 Android for Work 的应用的变更,包括对证书安装、密码重置、二级用户管理、设备标识符访问权限的变更。如果您是要针对 Android for Work 环境开发应用,则应仔细检查这些变更并相应地修改您的应用。

  • 您必须先安装授权证书安装程序,然后 DPC 才能对其进行设置。 对于面向 N SDK 的个人资料和设备所有者应用,您应在设备策略控制器 (DPC) 调用DevicePolicyManager.setCertInstallerPackage() 之前安装授权证书安装程序。 如果尚未安装此安装程序,则系统会引发IllegalArgumentException
  • 针对设备管理员的重置密码限制现在也适用于个人资料所有者。 设备管理员无法再使用 DevicePolicyManager.resetPassword() 来清除或更改已经设置的密码。 设备管理员仍可以设置密码,但只能在设备没有密码、PIN 或图案时这样做。
  • 即使设置了限制,设备所有者和个人资料所有者仍可以管理帐户。而且,即使具有 DISALLOW_MODIFY_ACCOUNTS 用户限制,设备所有者和个人资料所有者仍可调用 Account Management API。
  • 设备所有者可以更轻松地管理二级用户。当设备在设备所有者模式下运行时,系统将自动设置 DISALLOW_ADD_USER 限制。 这样可以防止用户创建非托管二级用户。 此外,CreateUser() 和 createAndInitializeUser() 方法已弃用,取而代之的是DevicePolicyManager.createAndManageUser() 方法。
  • 设备所有者可以访问设备标识符。设备所有者可以使用 DevicePolicyManagewr.getWifiMacAddress() 访问设备的 Wi-Fi MAC 地址。 如果设备上从未启用 Wi-Fi,则此方法将返回一个 null 值。
  • 工作模式设置控制工作应用访问。当工作模式关闭时,系统启动器通过使工作应用显示为灰色来指示它们不可用。 启用工作模式会再次恢复正常行为。

如需了解有关 Android N 中针对 Android for Work 所做变更的详细信息,请参阅 Android for Work 更新

注解保留



Android N 在注解可见性被忽略时修复错误。这种问题将启用本不应被允许的运行时访问注解。 这些注解包括:

  • VISIBILITY_BUILD:仅应编译时可见。
  • VISIBILITY_SYSTEM:运行时应可见,但仅限基本系统。

如果您的应用依赖这种行为,请在注解中添加一项运行时必须可用的保留政策。 您可通过使用 @Retention(RetentionPolicy.RUNTIME) 来如此做。

其他重要说明


  • 如果一个应用在 Android N 上运行,但却是针对更低 API 级别开发的,那么在用户更改显示尺寸时,系统将终止此应用进程。 应用必须能够正常处理此情景。 否则,当用户从最近使用记录中恢复运行应用时,应用将会出现崩溃现象。

    您应测试应用以确保不会发生此行为。要进行此测试,您可以通过 DDMS 手动终止应用,以造成相同的崩溃现象。

    在密度发生更改时,系统不会自动终止面向 N 及更高版本的应用;不过,这些应用仍可能对配置变更做出不良响应。

  • Android N 上的应用应能够正常处理配置变更,并且在后续启动时不会出现崩溃现象。您可以通过更改字体大小 (Setting > Display > Font
    size
    ) 并随后从最近使用记录中恢复运行应用,来验证应用行为。
  • 由于之前的 Android 版本中的一项错误,系统未能将对主线程上的一个 TCP 套接字的写入操作举报为严格模式违反。 Android N 修复了此错误。呈现出这种行为的应用引发 android.os.NetworkOnMainThreadException。一般情况下,我们不建议在主线程上执行网络操作,因为这些操作通常都有可能导致 ANR 和卡顿的高尾延迟。
  • Debug.startMethodTracing() 方法族现在默认在您的共享的存储空间上的软件包特定目录中存储输出,而非 SD 卡顶级。 这意味着应用不再需要请求 WRITE_EXTERNAL_STORAGE 使用这些 API 的权限。
  • 许多平台 API 现在开始检查在 Binder 事务间发送的大负载,系统现在会将 TransactionTooLargeExceptions 再次作为 RuntimeExceptions 引发,而不再只是默默记录或抑制它们。
    一个常见例子是在 Activity.onSaveInstanceState() 上存储过多数据,导致 ActivityThread.StopInfo在您的应用面向
    Android N 时引发 RuntimeException
  • 如果应用向 View 发布 Runnable 任务,并且 View 未附加到窗口,系统会用 View 为 Runnable 任务排队;在 View 附加到窗口之前,Runnable 任务不会执行。
    此行为会修复以下错误:

    • 如果一项应用是从并非预期窗口 UI 线程的其他线程发布到 View,则Runnable 可能会因此运行错误的线程。
    • 如果 Runnable 任务是从并非环路线程的其他线程发布,则应用可能会曝光 Runnable 任务。
  • 如果 Android N 上一项有 DELETE_PACKAGES 权限的应用尝试删除一个软件包,但另一项应用已经安装了这个软件包,则系统可能要求用户确认。
    在这种情况下,应用在调用 PackageInstaller.uninstall() 时的返回状态应为 STATUS_PENDING_USER_ACTION
时间: 2024-10-14 06:00:44

Android7.0 之 行为变更的相关文章

Android7.0新特性,及Android N适配

新特性部分 Android 7.0 Nougat 提供新功能以提升性能.生产效率和安全性,主要新增了以下的新特性和优化: 一.新的Notification Android N 增加了许多新的notifications API,进行了重新的设计,引入了新的风格. 模板更新: 开发者将能够充分利用新模板,只需进行少量的代码调整. 消息样式自定义: 新增自定义样式.消息回复.消息分组等更加灵活. 捆绑通知: 系统可以将消息组合在一起(例如,按消息主题)并显示组.用户可以适当地进行 Dismiss 或

Android7.0对dlopen的改变

两个内存段 在同一个进程空间中dlopen一个.so文件,理论上在内存中是同一片区域,但实际调试中发现Android7.0(read "/proc/self/maps")中,先后读同一个.so内存中居然出现两个段! 这在低版本Android(比如4.x)中不曾出现. 如下一些blog中分析,与Android7.0对dlopen的改写有关,可能是不同命名空间下读取结果不一样,可能是对安全性的提升. Android 7.0 行为变更 NDK 应用链接至平台库 Android 7.0 dlo

[Android Pro] Android7.0系统 关于Android获取流量计数TrafficStats.getUidRxBytes(uid)和TrafficStats.getUidTxBytes(uid)返回-1解决方案

reference : http://blog.csdn.net/zhangyong7112/article/details/54574214 最近一个关于流量的项目在Android7.0系统的手机上运行,一直获取不到流量的使用数据,查看源码然后发现TrafficStats.getUidRxBytes(uid)和TrafficStats.getUidTxBytes(uid)一直都是返回的-1, // 获取某个网络UID接收和发送字节的总和 long total = TrafficStats.ge

WmS详解(二)之如何理解Window和窗口的关系?基于Android7.0源码

上篇博客(WmS详解(一)之token到底是什么?基于Android7.0源码)中我们简要介绍了token的作用,这里涉及到的概念非常多,其中出现频率最高的要数Window和窗口这一对搭档了,那么我们今天就来看看到底我们该如何理解Android系统中的Window和窗口. 窗口这个概念,从不同的角度来看它的含义不一样,如果我们从WmS(WindowManagerService)的角度来看窗口,那么这个窗口并不是一个Window类,而是一个View.用户发来的消息被WmS接收之后并不能直接发给各个

Android7.0 Doze模式分析(一)Doze介绍 &amp;amp; DeviceIdleController

 參考:http://blog.csdn.net/gaugamela/article/details/52981984 在Android M中,Google就引入了Doze模式.它定义了一种全新的.低能耗的状态. 在该状态,后台仅仅有部分任务被同意执行.其他任务都被强制停止. 在之前的博客中分析过Doze模式.就是device idle状态.可能有的地方分析的不是非常具体,如今在android7.0上又一次分析下. 一.基本原理 Doze模式能够简单概括为: 若推断用户在连续的一段时间内没有

拍照、本地图片工具类(兼容至Android7.0)

拍照.本地图片工具类:解决了4.4以上剪裁会提示"找不到文件"和6.0动态授予权限,及7.0报FileUriExposedException异常问题. package com.hb.weex.util; import android.Manifest; import android.app.Activity; import android.app.Dialog; import android.content.ClipData; import android.content.Conten

Android7.0下载Apk自动安装

Android7.0下载Apk自动安装 1. 整体需求 下载APK文件 使用DownloadManager来下载 在应用界面中展示下载进度 安装下载后的APK文件 root模式: 可以自动安装,不需要用户主动点击 正常模式: 弹出安装应用页面,需要兼容7.0以上版本 2. DownloadManager DownloadManager是Android提供的用于下载的类,使用起来比较简单,它包含两个静态内部类DownloadManager.Query和DownloadManager.Request

鹅厂bugly应用升级不能安装(Android7.0的新变化)

app升级是每一个android应用的标配了,大部分应用都会有升级提醒和apk下载安装(如果系统允许静默安装估计就没有提醒这段了). 以前的升级是自己写http下载或者通过系统提供的DownloadManager进行下载.无意间发现bugly提供下载更新服务而且免费(后来又提供了热更新),就乐呵呵的接入了sdk,毕竟是大厂的东西,值得信赖.开始用的时候用的很稳定(估计是手机厂商还没用上牛轧糖),后来就有人反应更新失败,一直提示安装,开始有些不相信直接让用户卸载重装(还好用户是公司自己人,是外人的

Android7.0 FileUriExposedException 问题解决

一.FileUriExposedException的原因 Android7.0不识别uri以file://开头,要将其转换为content://才能识别uri 二.如何解决 1.xml的创建: file_paths.xml中编写该Provider对外提供文件的目录:文件放置在res/xml/下. 为了避免和其它app冲突,最好带上自己app的包名. 文件内容: <?xml version="1.0" encoding="utf-8"?><paths