绪论
随着用户的需求增多,特别是对于一些Android平板电脑以及其他的一些Android智能设备可能有多个屏幕,用户不仅想要在主屏幕上显示内容,同样在第二屏幕上也要显示想要的内容,这样可以达到更好的体验效果。Google也是不负众望在Android4.2版本以后提供了Presentation类,可以轻松实现在两块屏幕上同时显示不同的内容。
Presentation是一个特殊的dialog,它的目的是显示内容到第二屏幕。在Presentation创建的时候关联一个目标设备,确定Presentation要显示在那个设备上,根据这个设备的信息来配置Presentation的context和resources信息。
Presentation的context与包含它的Activity的context是不相同的,用presentation的上下文来填充一个presentation的layout和加载其它的资源是非常重要的,可以确保我们加载的目标设备正确的尺寸密度assets。
当Presentation附属的display被移除的话,Presentation就会自动被取消。当创建Presentation的Activity自己处于paused或者resumed,无论Presentation在显示什么内容,该Activity就要关心对Presentation 进行pausing and resuming。
本文将讲解如何使用Presentation类做到双屏异显,以及实现的原理。
使用方法
在将presentation显示出来之前,最重要的事情就是选择要将presentation显示在哪个设备上。要选择一个presentation显示在哪个设备可能是一件非常困难的事情,因为有可能此时系统中有多个设备。与其自己猜想哪个设备是最适合显示presentation,可以让系统帮我们选择一个最好的设备。在Android系统中为我们提供了两种使用presentation的方法:
media router
选择显示presentation的设备最简单的方法就是使用Media Router,media router服务持续追踪在系统中哪个音频视频线路是可用的,当routes被选择或者不被选择,或者更好的显示presentation display的线路发生改变后media router就会发送消息。所以一些应用程序可以自动监视这些消息来在首选设备上显示或取消presentation。
首选显示presentation的设备是Media Router进行推荐的,如果应用想要显示内容在第二屏幕上就该使用该设备。有时可能没有首选显示presentation的设备,在这种情况下,应用可以在本地显示内容而不使用presentation。
下面将给出如何使用media router在首选的设备创建和显示presentation。
根据上面代码可以看出通过系统服务Media Router来选择一个合适的route,从route中来获取首选的display,如果之前已经有presentation,就要判断一下之前presentation显示的display是否与新的display相同,如果不相同说明首选的display发生了改变,就将该presentation取消,置空,再去创建,否则不用创建。如果是第一次创建presentation只要首选的display不为空就会创建该presentation,创建完成后调用presentation的show方法将该presentation显示出来。
display manager
另外一个获取首选display的方法是直接使用display Manager来获取。display manager服务提供方法枚举和描述系统中所有的设备,包括可以显示presentation的设备。display manager持续追踪系统中所有的设备,然而,并不是所有的设备都适合显示presentation,例如,如果一个Activity试图在主屏幕上显示一个presentation,它可能会掩盖自己的内容,这就象在Activity上打开一个dialog一样。
下面将给出例子,演示如何使用Display Manager获取合适的display显示presentation。
根据上面代码可以看出通过系统服务Display Manager来获取所有适合显示presentation的display列表,如果获取到了多个适合display对象,之后我们就要考虑给用户一个选择,我们选择第一个为首选的display。最后显示presentation。
获取首选显示设备
根据上文可以知道我们有两种方法使用presentation,而在本文中主要讲解第二种直接使用display Manager来获取首选display。
获取display服务
我们在Activity中使用getSystemService函数,通过参数Context.DISPLAY_SERVICE来指定要获取Service的类型。调用到Activity.java的getSystemService函数中,如果去需要创建的对象为Window manager或者search manager就直接将对象返回,因为在activity.java中有这两个对象,如果我们要获取display Service就需要继续获取。
由于Activity.java继承自ContextThemeWrapper.java,所以就会调用父类的getSystemService函数。
在父类中首先判断获取的Service是否是inflater