首页> 中国专利> 一种安卓兼容环境中多窗口模式下安卓应用的截屏方法

一种安卓兼容环境中多窗口模式下安卓应用的截屏方法

摘要

本发明涉及一种安卓兼容环境中多窗口模式下安卓应用的截屏方法,包括:获得置在最前的Linux端的窗口对应的安卓应用信息,遍历安卓环境中所有活动实例的堆栈,并将各活动实例的信息与该安卓应用信息进行匹配,如匹配到,则将该匹配到的活动实例的窗口尺寸设置为与该安卓应用的窗口尺寸一致;当安卓系统收到截屏指令时,将第一图层列表的图层进行渲染,并进行存储;当渲染完成后,进行图层的合成操作,并在Linux端的窗口进行显示;当安卓系统收到截图指令时,还停止界面的刷新,并判断收到停止界面刷新前最后一帧的图层合成请求,将恢复刷新前最后一帧的图层的相关数据保存,能够根据Linux截图指令,对安卓系统的多个窗口进行截图。

著录项

  • 公开/公告号CN114579246A

    专利类型发明专利

  • 公开/公告日2022-06-03

    原文格式PDF

  • 申请/专利权人 北京麟卓信息科技有限公司;

    申请/专利号CN202210478251.5

  • 发明设计人 温研;

    申请日2022-05-05

  • 分类号G06F9/451;G06F9/54;

  • 代理机构

  • 代理人

  • 地址 100085 北京市海淀区西三旗昌临801号27号3层310、312

  • 入库时间 2023-06-19 15:32:14

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2022-06-03

    公开

    发明专利申请公布

说明书

技术领域

本发明涉及安卓系统的截屏技术,特别涉及一种安卓兼容环境中多窗口模式下安卓应用的截屏方法。

背景技术

现有的安卓系统截屏方法有一般有两种,一种是使用系统自带的截屏服务,一种是通过相关的安卓应用实现。

对于安卓系统自带的截屏服务,每一个安卓界面都是一个活动实例(Activity),而界面的显示都是通过窗口Window的对象实现的,在活动实例的界面执行按键操作的时候,在将按键的处理操作分发到安卓应用之前,执行相应截图按键的判定逻辑后,执行截屏事件,截屏之后返回的是一个Bitmap对象。截屏操作时候,若截屏失败则直接发送截屏失败的通知。若截屏成功,则先执行截屏的动画,并在动画效果执行完毕之后,发送截屏成功的通知。

通过相关的安卓应用实现的核心是通过getDrawingCache获取拟截屏的视图的缓存区,然后将其转换为Bitmap,再将Bitmap保存成png等格式的图像文件。

获取缓存区的基本过程包括:获取View视图的信息,包括宽、高、背景颜色、透明度及缓存所需大小;如果宽高值小于0,或者所需要的缓存大小超过系统限制的大小则直接清空Cache,缓存失败。

根据当前是否设置Scale获取不同的Bitmap,然后设置Bitmap配置,最后将其设置给Canvas;Canvas通过dispatchDraw或者draw方法绘制,因为之前通过Canvas.setBitmap方法将bitmap设置给了Canvas,所以Canvas所有的绘制元素最终都将绘制在bitmap上。

但通过getDrawingCache进行截屏的方效率低、资源占用高。安卓系统自带的截屏服务在多窗口模式下会截取所有窗口的内容,而通过安卓应用则只能截取安卓应用自己的窗口内容。

发明内容

本发明的目的在于提供一种安卓兼容环境中多窗口模式下安卓应用的截屏方法,用于解决安卓兼容环境中多窗口模式下对安卓应用的截屏。

本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法,包括:

当用户发出截屏指令,获得置在最前的Linux端的窗口对应的安卓应用信息,遍历安卓环境中所有活动实例的堆栈,并将各活动实例的信息与该安卓应用信息进行匹配,如匹配到,则将该匹配到的活动实例的窗口尺寸设置为与该安卓应用的窗口尺寸一致;

创建一个用于保存匹配到的活动实例的窗口截屏的图层,当安卓系统收到截屏指令时,将第一图层列表的图层进行渲染,并进行存储;当渲染完成后,进行图层的合成操作,并存储至安卓下的第一缓存区, Linux下的第二缓存区获取该第一缓存区的数据,并在Linux端的窗口进行显示;

