1.本发明涉及智能系统终端的技术领域,特别是涉及一种应用卡顿监控方法、装置、计算机设备和存储介质。
背景技术:
2.随着移动互联网的普及,手机作为社交、娱乐、导航等活动的智能化载体,是人们生活中必不可少的工具。随着手机的容量空间越来越大,用户安装的app也就越来越多,但并不是每一个app都能运行的非常的流畅;作为手机软件开发商,如何提高软件的应用体验是一个非常大的挑战;尤其是一些小公司或者个人开发的app,没有经过严格的测试和质量把关,就上传到公共平台进行发布了,用户下载安装了这些app后,在使用的时候,就会经常出现死机卡顿的现象,给用户造成非常不好的影响。因此,解决手机的卡顿监控问题就是其中一个非常大的挑战。
3.目前大多数手机都是采用android系统,在开发测试过程中,如何解决android系统应用卡顿监控问题显得尤为重要。现有技术的android系统采用的卡顿监控方案大多是字节码插桩方案,其原理是在每个方法的开始和结束都插入一行代码,以监控每个方法所带来的耗时。字节码插桩方案可以很精细地监控到每一个方法的执行过程,同时无需我们手动去添加监控。但目前这种方法带来的弊端也是不容忽视的:
4.1)增加了字节码代码量。
5.2)对于简单函数的监控是无意义的,比如getter和setter方法。
6.3)该方案对业务代码具有侵入性。
7.4)需要修改打包过程。
8.因此,如何实现android系统应用卡顿监控方法的无侵入性及简便性,以规避存在可能破坏原有代码逻辑的监控场景发生,尚未提出有效的解决方案。
技术实现要素:
9.基于此,本发明提供了一种应用卡顿监控方法、装置、计算机设备和存储介质,以解决现有技术的android系统应用卡顿监控方法存在侵入性、操作繁琐以及可能破坏原有代码逻辑的监控场景,以确保android系统应用卡顿监控方法的无侵入性及简便性。
10.为实现上述目的,本发明提供一种应用卡顿监控方法,其包括:
11.创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志;
12.从消息队列中通过所述主线程的消息处理函数获取消息;
13.在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长;
14.判断所述时长是否大于预设的时长阈值;
15.若是,则判定所述所述目标应用发生卡顿。
16.优选的,所述在所述主线程逐个处理所述消息时,通过所述输出日志获取当前消息处理所耗的时长的步骤具体包括:
17.在所述主线程逐个开始处理所述消息前,通过所述自定义打印实例以命名为开始消息字符串对当前打印开始处理进行标记,并为所述开始消息字符串串拼接上命名为开始时间戳,构成开始标记字符串;
18.当所述主线程处理完所述当前消息后,通过所述自定义打印实例以命名为结束消息字符串对所述当前消息处理完进行标记,并为所述结束消息字符串串拼接上命名为结束时间戳,构成结束标记字符串;
19.通过计算所述结束时间戳与所述开始时间戳的时长,以获取当前消息处理所耗的时长。
20.优选的,所述判断所述时长是否大于预设的时长阈值的步骤之后,所述方法还包括:
21.若判断所述时长不大于预设的时长阈值,则判定所述所述目标应用未发生卡顿。
22.在一些实施例中,所述判定所述所述目标应用发生卡顿的步骤之后,所述方法还包括:
23.获取linkedhashmap保存的现场信息,以及所述linkedhashmap保存现场信息时的时间戳,以通过所述现场信息及所述时间戳分析卡顿原因。
24.优选的,所述获取linkedhashmap保存的现场信息,以及所述linkedhashmap保存现场信息时的时间戳的步骤具体包括:
25.创建保存现场的守护线程,设定所述守护线程按预设间隔时长dump当前应用的现场信息;其中,所述现场信息至少包括堆栈信息、cpu信息;
26.将所述现场信息通过所述linkedhashmap保存;
27.获取所述linkedhashmap保存现场信息时的时间戳。
28.优选地,所述创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志的具体步骤包括:
29.通过printer软件以自定义的方式创建自定义打印实例;
30.通过anr监控方法将所述自定义打印实例写入所述目标应用的主线程,并通过所自定义打印实例输出日志。
31.为实现上述目的,本发明还提供了一种应用卡顿监控装置,其包括:
32.创建模块:用于创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志;
33.调取模块,用于从消息队列中通过所述主线程的消息处理函数获取消息;
34.计算模块:用于在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长;
35.判断模块,用于判断所述时长是否大于预设的时长阈值;
36.第一判定模块,用于若所述时长大于预设的时长阈值,则判定所述所述目标应用发生卡顿。
37.优选的,所述计算模块包括:
38.第一标记单元,用于在所述主线程逐个开始处理所述消息前,通过所述自定义打
印实例以命名为开始消息字符串对当前打印开始处理进行标记,并为所述开始消息字符串串拼接上命名为开始时间戳,构成开始标记字符串;
39.第二标记单元,用于当所述主线程处理完所述当前消息后,通过所述自定义打印实例以命名为结束消息字符串对所述当前消息处理完进行标记,并为所述结束消息字符串串拼接上命名为结束时间戳,构成结束标记字符串;
40.计算单元,用于通过计算所述结束时间戳与所述开始时间戳的时长,以获取当前消息处理所耗的时长。
41.优选的,所述装置还包括:
42.第二判定模块,用于若所述时长不大于预设的时长阈值,则判定所述所述目标应用未发生应用卡顿。
43.优选的,所述装置还包括:
44.分析模块:用于获取linkedhashmap保存的现场信息,以及所述linkedhashmap保存现场信息时的时间戳,以通过所述现场信息及所述时间戳分析卡顿原因。
45.优选的,所述分析模块包括:
46.设置单元,用于创建保存现场的守护线程,设定所述守护线程按预设间隔时长dump当前应用的现场信息;其中,所述现场信息至少包括堆栈信息、cpu信息;
47.保存单元,用于将所述现场信息通过所述linkedhashmap保存;
48.获取单元,用于获取所述linkedhashmap保存现场信息时的时间戳。
49.优选的,所述创建模块包括:
50.自定义单元:用于通过printer软件以自定义的方式创建自定义打印实例;
51.调取单元:用于通过anr监控方法将所述自定义打印实例写入所述目标应用的主线程,并通过所自定义打印实例输出日志。
52.为实现上述目的,本发明还提供了一种计算机设备,包括存储器和处理器,所述存储器中存储有计算机可读指令,所述计算机可读指令被所述处理器执行时,使得所述处理器执行如上所述应用卡顿监控方法的步骤。
53.为实现上述目的,本发明还提供了一种存储介质,存储有计算机可读指令,所述计算机可读指令被处理器执行时实现如上所述应用卡顿监控方法的步骤。
54.上述本发明提供了一种应用卡顿监控方法、装置、计算机设备和存储介质,其中,通过在android主线程的消息处理函数从messagequeue中取出message进行处理,在正式处理一个message前,系统使用自定义打印实例输出一行日志,当主线程处理完成该message时,会再次输出一行日志;通过自定义打印实例前、后输出的日志可计算出当前message处理所耗的时间,根据与预设的时长阀值的比较,从而监控android在处理目标应用时是否发生卡顿。本发明的android应用卡顿监控方法无需对源代码做任何改动且创建的自定义打印实例接入与实现更加简单。
附图说明
55.图1为本发明实施例一提供的应用卡顿监控方法的实施环境图;
56.图2为本发明实施例一提供的应用卡顿监控方法的流程图;
57.图3为本发明实施例一提供的步骤s101具体流程图;
58.图4为本发明实施例一提供的步骤s103具体流程图;
59.图5为本发明实施例二提供的与实施例一方法对应的应用卡顿监控装置结构框图;
60.图6为本发明实施例三提供的应用卡顿监控方法的流程图;
61.图7为本发明实施例四提供的与实施例三方法对应的应用卡顿监控装置结构框图;
62.图8为本发明实施例五提供的应用卡顿监控方法的流程图;
63.图9为本发明实施例五提供的步骤s306具体流程图;
64.图10为本发明实施例六提供的与实施例五方法对应的应用卡顿监控装置结构框图;
65.图11为本发明实施例七提供的计算机设备的结构示意图;
66.图12为本发明实施例八提供的存储介质的结构示意图。
67.110-计算机设备、111-处理器、112-储存器、113-计算机存储介质、1131-程序文件、120-终端设备;
68.20-创建模块、21-自定义单元、22-调取单元;
69.30-调取模块;
70.40-计算模块、41-第一标记单元、41-第二标记单元、43-计算单元;
71.50-判断模块;
72.60-第一判定模块;
73.70-第二判定模块;
74.80-分析模块、81-设置单元、82-保存单元、83-获取单元。
具体实施方式
75.为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。
76.可以理解,本技术所使用的术语“第一”、“第二”等可在本文中用于描述各种元件,但这些元件不受这些术语限制。这些术语仅用于将第一个元件与另一个元件区分。
77.实施例一
78.本技术提供的应用卡顿监控方法,可应用在如图1的应用环境中,其中,该计算机设备可通过网络与服务器进行通信。其中,该计算机设备包括但不限于各种个人计算机、笔记本电脑、智能手机、平板电脑和便携式可穿戴设备。服务器可以用独立的服务器或者是多个服务器组成的服务器集群来实现。
79.如图2所示,本实施例提出了一种应用卡顿监控方法,以该方法应用在图1中的计算机设备为例进行说明,具体可以包括以下步骤:
80.步骤s101,创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志。
81.具体地,本实施例中,自定义打印实例通过printer软件自定义创建myprinter,打印机服务官方文档位于android.printservice包下,这个包下提供了实现打印服务的类,
打印服务是知道如何通过一些标准协议与打印机通话的插件组件;这些服务是系统和打印机之间的桥梁。因此,打印机和打印机协议的具体实现是从系统中分解出来的,并且可以独立开发和更新。系统负责根据服务管理的打印机是否存在活动的打印作业来启动和停止打印服务。打印服务也应该及时执行打印机发现以确保良好的用户体验。打印机运行期间系统和打印服务之间的交互由系统请求时打印服务创建的printerdiscoverysession进行封装。
82.进一步地,如图3所示,步骤s101的具体步骤包括步骤s1011~s1012:
83.步骤s1011,通过printer软件以自定义的方式创建自定义打印实例;
84.具体地,printer软件是指打印机诊断管理软件,可以方便用户进行打印机的各种设置,解决日常遇到的问题,比如墨水弄脏、打印机暂停、脱机、端口不正确等。
85.步骤s1012,通过anr监控方法将所述自定义打印实例写入所述目标应用的主线程,并通过所自定义打印实例输出日志。;
86.具体地,所述anr监控方法采用基于代码looper.getmainlooper().setmessagelogging实现。关于handler、looper、messagequeue,简单来说就是一个handler对应一个looper,一个looper对应一个message;在看looper的源码时,发现其中的getmainlooper方法,从名字可以看出是获取主线程的looper,该方法的源码如下:
87.返回应用主线程中的looper
[0088][0089]
其实最常用的是无构造参数的handler,其实handler还有构造参数的构造方法;在此注意构造函数中第一个参数是looper,就是说,可以传递一个已有的looper来创建handler.looper.getmainlooper(),将主线程中的looper扔进去,也就是说handlemessage会运行在主线程中,这样可以在主线程中更新ui而不用把handler定义在主线程中。当然,刚才提到的作用只是对应于主线程中的smainlooper,其实各种looper都可以往handler的构造方法里扔,从而使得handlemessage运行在想要的线程中,进而实现线程间通信。
[0090]
步骤s102,从消息队列中通过所述主线程的消息处理函数获取消息。
[0091]
具体地,所述消息处理函数为looper.loop()方法。handler获取当前线程中的looper对象,looper用来从存放message的messagequeue中取出message,再由handler进行message的分发和处理.message queue(消息队列):用来存放通过handler发布的消息,通常附属于某一个创建它的线程,可以通过looper.myqueue()得到当前线程的消息队列.handler:可以发布或者处理一个消息或者操作一个runnable,通过handler发布消息,消息将只会发送到与它关联的消息队列,然也只能处理该消息队列中的消息.looper:是handler和消息队列之间通讯桥梁,程序组件首先通过handler把消息传递给looper,
looper把消息放入队列。looper也把消息队列里的消息广播给所有的handler:handler接受到消息后调用handlemessage进行处理。
[0092]
需要指出的是,android中的looper类,是用来封装消息循环和消息队列的一个类,用于在android线程中进行消息处理;handler其实可以看做是一个工具类,用来向消息队列中插入消息的。其中,looper类用来为一个线程开启一个消息循环,通常是通过handler对象来与looper进行交互的,looper.loop();让looper开始工作,从消息队列里取消息,处理消息。需要注意的是,写在looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mhandler.getlooper().quit()后,loop才会中止,其后的代码才能得以运行。
[0093]
步骤s103,在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长。
[0094]
需要说明的是,很多应用场景需要让主线程给子线程发送消息,该消息作为任务的载体,比如在intentservice中,主线程就给子线程发送了消息,让子线程干活。
[0095]
进一步地,如图4所示,步骤s103的具体步骤包括步骤s1031~s1033:
[0096]
步骤s1031,在所述主线程逐个开始处理所述消息前,通过所述自定义打印实例以命名为开始消息字符串对当前打印开始处理进行标记,并为所述开始消息字符串串拼接上命名为开始时间戳,构成开始标记字符串;其中,本实施例中的开始消息字符串为“》》》》》dispatching to”。
[0097]
步骤s1032,当所述主线程处理完所述当前消息后,通过所述自定义打印实例以命名为结束消息字符串对所述当前消息处理完进行标记,并为所述结束消息字符串串拼接上命名为结束时间戳,构成结束标记字符串;其中,本实施例中的结束消息字符串为“《《《《《finished to”。
[0098]
步骤s1033,通过计算所述结束时间戳与所述开始时间戳的时长,以获取当前消息处理所耗的时长。
[0099]
步骤s104,判断所述时长是否大于预设的时长阈值。
[0100]
具体地,通过所述endtime时间戳减去所述starttime时间戳,即可得出当前message处理所耗的时长;另外,手上时长阈值t根据具体情况进行调节,比如设定message处理时间超过5秒,即认为所述目标应用发生卡顿,那么时长阈值为5000(毫秒),这个时长阈值是一个静态常量,在运行过程中并不允许修改。
[0101]
需要说明的是,界面卡顿主要是因为消息分发处理的不及时导致的,android的消息分发机制主要是由message/looper/handler构建的。由于主线程只存在一个looper,并且android系统所有更新ui的操作都是在主线程里面执行的。因此所有的ui操作都会经过主线程的looper消息循环。
[0102]
步骤s105,若是,则判定所述所述目标应用发生卡顿。
[0103]
具体地,通过所述endtime时间戳减去所述starttime时间戳得出当前message处理所耗的时长,当时长大于时长阈值,说明当前的message发送卡顿现象。
[0104]
需要指出的是,用户对卡顿的感知,主要来源于界面的刷新,而界面的性能主要是依赖于设备的ui渲染性能。如果ui设计过于复杂,或是实现不够友好,计算绘制算法不够优化,设备又不给力,界面就会像卡住了一样,给用户卡顿的感觉。界面性能取决于ui渲染性
能。可以理解为ui渲染的整个过程是由cpu和gpu两个部分协同完成的;具体地,cpu会先把layout中的ui组件计算成polygons(多边形)和textures(纹理),然后经过opengl es处理。opengl es处理完后再交给gpu进行栅格化渲染,渲染后gpu再将数据传送给屏幕,由屏幕进行绘制显示。activity的界面之所以可以被绘制到屏幕上其中有一个很重要的过程就是栅格化(resterization),栅格化简单来说就是将向量图转化为机器可以识别的位图的一个过程。其中很复杂也比较很耗时,gpu就是用来加快栅格化的速度。其中,cpu负责ui布局元素的measure、layout、draw等相关运算执行,gpu负责栅格化(rasterization),将ui元素绘制到屏幕上。如果ui布局层次太深,或是自定义控件的ondraw中有复杂运算,cpu的相关运算就可能大于16ms,导致卡顿。通常需要借助hierarchy viewer这个工具来分析布局,hierarchy viewer不仅可以以图形化树状结构的形式展示出ui层级,还对每个节点给出了三个小圆点,以指示该元素measure、layout、draw的耗时及性能。
[0105]
通过上述步骤,本实施例通过在android主线程的消息处理函数,即为looper.loop()方法从messagequeue中不断取出message进行处理,在正式处理一个message前,系统使用printer输出一行以“》》》》》dispatching to”开头的日志,当主线程处理完成该message时,会再次输出一行以“《《《《《finished to”开头日志。只需要在message处理前和处理后添加相应的时间戳即可计算出当前message处理所耗的时间,根据与预设的时长阈值进行比较,从而判断所述目标应用是否发生了卡顿,得到监控卡顿的目的。
[0106]
在一个可选的实施方式中,还可以:将所述应用卡顿监控方法的结果上传至区块链中。
[0107]
具体地,基于所述应用卡顿监控方法的结果得到对应的摘要信息,具体来说,摘要信息由所述应用卡顿监控方法的结果进行散列处理得到,比如利用sha256s算法处理得到。将摘要信息上传至区块链可保证其安全性和对用户的公正透明性。用户可以从区块链中下载得该摘要信息,以便查证所述应用卡顿监控方法的结果是否被篡改。本示例所指区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。区块链(blockchain),本质上是一个去中心化的数据库,是一串使用密码学方法相关联产生的数据块,每一个数据块中包含了一批次网络交易的信息,用于验证其信息的有效性(防伪)和生成下一个区块。区块链可以包括区块链底层平台、平台产品服务层以及应用服务层等。
[0108]
实施例二
[0109]
本实施例提供了与实施例一所述方法相对应的装置的结构框图。图5是根据本技术实施例的应用卡顿监控装置的结构框图,如图5所示,该装置包括:
[0110]
创建模块20:用于创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志;
[0111]
调取模块30,用于从消息队列中通过所述主线程的消息处理函数获取消息;
[0112]
计算模块40:用于在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长;
[0113]
判断模块50,用于判断所述时长是否大于预设的时长阈值;
[0114]
第一判定模块60,用于若所述时长大于预设的时长阈值,则判定所述所述目标应用发生卡顿。
[0115]
进一步地,所述创建模块20包括:
[0116]
自定义单元21,用于通过printer软件以自定义的方式创建自定义打印实例;
[0117]
调取单元22,用于用于通过anr监控方法将所述自定义打印实例写入所述目标应用的主线程,并通过所自定义打印实例输出日志。
[0118]
进一步地,所述计算模块40包括:
[0119]
第一标记单元41,用于在所述主线程逐个开始处理所述消息前,通过所述自定义打印实例以命名为开始消息字符串对当前打印开始处理进行标记,并为所述开始消息字符串串拼接上命名为开始时间戳,构成开始标记字符串;
[0120]
第二标记单元42,用于当所述主线程处理完所述当前消息后,通过所述自定义打印实例以命名为结束消息字符串对所述当前消息处理完进行标记,并为所述结束消息字符串串拼接上命名为结束时间戳,构成结束标记字符串;
[0121]
计算单元43,用于通过计算所述结束时间戳与所述开始时间戳的时长,以获取当前消息处理所耗的时长。
[0122]
需要说明的是,上述各个模块可以是功能模块也可以是程序模块,既可以通过软件来实现,也可以通过硬件来实现。对于通过硬件来实现的模块而言,上述各个模块可以位于同一处理器中;或者上述各个模块还可以按照任意组合的形式分别位于不同的处理器中。
[0123]
实施例三
[0124]
如图6所示,本实施例提出了一种应用卡顿监控方法,以该方法应用在图1中的计算机设备为例进行说明,具体可以包括以下步骤:
[0125]
步骤s201,创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志;
[0126]
步骤s202,通过从消息队列中所述主线程的消息处理函数获取消息;
[0127]
步骤s203,在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长;
[0128]
步骤s204,判断所述时长是否大于预设的时长阈值;
[0129]
步骤s205,若否,则判定所述所述目标应用未发生卡顿。
[0130]
实施例四
[0131]
本实施例提供了与实施例三所述方法相对应的装置的结构框图。图7是根据本技术实施例的应用卡顿监控装置的结构框图,如图7所示,该装置包括:
[0132]
创建模块20:用于创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志;
[0133]
调取模块30,用于从消息队列中通过所述主线程的消息处理函数获取消息;
[0134]
计算模块40:用于在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长;
[0135]
判断模块50,用于判断所述时长是否大于预设的时长阈值;
[0136]
第二判定模块70,用于若所述时长不大于预设的时长阈值,则判定所述所述目标应用未发生卡顿。
[0137]
实施例五
[0138]
如图8所示,本实施例提出了一种应用卡顿监控方法,以该方法应用在图1中的计
算机设备为例进行说明,具体可以包括以下步骤:
[0139]
步骤s301,创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志;
[0140]
步骤s302,从消息队列中通过所述主线程的消息处理函数获取消息;
[0141]
步骤s303,在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长;
[0142]
步骤s304,判断所述时长是否大于预设的时长阈值;
[0143]
步骤s305,若是,则判定所述所述目标应用发生卡顿;
[0144]
步骤s306,获取linkedhashmap保存的现场信息,以及所述linkedhashmap保存现场信息时的时间戳,以使通过所述现场信息及所述时间戳分析卡顿原因。
[0145]
具体地,linkedhashmap中map接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与hashmap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。需要注意的是,如果在映射中重新插入键,则插入顺序不受影响。如果在调用m.put(k,v)前m.containskey(k)返回了true,则调用时会将键k重新插入到映射m中;其中,k-由此映射维护的键的类型、v-映射值的类型。
[0146]
需要说明的是,可以重写removeeldestentry(map.entry)方法来实施策略,以便在将新映射关系添加到映射时自动移除旧的映射关系。此类提供所有可选的map操作,并且允许null元素。与hashmap一样,它可以为基本操作(add、contains和remove)提供稳定的性能,假定哈希函数将元素正确分布到桶中。由于增加了维护链接列表的开支,其性能很可能比hashmap稍逊一筹,不过这一点例外:linkedhashmap的collection视图迭代所需时间与映射的大小成比例。hashmap迭代时间很可能开支较大,因为它所需要的时间与其容量成比例。
[0147]
进一步地,如图9所示,步骤s306的具体步骤包括步骤s3061~s3063:
[0148]
步骤s3061,创建保存现场的守护线程,设定所述守护线程按预设间隔时长dump当前应用的现场信息;其中,所述现场信息至少包括堆栈信息、cpu信息。
[0149]
具体地,守护线程(daemon)是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。linux的大多数服务器就是用守护进程实现的;比如,internet服务器inetd、web服务器httpd等。同时守护进程完成许多系统任务;比如,作业规划进程crond,打印进程lpd等。
[0150]
步骤s3062,将所述现场信息通过所述linkedhashmap保存。
[0151]
具体地,所述现场信息至少包括堆栈信息、cpu信息;其中,堆栈是两种数据结构,都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。需要注意的是:堆,队列优先,先进先出。栈,先进后出(first-in/last-out)。gpu信息用来反映加快栅格化的速度,cpu负责ui布局元素的measure、layout、draw等相关运算执行。
[0152]
步骤s3063,获取所述linkedhashmap保存现场信息时的时间戳。
[0153]
具体地,时间戳通过system.currenttimemillis()方法获取。
[0154]
需要说明的是,system类代表系统,系统级的很多属性和控制方法都放置在该类
的内部。该类位于java.lang包。public static long currenttimemillis(),该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和gmt时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。可以直接把这个方法强制转换成date类型。诸如:
[0155]
long currenttime=system.currenttimemillis();
[0156]
simpledateformat formatter=new simpledateformat("yyyy年-mm月dd日-hh时mm分ss秒");
[0157]
date date=new date(currenttime);
[0158]
system.out.println(formatter.format(date));
[0159]
运行结果如下:
[0160]
当前时间:1111年-08月10日-14时11分46秒
[0161]
另可获得当前的系统和用户属性:
[0162]
string osname=system.getproperty(“os.name”);
[0163]
string user=system.getproperty(“user.name”);
[0164]
system.out.println(“当前操作系统是:” osname);
[0165]
system.out.println(“当前用户是:” user);
[0166]
system.getproperty这个方法可以得到很多系统的属性。
[0167]
实施例六
[0168]
本实施例提供了与实施例五所述方法相对应的装置的结构框图。图10是根据本技术实施例的应用卡顿监控装置的结构框图,如图11所示,该装置包括:
[0169]
创建模块20:用于创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志;
[0170]
调取模块30,用于从消息队列中通过所述主线程的消息处理函数获取消息;
[0171]
计算模块40:用于在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长;
[0172]
判断模块50,用于判断所述时长是否大于预设的时长阈值;
[0173]
第一判定模块60,用于若所述时长t大于预设的时长阈值t,则判定所述所述目标应用发生卡顿;
[0174]
分析模块80:用于获取linkedhashmap保存的现场信息,以及所述linkedhashmap保存现场信息时的时间戳,以使通过所述现场信息及所述时间戳分析卡顿原因。
[0175]
进一步地,所述分析模块80包括:
[0176]
设置单元81,用于创建保存现场的守护线程,设定所述守护线程按预设间隔时长dump当前应用的现场信息;其中,所述现场信息至少包括堆栈信息、cpu信息;
[0177]
保存单元82,用于将所述现场信息通过所述linkedhashmap保存;
[0178]
获取单元83,用于获取所述linkedhashmap保存现场信息时的时间戳。
[0179]
实施例七
[0180]
请参考图11,图11为本发明实施例的计算机设备的结构示意图。如图12所示,该计算机设备110包括处理器111及和处理器111耦接的存储器112。
[0181]
存储器112存储有用于实现上述任一实施例所述应用卡顿监控方法的程序指令。
[0182]
处理器111用于执行存储器112存储的程序指令。
[0183]
其中,处理器111还可以称为cpu(central processing unit,中央处理单元)。处理器111可能是一种集成电路芯片,具有信号的处理能力。处理器111还可以是通用处理器、数字信号处理器(dsp)、专用集成电路(asic)、现成可编程门阵列(fpga)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。通用处理器可以是微处理器或者该处理器也可以是任何常规的处理器等。
[0184]
实施例八
[0185]
参阅图12,图12为本发明实施例的计算机存储介质的结构示意图。本发明实施例的计算机存储介质113存储有计算机可读指令,所述计算机可读指令被处理器执行时实现如上所述步骤,即计算机介质存储113有能够实现上述所有方法的程序文件1131,其中,该程序文件1131可以以软件产品的形式存储在上述存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)或处理器(processor)执行本技术各个实施方式所述方法的全部或部分步骤。而前述的存储介质包括:u盘、移动硬盘、只读存储器(rom,read-only memory)、随机存取存储器(ram,random access memory)、磁碟或者光盘等各种可以存储程序代码的介质,或者是计算机、服务器、手机、平板等终端设备。
[0186]
需要说明的是,在本文中,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、装置、物品或者方法不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、装置、物品或者方法所固有的要素。在没有更多限制的情况下,由语句“包括一个
……”
限定的要素,并不排除在包括该要素的过程、装置、物品或者方法中还存在另外的相同要素。
[0187]
上述本发明实施例序号仅仅为了描述,不代表实施例的优劣。通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到上述实施例方法可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件,但很多情况下前者是更佳的实施方式。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在如上所述的一个存储介质(如rom/ram、磁碟、光盘)中,包括若干指令用以使得一台终端设备(可以是手机,计算机,服务器,或者网络设备等)执行本发明各个实施例所述的方法。
技术特征:
1.一种应用卡顿监控方法,其特征在于,包括:创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志;从消息队列中通过所述主线程的消息处理函数获取消息;在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长;判断所述时长是否大于预设的时长阈值;若是,则判定所述所述目标应用发生卡顿。2.根据权利要求1所述的应用卡顿监控方法,其特征在于,所述在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长的步骤具体包括:在所述主线程逐个开始处理所述消息前,通过所述自定义打印实例以命名为开始消息字符串对当前打印开始处理进行标记,并为所述开始消息字符串串拼接上命名为开始时间戳,构成开始标记字符串;当所述主线程处理完所述当前消息后,通过所述自定义打印实例以命名为结束消息字符串对所述当前消息处理完进行标记,并为所述结束消息字符串串拼接上命名为结束时间戳,构成结束标记字符串;通过计算所述结束时间戳与所述开始时间戳的时长,以获取当前消息处理所耗的时长。3.根据权利要求1所述的应用卡顿监控方法,其特征在于,所述判断所述时长是否大于预设的时长阈值的步骤之后,所述方法还包括:若判断所述时长不大于预设的时长阈值,则判定所述所述目标应用未发生卡顿。4.根据权利要求1所述的应用卡顿监控方法,其特征在于,所述判定所述所述目标应用发生卡顿的步骤之后,所述方法还包括:获取linkedhashmap保存的现场信息,以及所述linkedhashmap保存现场信息时的时间戳,以通过所述现场信息及所述时间戳分析卡顿原因。5.根据权利要求4所述的应用卡顿监控方法,其特征在于,所述获取linkedhashmap保存的现场信息,以及所述linkedhashmap保存现场信息时的时间戳的步骤具体包括:创建保存现场的守护线程,设定所述守护线程按预设间隔时长dump当前应用的现场信息;其中,所述现场信息至少包括堆栈信息、cpu信息;将所述现场信息通过所述linkedhashmap保存;获取所述linkedhashmap保存现场信息时的时间戳。6.根据权利要求1所述的应用卡顿监控方法,其特征在于,所述创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志的具体步骤包括:通过printer软件以自定义的方式创建自定义打印实例;通过anr监控方法将所述自定义打印实例写入所述目标应用的主线程,并通过所自定义打印实例输出日志。7.一种应用卡顿监控装置装置,其特征在于,包括:创建模块:用于创建自定义打印实例,并使目标应用的主线程通过所述自定义打印实例输出日志;调取模块,用于从消息队列中通过所述主线程的消息处理函数获取消息;计算模块:用于在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理
所耗的时长;判断模块,用于判断所述时长是否大于预设的时长阈值;第一判定模块,用于若所述时长大于预设的时长阈值,则判定所述所述目标应用发生卡顿。8.根据权利要求7所述的应用卡顿监控装置,其特征在于,所述计算模块包括:第一标记单元,用于在所述主线程逐个开始处理所述消息前,通过所述自定义打印实例以命名为开始消息字符串对当前打印开始处理进行标记,并为所述开始消息字符串串拼接上命名为开始时间戳,构成开始标记字符串;第二标记单元,用于当所述主线程处理完所述当前消息后,通过所述自定义打印实例以命名为结束消息字符串对所述当前消息处理完进行标记,并为所述结束消息字符串串拼接上命名为结束时间戳,构成结束标记字符串;计算单元,用于通过计算所述结束时间戳与所述开始时间戳的时长,以获取当前消息处理所耗的时长。9.一种计算机设备,包括存储器和处理器,所述存储器中存储有计算机可读指令,所述计算机可读指令被所述处理器执行时,使得所述处理器执行如权利要求1至6中任一项权利要求所述应用卡顿监控方法的步骤。10.一种存储介质,其特征在于,存储有计算机可读指令,所述计算机可读指令被处理器执行时实现如权利要求1至6中任一项所述应用卡顿监控方法的步骤。
技术总结
本发明提供了一种应用卡顿监控方法、装置、计算机设备和存储介质,其中,所述应用卡顿监控方法包括创建自定义打印实例,并使应用的主线程通过自定义打印实例输出日志;从消息队列中通过所述主线程的消息处理函数获取消息;在所述主线程逐个处理所述消息时,通过所述日志获取当前消息处理所耗的时长;判断所述时长是否大于预设的时长阈值;若是,则判定所述当前消息发生卡顿。因此,本发明的Android应用卡顿监控方法无需对源代码做任何改动且创建的自定义打印实例接入与实现更加简单。同时,本发明还涉及区块链技术。发明还涉及区块链技术。发明还涉及区块链技术。
技术研发人员:王彪
受保护的技术使用者:中国平安人寿保险股份有限公司
技术研发日:2022.02.17
技术公布日:2022/5/25
转载请注明原文地址:https://tc.8miu.com/read-10535.html