双屏异显在Android系统上的实现
作者:康金荣 彭宏利
来源:《软件导刊》2016年第12期
        摘 要:提出了一种在ARM/Android平台上实现双屏异显功能的方法。所谓双屏异显,即在同一软硬件平台上,实现同时驱动两块LCD屏幕,并且这两块屏幕所显示的内容可以不同。这种功能的实现一方面降低了硬件设备成本,另一方面对于提高消费场景的交互性具有重要意义。
        关键词:Android;POS;双屏异显;LCD;消费场景
        DOIDOI:10.11907/rjdk.162114
        中图分类号:TP319
        文献标识码:A文章编号:1672-7800(2016)012-0118-03
        0 引言
        近年来,随着ARM SOC与Android 生态组合的快速发展,其应用已经从智能移动终端(如智能手机、平板电脑等消费电子领域)渗透到各行各业。但受制于芯片体系结构和操作系统架构设计,在Android 平台上,通常只能实现同步双屏的一些应用,如基于智能手机的显示器应用或者基于平板电脑的投影仪应用。在这样的应用中,大屏只能作为小屏的延伸,两块不同的屏上只能显示相同的内容,专业上可称为同步双显或称双屏同显技术。但在现实应用场景中,双屏异显功能更能满足人们的需要。
        本文提出了一种在Android平台上实现双屏异显的方案。该方案以瑞芯微公司推出的RK3288芯片为硬件平台,以Android为移动操作系统,通过开发的APP实现双屏异显功能。
        1 实现原理
        Android框架中与显示相关的组件主要有Activity、Windows、WindowState、Windows Manager Service、Display Manager Service、Surface Manager/Surface Flinger、Display HAL(Hardware Abstraction Layer)以及Linux Kernel中显示方面的驱动等。Android平台的显示框架如图1所示。
        各层模块功能说明如下[1-2]:①Activity:应用程序的主要生命周期载体,显示过程中的内容提供者;②Windows:窗体组件为应用显示的载体组件,应用的界面交互将全部通过窗体组件呈现;③WindowState:窗体组件的实例,用于窗体状态运营和各属性的组成传递;④Windows Manager Service:窗口管理服务是Android系统整个运行状态中所有应用窗体的各管理服务,主要负责窗体状态的转换和上下层之间的信息传递;⑤Display Manager Service:显示设备管理服务是管理Android系统中逻辑显示设备的服务,主要响应显示参数获取和相关状态;⑥Surface Manager/Surface Finger:系统级显示管理服务,处理图形合成,显示状态切换及硬件设备参数调整等;⑦Display HAL(Hardware Abstraction Layer):对于硬件操作的抽象层,通过封装部分JNI的接口与Framework以及APP层进行互动;⑧Kernel Driver:内核驱动处理显示硬件设备细节参数运行。
        2 详细设计
        2.1 Android平台下双屏异显设计
        Android 平台在4.2版本之后新增了对于多屏的支持,主要有3种屏幕类型:主屏幕(Primary Display)、外屏幕(External Display)和虚拟屏幕(Virtual Display)。其中自
带屏幕一般识别为主屏幕,而HDMI将会被设为外屏幕。为了方便APP访问上述3种屏幕,Android还提供了一个统一的屏幕管理服务DisplayManagerService。虽然屏幕被划分为3种类型,但是建立于它们之上的窗口合成以及渲染依然统一由SurfaceFlinger管理。这些新特性的引入确保了双屏异显的框架基础。
        2.1.1 Application到Framework
        Android的应用以Activity为基础。应用在启动时会向系统申请建立新的Activity,系统通过Activity Manager Service创建Activity并赋予相应的运行环境,系统通过调用返回给Activity一个可操作WindowState的对象用于显示。应用显示的过程将会通过系统和自己拥有的WindowState与底层进行交换,而内容最终生成于WindowState指向的Surface之中。
        2.1.2 Framework到本地库
        应用的Activity所需显示部分将由ActivityManagerService通过View -> ViewRoot -> Window 的关系最终向WindowsManagerService申请一个新Window。WindowsManagerService通过系统本地运行调用,最终生成一个新的Surface封装在Window