当安卓系统收到截图指令时,停止界面的刷新,并判断收到停止界面刷新前最后一帧的图层合成请求,是否对应该匹配到的活动实例,如果是,将恢复刷新前最后一帧的图层的相关数据保存,以用于安卓系统恢复刷新后进行显示。

进一步地,本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法还包括:

活动实例的窗口截屏的图层中,如存在透明图层且不在最下层时,将该第一缓存区设置为ARGB_8888格式,否则,将该第一缓存区设置为RGB_565格式。

进一步地,本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法还包括:

依据活动实例的窗口的尺寸和截图格式计算所需的第一缓存区的空间newSize;

如newSize大于第一缓存区当前空间,则判断第一缓存区是否为空,如果不为空,则执行释放操作,并根据newSize重新分配第一缓存区的空间;如果为空则不执行释放操作;

如newSize小于等于第一缓存区空间,则不重新分配。

进一步地,本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法,该第一缓存区与该第二缓存区共享物理内存,该第二缓存区的共享内存全局标识符id将共享物理内存映射到安卓系统图层合成所在进程,并将映射地址赋值给该第一缓存区,在截屏过程完成后,在进程中内存地址空间释放映射的地址赋值。

进一步地,获得置在最前的Linux端的窗口对应的安卓应用的信息包括:

通过xDroidUI响应用户截屏指令,获取当前进程被用户置在最前的xDroidUI的Linux端的窗口对应的安卓应用信息;

将该安卓应用信息通过远程过程调用传递给安卓环境中的xDroid服务xDroidService。

进一步地,将各活动实例的信息与该安卓应用信息进行匹配的匹配方式包括:

比对安卓应用信息与活动实例的packageName、ActivityName以及TaskID,若均相同,则认为匹配成功;或

比对安卓应用信息与活动实例的packageName以及ActivityName,若均相同,则认为匹配成功。

进一步地,本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法还包括:

对于安卓8之前的版本,当与该安卓应用信息进匹配上的活动实例不在该活动实例的堆栈的栈顶时,将该匹配到的活动实例置于栈顶;

对于安卓8或之后的版本,将匹配到的活动实例设置为活跃。

进一步地,当安卓系统收到开始截图命令时,遍历安卓SurfaceComposer的图层列表,如存在图层不属于匹配到的活动实例的窗口,则复制一份SurfaceComposer当前的图层列表的拷贝给该第一图层列表,将不属于匹配到的活动实例的所有图层从该第一图层列表中删除,直至该第一图层列表只存在匹配到的活动实例的图层;

将该第一缓存区设置为渲染缓存区,执行渲染操作。

进一步地,本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法还包括:如果存在图层来自安卓系统提供的轻量级信息提醒机制Toast或对话框Dialog的窗口及图,且不是系统和截图应用创建的,则将该图层从该第一图层列表中移除。

进一步地,当SurfaceComposer收到截屏指令时,禁用安卓系统同步rsync信号,以停止界面的刷新;

根据SurfaceComposer收到停止界面刷新前最近一次的图层合成请求中的活动实例的packageName和ActivityName,判断该图层合成请求是否来自匹配到的活动实例;

将恢复刷新前最后一帧的图层的相关数据保存在第一存储区,当SurfaceComposer收到截图完成命令时,判断该第一存储区是否为空,如不为空,则对该第一存储区中保存的图层执行图层的合成操作,以用于安卓系统恢复刷新后进行显示;如果为空则不执行释放操作。

本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法,能够在有效根据Linux的截图指令,对安卓系统的多窗口进行截图,并将截图显示在Linux系统下。

附图说明

图1为本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法的流程图。

具体实施方式

为使本发明的目的、内容、和优点更加清楚,下面结合附图和实施例,对本发明的具体实施方式作进一步详细描述。

图1为本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法的流程图,如图1所示,本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法包括:

A.当用户发出截屏指令,获得置在最前的Linux端的窗口对应的安卓应用信息,遍历安卓环境中所有活动实例的堆栈,并将各活动实例的信息与该安卓应用信息进行匹配,如匹配到,则将该匹配到的活动实例的窗口尺寸设置为与该安卓应用的窗口尺寸一致;

B.创建一个用于保存匹配到的活动实例的窗口截屏的图层,当安卓系统收到截屏指令时,将第一图层列表的图层进行渲染,并进行存储;当渲染完成后,进行图层的合成操作,并存储至安卓下的第一缓存区,Linux下的第二缓存区获取该第一缓存区的数据,并在Linux端的窗口进行显示;

