|
首先大致说一下android7.0改动的地方
Android N 这次的新特性包括多窗口的支持、通知栏支持直接回复消息、对部分广播的后台限制、网络数据节省开关等,并不多,也有很多翻译文章已经介绍。
这里主要分享对 Android N 的适配大家可能要注意什么。
还记得 6.0 对 Apache Http 库的废除导致的应用崩溃吗?
还记得 6.0 中 MAC id 始终返回为空导致的唯一 id 混合生成算法大幅失效吗? 1. Android 中 Java 的实现向 OpenJDK 8 迁移
Android 是站在 Linux 和 Java 肩膀上快速成长的,在运行时依赖 Oracle JDK,早在 2010 年甲骨文就起诉谷歌侵权 Java。在 N 中 Google 采用 OpenJDK 8 作为 Java 的实现,在 Java 实现上的一些差别可能导致应用出问题。如:
(1) ArrayList 实现中的私有属性 array 被移除,反射使用该属性的需要注意下。
(2) 随机数种子调用可能出错
Crypto 安全提供商在 OpenJDK 中不提供,而它在大家调用 SecureRandom.setSeed() 设置随机种子时会用到,OpenJDK 中需要通过 SecretKeySpec 去直接加载原始密钥或者使用真正的密钥导出函数。
有了解 OpenJDK 8 与 Oracle JDK 更多实现差别的欢迎留言。
(1) 记得 2014 年 InfoQ 大会上 Oracle 的人介绍 Java 8 的特性,当时还在想 Android 现在依赖 JDK6.0 什么时候才能到 8,现在终于等到了这一天,可惜不是你..
(2) Kotlin 还有机会吗? 2. JNI 中不允许调用非公有 API
JNI 中不允许调用非公有 API,由于命名空间的变化,在 Android N 上运行会崩溃,需要切换到对应公有 API。 3. “老人机的适配”
Android N 允许用户设置显示密度,有点像老人机模式。需要测试 App 在 sw320dp 密度下显示是否正常,及配置变更后应用是否会有异常。 4. 后台优化——三个广播被禁止监听或发送
(1) CONNECTIVITY_CHANGE 广播
对 targetVersion 设置为 Android N 的 App,在后台时不再能接收到 CONNECTIVITY_CHANGE 广播,前台不影响。
(2) ACTION_NEW_PICTURE 和 ACTION_NEW_VIDEO 广播
所有运行在 Android N 上的 App 不能发送或是接收新增图片(ACTION_NEW_PICTURE)和新增视频(ACTION_NEW_VIDEO) 的广播。 5. 权限改动
(1) GET_ACCOUNTS 权限被废弃
对 targetVersion 设置为 Android N 的 App,GET_ACCOUNTS 权限被废弃。
(2) 增加 ACTION_OPEN_EXTERNAL_DIRECTORY 权限
这个感觉就是对部存储设备写权限的保护,需要用户同意,说不定以后就慢慢废弃 WRITE_EXTERNAL_STORAGE 权限了。 6. 更严格的 Doze 模式
大家知道在 Android 6.0 中,在手机关屏且静止时,Doze 模式通过推迟 CPU 和网络操作延长底池寿命。而 Android N 则在手机关屏时就会一定程度限制 CPU 和网络操作,进入 Doze 模式一段时间后进一步限制 WakeLock、Alarm、GPS 和 Wi-Fi 扫描等,做好迎接休眠状态下更多功能受限导致的 bug 吧,哈哈。 7. 自带 ICU4J 库的子集
更方便 App 的全球化了
其实Android原生6.0也有自带分屏.
1. root
2. 用RE文件管理器打开system/build.prop找到ro.build.type这一行,
把=号后面的user改成userdebug,保存后重启.
3. 重启后,在系统设置进入开发者选项.
4. 找到“多窗口模式”,激活功能即可.
在7.0版本时我们如何去实现多窗口呢?
给wm 应用配置分屏模式
在清单文件的 或 节点中设置该属性,启用或禁用多窗口显示:
android:resizeableActivity="true"
在AndroidManifest中的布局属性
对于 Android N,<layout> 清单文件元素支持以下几种属性,这些属性影响 Activity 在多窗口模式中的行为,我们先看看下面的代码.
<activity android:name=".MyActivity">
<layout android:defaultHeight="500dp"
android:defaultWidth="600dp"
android:gravity="top|end"
android:minimalSize="450dp" />
</activity>
这些布局属性会对多窗口带来什么影响呢?看看下面.
android:defaultWidth
以自由形状模式启动时 Activity 的默认宽度。
android:defaultHeight
以自由形状模式启动时 Activity 的默认高度。
android:gravity
以自由形状模式启动时 Activity 的初始位置。
android:minimalSize
分屏和自由形状模式中 Activity 的最小高度和最小宽度。 如果用户在分屏模式中移动分界线,使 Activity 尺寸低于指定的最小值,系统会将 Activity 裁剪为用户请求的尺寸。
例如,以下节点显示了如何指定 Activity 在自由形状模式中显示时 Activity 的默认大小、位置和最小尺寸:
不同的配置下,效果会不一样
-
- 如何设置禁止分屏.
在AndroidManifest中配置UnresizableActivity的unresizable属性.
在这添加FLAG_ACTIVITY_NEW_TASK 标签开启新的任务栈,是为了避免其继承根activity的属性,比如在根activity设置了尺寸大小的话,其不设置标签属性会被继承.
Intent intent = new Intent(this, UnresizableActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
清单xml中配置unresizable属性.
<activity
android:name="com.android.multiwindowplayground.activities.UnresizableActivity"
android:resizeableActivity="false"
android:taskAffinity="" />
-
- 设置以最小尺寸方式开启分屏
在AndroidManifest中配置MinimumSizeActivity的默认尺寸,最小尺寸,
startActivity(new Intent(this, MinimumSizeActivity.class));
清单xml中配置unresizable属性.
<activity
android:name="com.android.multiwindowplayground.activities.MinimumSizeActivity"
android:launchMode="singleInstance"
android:taskAffinity="">
<layout
android:defaultHeight="500dp"
android:defaultWidth="750dp"
android:gravity="top|end"
android:minimalWidth="500dp"
android:minimalHeight="500dp" />
</activity>
-
- AndroidManifest 配置Configuration的参数会有什影响?
activity中AndroidManifest 配置Configuration的参数,会影响到分屏.
<activity
android:name=".CustomConfigurationChangeActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:launchMode="singleInstance"
android:taskAffinity=""/>
如果上面配置的参数有所变化,我们可以在onConfigurationChanged()方法中监听到.
如下:
@Override
public void onConfigurationChanged(Configuration newConfig) {
if(newConfig.orientation==Configuration.ORIENTATION_PORTRAIT) {
}
if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE) {
}
super.onConfigurationChanged(newConfig);
}
注意: 可能会监听不了参数的变化,别忘记加上权限
<uses-permission Android:name="android.permission.CHANGE_CONFIGURATION"></uses-permission>
如何处理设备配置带来的运行变化
有些设备配置可能会在运行时发生变化(例如屏幕方向、键盘可用性及语言)。 发生这种变化时,Android 会重启正在运行的 Activity(先后调用
onDestroy() 和 onCreate())。重启行为旨在通过利用与新设备配置匹配的备用资源自动重新加载您的应用,来帮助它适应新配置。
首先这个变化的过程是这样的,如果你没有在activity的属性中配置’android:configChanges=”keyboardHidden| orientation’那么默认是会走横竖屏的,也就是说会走,销毁Activity->创建Activity.
由于重启整个Activity,如果数据量比较大的情况下,用户体验会十分差(例如网络请求,复杂View的绘制,动画的渲染等),所以解决这种体验我们可以通过下面两种方式:
- 通过onSaveInstanceState()与onRestoreInstanceState()保存变动前的对象.
Android 会在销毁 Activity 之前调用 onSaveInstanceState(),以便您保存有关应用状态的数据。 然后,您可以在 onCreate() 或 onRestoreInstanceState() 期间恢复 Activity 状态。
- 通过`android:configChanges=”keyboardHidden| orientation’禁止横竖屏切换.
阻止系统在某些配置变更期间重启 Activity,但要在配置确实发生变化时接收回调(具体回调上面有代码),这样,您就能够根据需要手动更新 Activity。
多窗口的生命周期
除了知道上面的不同的配置下,效果会不一样之外,我们是不是还要注意一个问题,我们知道Activity的横竖屏会影响它的生命周期,那么对于多窗口来说,是否也会有这样的影响呢?
下面是Goodle官方的说明.
在多窗口模式中,在指定时间只有最近与用户交互过的 Activity 为活动状态。 该 Activity 将被视为顶级 Activity。 所有其他 Activity 虽然可见,但均处于暂停状态。 但是,这些已暂停但可见的 Activity 在系统中享有比不可见 Activity 更高的优先级。 如果用户与其中一个暂停的 Activity 交互,该 Activity 将恢复,而之前的顶级 Activity 将暂停。
注:在多窗口模式中,用户仍可以看到处于暂停状态的应用。 应用在暂停状态下可能仍需要继续其操作。 例如,处于暂停模式但可见的视频播放应用应继续显示视频。 因此,我们建议播放视频的 Activity 不要暂停其 onPause() 处理程序中的视频。 应暂停 onStop() 中的视频,并恢复onStart() 中的视频播放。
也就是说多窗口模式不会更改Activity的生命周期,但是在对一些需要使用到onPause()方法的为了更好体验,需要做小变动.
|