目前谷歌已经放出了Android O(8.0)的预览版,但很多app并没有使用6.0以来的新特性。下面就结合官方文档和自己工作中需要的一些问题,简单总结了下,在对您的应用进行针对target23以其以上重构时,需要注意和兼容的问题。
一,低耗电模式。
Android 6.0(API 级别 23)引入了低电耗模式,当用户设备未插接电源、处于静止状态且屏幕关闭时,该模式会推迟 CPU 和网络活动,从而延长电池寿命。而 Android 7.0 则通过在设备未插接电源且屏幕关闭状态下、但不一定要处于静止状态(例如用户外出时把手持式设备装在口袋里)时应用部分 CPU 和网络限制,进一步增强了低电耗模式。
A.网络访问的限制
在涉及到网络访问,特别时后台访问网络的,需要测试下,在低耗电模式下,应用是否执行正常,会不会anr或者崩溃
B.后台唤醒机制
即对齐唤醒,主要涉及到的是WakeLockAlarm,后台的一些定时服务,可能会不准
二,后台优化
Android 7.0移除了三项隐式广播,以帮助优化内存使用和电量消耗。此项变更很有必要,因为隐式广播会在后台频繁启动已注册侦听这些广播的应用。删除这些广播可以显著提升设备性能和用户体验。
A. CONNECTIVITY_ACTION
面向 Android 7.0 开发的应用不会收到CONNECTIVITY_ACTION广播,即使它们已有清单条目来请求接受这些事件的通知。在前台运行的应用如果使用BroadcastReceiver请求接收通知,则仍可以在主线程中侦听CONNECTIVITY_CHANGE。
B. ACTION_NEW_PICTURE
C. ACTION_NEW_VIDEO
应用无法发送或接收ACTION_NEW_PICTURE或ACTION_NEW_VIDEO广播。此项优化会影响所有应用,而不仅仅是面向 Android 7.0 的应用。
三,权限更改
A.私有文件的文件权限不应再由所有者放宽,为使用MODE_WORLD_READABLE和/或MODE_WORLD_WRITEABLE而进行的此类尝试将触发SecurityException。
B.当你跨package域传递file://的URI时,接收者得到的将是一个无权访问的路径,将会触发FileUriExposedException。官方推荐的方式是使用FileProvider,也可以使用ContentProvider
Eg:调用系统相机拍照并存入指定路径中
Api24之前,可以这样
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Uri uri = Uri.fromFile(sdcardTempFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
Target=24时,会报crash FileUriExposedException
Target24上的正确方法是:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); ContentValues contentValues = new ContentValues(1); contentValues.put(MediaStore.Images.Media.DATA, sdcardTempFile.getAbsolutePath());
Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);
或者使用FileProvider方式
这块儿,分享模块或者其他有 调起三方应用并给其传递我们应用理解的图片等文件资源的话,会存在这个问题。这块儿有个帖子写到了他们的解决办法
http://www.jianshu.com/p/68a4e8132fcd
四,屏幕缩放
Android 7.0 支持用户设置显示尺寸,以放大或缩小屏幕上的所有元素,从而提升设备对视力不佳用户的可访问性。用户无法将屏幕缩放至低于最小屏幕宽度
在android N上,Setting多了一个Display size设置,更改这个属性,系统会以如下方式通知正在运行的应用:
A.如果是面向API级别23或更低版本系统的应用,系统会自动终止其所有后台进程。这意味着如果用户切换离开此类应用,转而打开Settings屏幕并更改Display size设置,则系统会像处理内存不足的情况一样终止该应用。如果应用具有任何前台进程,则系统会如处理运行时更改中所述将配置变更通知给这些进程,就像对待设备屏幕方向变更一样。
B.如果是面向Android 7.0的应用,则其所有进程(前台和后台)都会收到有关配置变更的通知
在这里,需要测试这几个方面的问题:
a.界面显示问题,既在用户更改了这个属性时,整个界面元素的大小都会变化,需要测试此时我们的界面是否ok
b.当设备配置发生变更时,更新任何与密度相关的缓存信息
五,NDK应用链接至平台库
从 Android 7.0 开始,系统将阻止应用动态链接非公开 NDK 库,这种库可能会导致您的应用崩溃。
即使您的代码可能不会链接私有库,但您的应用中的第三方静态库可能会这么做。因此,所有开发者都应进行相应检查,确保他们的应用不会在运行 Android 7.0 的设备上崩溃。
Logcat会给我们一些提示。
应用面向 API 级别 24 或更高级别,logcat 会生成以下运行时错误,您的应用可能会崩溃:
java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by
"/system/lib/libnativeloader.so" is not accessible for the namespace
"classloader-namespace"
at java.lang.Runtime.loadLibrary0(Runtime.java:977)
at java.lang.System.loadLibrary(System.java:1602)
利用 Android 7.0DK 中的 readelf 工具,您可以通过运行以下命令生成给定.so文件的所有动态链接的共享库列表:
aarch64-linux-android-readelf -dW libMyLibrary.so
六,Android for Work
可以使用DevicePolicyManagewr.getWifiMacAddress()访问设备的 WLAN MAC 地址。如果设备上从未启用 WLAN,则此方法将返回一个null值。
七,权限,重要的权限需要授权。
网上很多开源的授权工具类,例如这个
八,其他
悬浮窗授权。 很多时候程序里面有在当前界面弹出一个授权窗口,引导用户去授权或者开启辅助选项等。在api24上,需要对在当前页面弹窗这一动作授权
Note:If the app targets API level 23 or higher, the app user must explicitly grant this permission to the app through a permission management screen. The app requests the user's approval by sending an intent with actionACTION_MANAGE_OVERLAY_PERMISSION. The app can check whether it has this authorization by callingSettings.canDrawOverlays().
Constant Value: "Android.permission.SYSTEM_ALERT_WINDOW"
代码如下:
if (Build.VERSION.SDK_INT >= 23) {
if(!Settings.canDrawOverlays(getApplicationContext())) {
//启动Activity让用户授权
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(intent);
return;
} else {
//执行6.0以上绘制代码
}
} else {
//执行6.0以下绘制代码
}
网友评论