一 概述
android N的发布,最大的亮点有2个,原生系统对应用分屏的支持和快捷回复。现在只介绍分屏功能,目前最新的Android N系统支持横屏时让两个APP并排,竖屏时上下排放,而在Android TV上,原生系统也支持APP实现画中画。用户还可以在这两个App之间拖动数据,例如将一个App的Activity上的文件拖动到另外一个App的Activity中去。
用户开启分屏模式:
1点击右下角的方块,进入任务管理器,长按一个App的标题栏,将其拖入屏幕的高亮区域,这个App金进入了分屏模式。然后在任务管理器中选择另一个App,单击它使得这个App也进入分屏模式。
2打开一个App,然后长按右下角的方块,此时已经打开的这个App将进入分屏模式。然后在屏幕上的任务管理器中选择另外一个App,单击它使得这个App也进入分屏模式。
3最新发现:下拉通知栏,长按右上角的设置图标,将开启隐藏设置功能 “系统界面调谐器”,进入设置界面,最下方有系统界面调谐器选项,进入后选择 “Other”->“启用分屏上滑手势”,就可以从任务管理器上上滑进入分屏模式了。具体操作是 当一个App已经处于全屏模式时,用手指从右下角的小方块向上滑动 。这个设置将来在正式版可能有变化,所以还是不要太依赖。
二 分屏模式的生命周期
首先要说明的一点是,分屏模式没有改变Activity的生命周期。
官方说法是:在分屏模式下,用户最近操作、激活过的Activity将被系统视为 topmost 。而其他的Activity都属于 paused 状态,即使它是一个对用户可见的Activity。但是这些可见的处于 paused 状态的Activity将比那些不可见的处于 paused 状态的Activity得到更高优先级的响应。当用户在一个可见的 paused 状态的Activity上操作时,它将得到恢复 resumed 状态,并被系统视为 topmost 。而之前那个那个处于 topmost 的Activity将变成 paused 状态。
在分屏模式中,一个App可以在对用户可见的状态下进入 paused 状态,这与以往是不同的。所以你的App在处理业务时,也应该知道自己什么时候应该真正的暂停。例如一个视频播放器,如果进入了分屏模式,就不应该在 onPaused() 回调中暂停视频播放,而应该在 onStop() 回调中才暂停视频,然后在 onStart()回调中恢复视频播放。关于如何知道自己进入了分屏模式,在 Android N 的Activity API中,增加了一个 void onMultiWindowChanged(boolean inMultiWindow) 回调,所以我们可以在这个回调知道自己是不是进入了分屏模式。
当App进入分屏模式后,将会触发Activity的 onConfigurationChanged() ,这与以前我们在处理App从 横竖屏切换 时的方法一样,不同于的地方是这里是宽/高都有所改变,而 横竖屏切换 是宽高互换。我们最好处理好运行时状态的改变,否则我们的App将被重新创建,即重新以新的宽高尺寸 onCreate() 一遍。
如果用户重新调整窗口的大小,系统在必要的时候也会触发 onConfigurationChanged()。如果App的尺寸处于被拖动中还没有完全绘制完成时,系统将暂时用主题中的 windowBackground 属性来填充这些区域。
三 设置APP的分屏模式
如果你适配到了 Android N,android:resizeableActivity 的默认值就是 true ,是默认支持分屏的。该属性是在 AndroidManifest.xml 中的 <application> 或者 <activity> 标签下设置新的属性 android:resizeableActivity="true" 。设置了这个属性后,你的App/Activity就可以进入分屏模式或者自由模式 了。如果这个属性被设为false,那么你的App将无法进入分屏模式,如果你在打开这个App时,长按右下角的小方块,App将仍然处于全屏模式,系统会弹出Toast提示你无法进入分屏模式。
注意:假如你 没有适配到Android N ( target < Android N ),打包App时的 compileSDKVersion < Android N ,你的App也是可以支持分屏的!!!!原因在于:如果你的App 没有 设置 仅允许Activity竖屏/横屏 ,即没有设置类型 android:screenOrientation="XXX" 属性时,运行Android N系统的设备还是 可以 将你的App 分屏!! 但是这时候系统是不保证运行时的稳定性的,在进入分屏模式时,系统首先也会弹出Toast来提示你说明这个风险。
四 Layout attributes
在Android N中,我们可以向 manifest 文件中添加 layout 节点,并设置一些新增加的属性,通过这些属性来设置分屏模式的一些行为,如最小尺寸等。
?android:defaultWidth
?android:defaultHeight
?android:gravity
?android:minimalSize
我们可以给一个 Activity 增加一个 layout 子节点:
<activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <layout android:defaultHeight="500dp" android:defaultWidth="600dp" android:gravity="top|end" /> </activity>
五 支持拖拽
现在我们可以实现在两个分屏模式的Activity之间拖动内容了。Android N Preview SDK中,View已经增加支持Activity之间拖动的API。具体的类和方法,可以参考N Preview SDK Reference,主要用到下面几个新的接口:
?View.startDragAndDrop():View.startDrag() 的替代方法,需要传递View.DRAG_FLAG_GLOBAL来实现跨Activity拖拽。如果需要将URI权限传递给接收方Activity,还可以根据需要设置View.DRAG_FLAG_GLOBAL_URI_READ或者View.DRAG_FLAG_GLOBAL_URI_WRITE。
?View.cancelDragAndDrop():由拖拽的发起方调用,取消当前进行中的拖拽。
?View.updateDragShadow():由拖拽的发起方调用,可以给当前进行的拖拽设置阴影。
?android.view.DropPermissions:接收方App所得到的权限列表。
?Activity.requestDropPermissions():传递URI权限时,需要调用这个方法。传递的内容存储在DragEvent中的ClipData里。返回值为前面的android.view.DropPermissions。
五 测试清单
关于功能、性能方面测试,还可以按照下面的操作来进行。
?让App进入,再退出分屏模式,确保此时App功能正常。
?让App进入分屏模式,激活屏幕上的另外一个App,让自己的App进入可见、paused状态。举了例子来讲,如果你的App是一个视频播放器,那么当用户点击了屏幕上另外一个App时,你的App不应该停止播放视频,即使此时你的Activity/Fragment已经接到了onPaused()回调。
?让App进入分屏模式,拖动分栏上的小白线,改变App的尺寸。请在竖屏(两个App一上一下布局)和横屏(两个App一左一右布局)模式下分别进行改变尺寸的操作。确保App不会崩溃,各项功能正常,且UI的刷新没有花费太多时间。
?在短时间内、多次、迅速地改变App尺寸,确保App没有崩溃,且没有发生内存泄露。关于内存使用方面的更详细注意事项,请参考Investigating Your RAM Usage。
?在不同的窗口设置的情况下,正常使用App,确保App功能正常,文字仍然可读,其他的UI元素也没有变得太小,用户仍然可以舒适地操作App。