Android N Multi window


Multi Window 是Android N中引入的一个重要的新功能。 本文介绍跟Multi Window 相关的系统实现及应用编程。


一.     Multi Window 简介

        Android N 允许多个APP在屏幕上同时显示。 如下图所示, 两个app同时显示在屏幕上:


 


在不同的设备上,Multi window 的功能也略有不同:

1.    在手机上,Android N 提供split-screen mode. 也就是屏幕上只能同时显示两个APP , 左右或者上下, 如上图所示.用户可以拖拽中间的的分割线划分窗口的大小。

如何进入split screen mode :

a.    用户在full screen mode 下,长按resent key , 会进入split-screen mode.

b.    正常界面下,按resent key, 按住一个activity,按提示拖拽至屏幕上方, 进入split-screen mode。

2.    在android TV 上,Android N 提供picture- in- picture mode,即用户可以变看video边浏览其他应用。用户可以将播放Video的窗口放在屏幕一角,然后去浏览其他app。PIP 窗口的大小为240x135 dp。可以显示在屏幕四个角的任意一角并且在所有窗口中之上。如下图。


 

3.    大屏幕设备例如平板可以选择使用freeform mode。也就是用户可以任意改变窗口大小。这种模式下,既可以使用split –screen mode, 也可以使用freeform mode。


二.    Multi window 生命周期

        Multi window 模式下activity 的生命周期和正常模式下是相同的。 同时显示的几个activity中,最上层的是刚刚和用户有过交互的activity。 这个activity 是在resume 状态。其他的activity 尽管也完全显示在屏幕上,但是是处于pause 状态。只有用户在屏幕上点击某个pause 状态的activity 时, 这个activity 才会切换到resume 状态,原来在resume状态的activity转入pause状态。

        要注意的一点是,在multi window 模式下,video 播放器app 可能完全显示在屏幕上,但是状态是pause。 这种情况下,app最好在pause 状态也能继续播放video , 进入stop状态后再停止播放。同样,在 onStart 时恢复video播放, 而不是onResume。

        一个app在进入 multi window mode, 或者app 尺寸发生变化,或者从multi window mode 返回全屏的时候, 系统会通知app configuration change 。 相应的处理跟以前configuration change 一样。

        如果APP想处理configuration change, 在manifest文件声明的时候, 最好使用以下声明, 注意加上screenLayout, 因为在屏幕由全屏转为multiwindow时, 可能会导致screenlayout变化,比如从normal到small.

   android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"

        如果窗口尺寸变大, app 不能及时地绘制新的图形,那么变化的部分会临时用窗口背景色(windowBackground)填充。


三.    App 配置是否支持multi window

        App 可以在AndroidManifest.xml 文件中配置是否支持multi window. 注意的一点是,如果task中的root activity 支持multi window, 那么这个task 中的所有activity 都会支持multi window。

固定方向的app(只能横屏或者竖屏显示) 不支持multiwindow。

具体在AndroidManifest.xml中的设置如下:

1.    在application 或者activity下,disable 或者enable multi window, 默认值为true:

        android:resizeableActivity=["true" | "false"]

2.    设置layout. 可以在activity的layout 元素下设置以下值。

•    android:defaultWidth

      在freeform mode下,默认的宽度。

•    android:defaultHeight

                  在freeform mode下,默认的高度。

•    android:gravity

      在freeform mode下, activity初次启动时在屏幕上的位置。比如水平居中,垂直居中等。具体值可以参见:

                    https://developer.android.com/reference/android/view/Gravity.html?hl=mr

•    android:minHeight, android:minWidth

      在split-screen 和 freeform mode 下, activity的最小宽度和高度.如果用户在split-screen mode 下拖拽分割符,导致一个activity小于要求的最小尺寸,系统会自动剪切activity。

      下面是一个设置的例子 :


<activity android:name=".MyActivity">

    <layout android:defaultHeight="500dp"

          android:defaultWidth="600dp"

          android:gravity="top|end"

          android:minHeight="450dp"

          android:minWidth="300dp" />

</activity>


四.    Android N 提供了一些新的activity API:

•    Activity.isInMultiWindowMode()

       是否在multi window mode 下

•    Activity.isInPictureInPictureMode()

        是否在picture-in-picture mode下。如果isInPictureInPictureMode返回true, 那么isInMultiWindowMode也会返回true.

•    Activity.onMultiWindowModeChanged()

       只要activity 进入或者退出multi  window, 系统都会调用该方法。传入参数为true, 则是进入multi window mode. False, 退出multi window mode.

•    Activity.onPictureInPictureModeChanged()

        只要activity 进入或者退出picture-in-picture mode系统都会调用该方法。传入参数为true, 则是进入。 False, 退出picture-in-picture mode。

         Fragment也提供了以上同样的API。

•    Activity.enterPictureInPictureMode()

       调用该函数,activity 会进入picture-in-picture 模式。

五.    如何以multi window Mode 启动一个activity

1.    当启动一个activity 时,在intent中加入以下flag:

                     intent.FLAG_ACTIVITY_LAUNCH_TO_ADJACENT

         使用该flag 表示你希望新启动的activity 在屏幕上挨着当前的activity。那么如果当前设备是在split-screen模式下,这个新的activity 会与现在的activity 共享屏幕,即新的activity显示在屏幕的另一部分上。但是需要注意的是,系统并不保证一定能够实现这种效果。

        如果当前屏幕并不在split-screen模式下,这个flag会被忽略,没有任何效果。