C.当安卓系统收到截图指令时,还停止界面的刷新,并判断收到停止界面刷新前最后一帧的图层合成请求,是否对应该匹配到的活动实例,如果是,将恢复刷新前最后一帧的图层的相关数据保存,以用于安卓系统恢复刷新后进行显示。

D. 依据截图的图层的信息,对截图缓存DrawingCache进行空间和格式的管理。

如图1所示,其中,对于步骤A具体的实现过程包括:

Linux端通过xDroidUI响应用户截屏命令(截屏命令通过菜单或者快捷键选择),获取当前进程被用户置在最前的xDroidUI的Linux端的窗口对应的安卓应用的信息安卓应用Info,安卓应用Info包括packageName、ActivityName、taskId、窗口大小等。

其中,xDroid是Linux操作系统的安卓兼容环境,通过xDroidService与xDroidUI的配合实现了安卓应用与Linux操作系统的兼容。xDroid中xDroidUI为安卓应用显示单元、xDroidServer为安卓应用兼容服务。

其中,packageName为安卓应用的包名。ActivityName为在安卓系统应用程序中的活动实例Activity的名称。活动实例Activity具有唯一的taskId,通过该taskId能够获取活动实例Activity与应用程序间的对应关系,由安卓系统创建时,taskId即与某个安卓系统的线程相对应。

将安卓应用Info通过远程过程调用(Remote Procedure Call,简称RPC)传递给安卓环境中的xDroid服务xDroidService。

遍历安卓环境内所有Activity的堆栈,查找与安卓应用Info匹配的Activity,如果查找到,则:

对比安卓应用Info中窗口大小与查找到的Activity的窗口(即安卓应用Window)的大小是否一致,如不一致(多窗口模式下可能因缩放操作未完成等原因导致不一致),则重新设置窗口大小(可以通过resize 安卓应用Window命令实现),使其与安卓应用Info中窗口大小一致,并调用onMeasure和layout功能进行重绘。onMeasure用于测量屏幕视图View的宽和高;layout用于进行屏幕视图View的精细布局。

其中,查找与安卓应用Info匹配的Activity的匹配方式可以是比对安卓应用Info与Activity的packageName,ActivityName,TaskID,若三者中均相同或packageName以及ActivityName二者相同,则认为查找到匹配的Activity。

为在安卓系统下对匹配到的Activity进行相应的截图,需要进行Activity的激活操作,具体对不同的安卓版本,可以分别进行以下动作:

(1)安卓 8之前的版本(不含8),因为同个类型多个Activity存储在一个堆栈,(根据SDK数字等可判断安卓版本):当与安卓应用Info匹配上的Activity不在堆栈的栈顶时,则将其置于栈顶;

(2)安卓 >= 8时,一个Activity存储在一个堆栈:将匹配的Activity设置为活跃Activity。

如图1所示,其中,步骤B具体的实现可以通过修改安卓框架图层合成器SurfaceComposer,筛选出给定应用窗口(即匹配到的Activity的窗口)截屏,并确保截取的就是用户执行截图命令瞬间的屏幕视图View,具体包括:

步骤B1、遍历所有准备渲染的安卓的图层Layer列表中的当前显示的图层Layer,依据图层Layer的信息判断,如存在其中一个图层Layer不属于给定应用窗口,则新建一个图层列表LayersToCaptureScreen,将SurfaceComposer当前图层Layer列表的拷贝给LayersToCaptureScreen,并将不属于给定应用窗口的所有Layer从LayersToCaptureScreen中删除,直至LayersToCaptureScreen只存在应用窗口的图层Layer;如果图层Layer列表中的图层Layer均属于给定窗口,则继续进行步骤B2;

对于步骤B1,进一步的,对安卓系统提供的轻量级信息提醒机制Toast和对话框Dialog处理。如果图层Layer列表中的图层Layer来自安卓系统提供的轻量级信息提醒机制Toast或对话框Dialog的窗口Window,且不是系统创建的,也不是截图应用创建的,则将该图层Layer从LayersToCaptureScreen中移除;

步骤B2、将安卓SurfaceComposer的缓存区DrawingCache(DrawingCache缓存应用窗口图层Layer的合成的图像)设置为SurfaceComposer的渲染缓存区,渲染后合成的图层的缓存区DrawingCache用于执行OpenGL ES/Vulkan对LayersToCaptureScreen中的图层Layer进行渲染以及图层的合成操作后,存储至缓存区DrawingCache。