State中提供给Activity。DisplayManagerService是用于管理显示的逻辑设备的一个中间层服务,主要用于维护已注册的显示设备对象列表并向系统提供各显示设备的参数和运行情况。WindowsManagerService在运行过程中将会评估当前设备的显示设备对象,通过DisplayManagerService获取当前已经在线的显示设备对象进行操作。其主要操作是将WindowState、Surface等软件中抽象的对象与实际的逻辑显示设备对象进行绑定,此外,将对比当前显示参数和逻辑显示设备的实际参数,最终将对比结果提供给下层用于图像的适配和变形。
        2.1.3 本地库与Kernel
        本地库中显示子系统中的最重要部分——Surface Manager/Surface Flinger。Surface Manager将负责管理显示与存取操作间的互动,Surface Flinger将已传送的各Surface内容以及应用所申请2D、3D的绘图进行系统级合成,并且管理双FB刷新机制。合成结果将直接送入Framebuffer进行显示。其中如果硬件有相应的加速设备可通过OpenGL/ES进行图像硬件加速,Display Manager Service则可通过Surface 和Display HAL获取较多的硬件设备参数。
        2.2 Android平台下双屏异显实现
        2.2.1 概述
        Android支持多屏幕框架为双屏异显工作提供了诸多便利,如Surface Manger在识别到当前设备拥有多个逻辑显示设备时,可根据需要创立对应的Surface; 通过Display Manager Service 也可方便地获取到显示设备列表并进行操作。下文将对双屏异显中的技术核心点进行阐述。
        2.2.2 Window Manager Service的改造
        Window Manager Service是一个显示控制方面的核心服务,选择通过Window Manager Service进行改造会较为方便地获取到各个运行的显示相关服务的通讯通路,以及所有窗体的状态控制,从而可以减少对于原生系统框架的修改,减少引入Bug和统一性降低的风险[3]。
        Android系统通过一个WindowState的列表维护当前窗体栈,列表从开始直至结束代表当前窗体显示的窗体景深(前后)布局顺序。该列表与当前显示默认设备绑定,而WindowState 本身包含着当前窗体的Surface信息。以上实现了默认显示设备、WindowState列表以及各Window 的Surface的连接关系。
        修改双屏异显功能如图2所示。
        根据当前显示情况进行判断,若当前是双屏同显状态,有应用请求显示至第二块屏幕上。首先按照默认窗体栈,也即默认WindowState列表创立一个新的窗体栈——第二窗体栈,通过Display Manager Service获取第二块屏幕操作上下文对象DisplayContent并将新创建的第二窗体栈与获取的上下文对象绑定。这时从第一窗体栈中查当前应用的窗体状态对象WindowState,获取后将其添加到第二窗体栈中,并从默认窗体栈中将这个窗体对象移除。
        若当前显示状态已经为双屏异显状态,则查默认窗体栈获取当前应用的窗体对象WindowState,将第二窗体栈中的应用窗体移动到默认窗体栈栈顶,然后将当前应用的窗体对象移动给第二窗体栈[4]。
        伪代码表示:
        moveAppToSecondDisplay(CurrnetID)
        {
        //查第二块屏幕
        displayCount=mDisplayContents.size();
        defaultContent=getDefaultDisplayContent();
        secondDisplayContent = null;
        for(int i = 0; i < displayCount;i++)
linux和安卓的关系        {
        tempContent=mDisplayContents.valueAt(i);
        if(tempContent != defaultContent){
        secondDisplayContent = tempContent;
        break;
        }
        }
        //查当前应用窗体并绑定显示屏幕
        currentWindowState = null;
        WindowList();
        WindowList();
        for(int i=defaultWindowList.size()-1;i>=0;i--)
        {
        (i);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。