2.    新启动的activiity的尺寸和在屏幕上位置: ActivityOptions.setLaunchBounds()。

        如果是在freeform模式下,在启动新的activit时, 可以调用函数ActivityOptions.setLaunchBounds()指定新启动的activiity的尺寸和在屏幕上位置。如果当前设备没在freeform模式下,该函数没有任何效果。

         注意,如果一个activity是被启动在与当前activity相同的task中 ,那么 这个新启动的activity会覆盖当前activity所在屏幕上的位置,  并且继承所有的前一个activity的mulit-window 属性。如果想要启动一个activity在不同的window 上,必须在一个新的task中启动activity.


六.    对拖拽的支持(drag and drop)

        如果两个activity同时显示在屏幕上,用户可以从一个activity拖拽数据到另一个activity中。

        Android N的SDK中拓展了android.view包的内容,支持跨app的数据拖拽。主要有以下一些:

•    android.view.DropPermissions

     Token 对象负责指定这个权限给接受拖拽数据的app。

•    View.startDragAndDrop()

      替代View.startDrag()的新方法,View.startDrag()建议不再使用。 这个函数enable 跨activity的拖拽。传送一个新的flag  View.DRAG_FLAG_GLOBAL. 如果需要给出URI permission 到接受方,传送另一个新的flag: View.DRAG_FLAG_GLOBAL_URI_READ 或者 View.DRAG_FLAG_GLOBAL_URI_WRITE

•    View.cancelDragAndDrop()

     Cancels 当前进行中的拖操作。只用被发起拖拽操作的app调用。

•    View.updateDragShadow()

     替换当前进行的拖拽操作的拖拽阴影(不知道是不是这么翻译, 就是拖拽时的一个缩略图)。只能由发起拖拽的app 调用。

•    Activity.requestDragAndDropPermissions()

     请求一个permission , 允许传输content URIs。 这个URI 包含在DragEven的ClipData 中。


七.    Framework 实现

       简单介绍一下framework的实现。Android L在ActivityManagerService 和WindowManagerService中引入了Stack的概念, 这个stack在多窗口模式下扮演了重要的角色,一个窗口对应一个stack.

        Multi window必然涉及到activity 显示尺寸的变化,以前每个窗口都对应一个Configuration信息记录当前系统的方向,屏幕尺寸,屏幕密度等情况,系统根据这个configuration信息去配置相应的显示资源。Android N上除了以前的configuration 信息,系统还为每个窗口都新增加了一个参数mOverrideConfig, 这个记录了当前状态下窗口的configuration信息。例如当前屏幕为竖屏并在split-screen模式下,mConfig记录的是全屏的尺寸,如方向为纵向,而mOverrideConfig会记录当前实际显示的屏幕信息, 例如屏幕size会缩小一半,方向也会变为横向。系统会根据 mOverrideConfig中的信息配置显示资源。


参考文档:

https://developer.android.com/preview/features/multi-window.html?hl=mr

https://developer.android.com/preview/features/picture-in-picture.html

 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android中intent multi_task flag的具体含义是指当打开一个新的Activity时,如果设置了multi_task flag,则会在后台创建新的task,而不是在当前task中打开新的Activity。 ### 回答2: Android中,Intent的multi_task标志是指一个意图可以同时启动多个任务。当我们在启动一个Activity时,可以设置Intent的flags属性为FLAG_ACTIVITY_MULTIPLE_TASK。这个标志告诉系统,当前的Activity可以在其自己的任务栈中启动。 具体来说,当我们使用multi_task标志时,通过startActivity()方法启动Activity时,系统会根据设置的flag来决定Activity的启动行为。如果该Activity已经存在于一个任务栈中,那么系统会创建一个新的任务栈,并在新的任务栈中启动这个Activity。这样可以同时打开多个相同的Activity,并且它们各自运行在不同的任务栈中。 使用multi_task标志可以实现一些特定的功能需求,比如多窗口分屏、在同一个应用中同时打开多个相同的Activity等。通过在Intent中设置这个标志,我们可以灵活地控制Activity的启动模式,增加用户的使用体验。 需要注意的是,使用multi_task标志时,要特别小心各个Activity之间的共享数据和资源的问题,需要进行适当的处理,以免出现意外情况。同时,使用该标志时,也要考虑到设备的性能和用户的使用习惯,避免过多占用系统资源。 总之,Intent的multi_task标志是指可以同时启动多个任务的意图。在Android开发中,我们可以通过设置这个标志来控制Activity的启动行为,从而满足不同功能需求。 ### 回答3: 在Android中,Intent是一种在组件之间传递信息的机制。Intent有很多的标志位(flag)可用于指定Intent的行为。其中,multi_task flag是一个用于指定启动Activity时的行为的标志位。 multi_task flag代表启动一个新的任务(Task)。在Android中,一个任务是一系列相关联的活动(Activity)的集合。当我们使用Intent启动一个Activity时,系统会创建一个新的任务,并将该Activity添加到该任务中。 具体来说,使用multi_task flag启动一个Activity时,系统会为该Activity创建一个独立的任务,并将该Activity置于任务栈的顶部。该Activity会显示在最近使用过的应用列表中,并且可以通过系统的任务切换(Task Switcher)功能进行切换。 multi_task flag的具体含义是允许Activity在独立的任务中运行。对于需要在不同任务之间切换的场景,例如在多窗口模式下同时运行多个应用程序,或者在某些设备的分屏模式下使用多个应用程序时,使用multi_task flag可以很方便地创建并切换任务。 需要注意的是,使用multi_task flag启动Activity时,可能会受到一些限制。例如,一些权限和启动模式可能会影响Activity是否能够在新的任务中启动。因此,在使用multi_task flag启动Activity时,需要仔细考虑相关的权限和启动模式设置。 总之,Androidmulti_task flag具体含义是允许Activity在独立的任务中运行,以实现在不同任务之间切换的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值