待渲染完毕,Linux下的缓存区SharedCache访问缓存区DrawingCache的内容,完成Linux环境下的截屏显示。

如图1所示,其中,步骤C的操作目的在于安卓系统恢复刷新后进行显示,具体可以通过修改SurfaceComposer完成,包括:

C1.当SurfaceComposer收到开始截图命令时,进行如下动作:

(1)禁用安卓系统同步rsync信号,以停止界面的刷新;

(2)依据SurfaceComposer收到停止界面刷新前最近一次的图层合成请求中的安卓应用信息中的packageName和ActivityName判断该图层合成请求是否来自截图应用(即为步骤A中匹配到的活动实例Activity):

1)如果合成请求来自被截图的截图应用,则执行以下操作:

收到截图完成命令后,将停止界面刷新前最后一帧的图层的数据或相应的指令保存在已经建立的存储区CachedComposingOperation中,之后,不进行图层合成操作;

2)如果合成请求不是来自截图应用,则正常执行图层合成操作(因为是多窗口,所以需要正常执行别的应用窗口的合成/渲染操作)。

C2.当SurfaceComposer收到截图完成命令时,进行如下动作:

(1)判断CachedComposingOperation是否为空,不为空,则对CachedComposingOperation中保存的图层Layer执行数据合成操作,以用于安卓系统恢复刷新后进行显示;如果为空则不执行释放当前DrawingCache的动作;

(2)重新启用rsync信号。

如图1所示,依据截图的图层的信息,对截图缓存DrawingCache进行空间和格式的管理,可以通过修改SurfaceComposer实现,具体包括:

D1.遍历截屏的活动实例Activity的窗口对应的所有图层Layer,对缓存区DrawingCache的格式进行管理,包括:

如遍历到存在透明的图层Layer且此透明图层Layer不在最下层时(透明图层Layer没有实质显示内容,作用就是使其之下的Layer渲染时加上透明度alpha,其中,alpha透明度值不是1,当alpha为1则不透明),则将DrawingCache设置为ARGB_8888格式,如果图层Layer在最下层,则不做处理;

否则,将DrawingCache设置为RGB_565格式(其中,RGB_565格式可以节省空间,同时可显著减少需复制的数据量)。

D2.根据截屏窗口大小和截图格式(ARGB_8888或RGB_565)计算缓存DrawingCache容量newSize,之后将当前DrawingCache的容量初始化为0后,再进行以下操作:

(1)如newSize > DrawingCache当前大小,则:

判断DrawingCache是否为空,如果不为空,则释放当前DrawingCache:根据newSize重新分配DrawingCache的容量;并利用RPC通知xDroidUI分配容量为newSize的共享内存SharedCache;其中,DrawingCache与sharedCach共享同一块物理内存;如果为空则不执行释放当前DrawingCache的动作;

将SharedCache的权限设置为Linux下的others用户可访问;

返回SharedCache的共享内存全局标识符id给SurfaceComposer;

SurfaceComposer根据id将SharedCache的共享内存映射到SurfaceComposer所在进程,并将映射地址赋值给DrawingCache;

释放DrawingCache的操作包括:SurfaceComposer在其所在进程中内存地址空间执行释放映射的地址赋值unmap DrawingCache;并利用RPC通知xDroid的Linux服务xDroidLinuxDaemon释放Linux下的共享内存SharedCache,其中,unmap DrawingCache操作即为映射地址赋值的DrawingCache的反操作;

(2)如newSize<=DrawingCache当前大小,否则,不执行任何操作。

本发明提供的一种安卓兼容环境中多窗口模式下安卓应用的截屏方法,只截取当前窗口(Linux上最前的窗口)的内容,能够对于内容快速更新的屏幕视图View,能够确保内容的准确性。且针对安卓 7和9(及之后的)对Stack管理机制的不同,做出了不同处理,有效适应不同的安卓版本。

而在较佳实施例中,还对Toast、系统弹窗等全局窗口进行了处理。针对创建的可复用的缓存区DrawingCache,默认情况下不启用Bitmap.Config.ARGB_8888格式,而在需要的情况下进行格式和空间的管理,能够有效提高系统的处理效率。

以上所述仅是本发明的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明技术原理的前提下,还可以做出若干改进和变形,这些改进和变形也应视为本发明的保护范围。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号