安卓性能監(jiān)控工具介紹(二)----工具介紹

前言

上一篇文章介紹了工具的數(shù)據(jù)采集部分,這段時間對工具頁面進行了優(yōu)化:

  • 增加清屏功能
  • 增加圖表顯示

新版本V1.1.0界面如下所示:


主界面.png

工具介紹

使用方法介紹

使用方法上一篇文章,已經(jīng)大致介紹過了,主要步驟如下:
(電腦環(huán)境配置什么的就不在贅述了)

  • 連接手機,點擊檢查設備,正常獲取返回設備SN號,獲取失敗,顯示‘No device found’
  • 打開待測應用,點擊獲取,獲取應用包名和activity
  • 下拉選擇更新時間
  • 開始測試,結(jié)束
  • 點擊圖表,顯示圖表(這邊暫時未做到實時顯示圖表,后續(xù)再優(yōu)化)

主界面介紹

基于QT Designer工具,添加需要的pushbutton、textedit等控件,這個上一篇文章已經(jīng)介紹過了,QT Designer的簡單使用,就不再多說了。
這篇文章就重點說一下核心代碼部分和遇到的問題及解決方法吧。
過程中主要遇到了兩個問題:
1.數(shù)據(jù)采集過程中,需要在保留原有數(shù)據(jù)的基礎上,不斷添加新數(shù)據(jù)
2.圖表的展示

流量的統(tǒng)計

數(shù)據(jù)采集部分,主要代碼如下:
采用

adb shell cat /proc/net/xt_qtaguid/stats | findstr uid

命令獲取到的流量是一個total值,而我們需要統(tǒng)計的是一段時間內(nèi)的值,所以這邊采用兩個值相減的方法,即根據(jù)選擇的更新時間,后一個減去前一個的結(jié)果,得到這段時間內(nèi)的統(tǒng)計值

#獲取流量
receive = []
sendflow = []
all = []
def flow():
    cmd = 'adb -s '+ get_devices() +' shell cat /proc/net/xt_qtaguid/stats | findstr '+ uid()
    print (cmd)
    flow_info = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines()
    down = 0
    up = 0
    if len(flow_info)>= 1:
        for flow in flow_info:
            down =down + int(flow.split()[5])
            up = up+ int(flow.split()[7])
        receive.append(down)
        sendflow.append(up)
    print (receive,sendflow)
    return (receive,sendflow)

def getflow():
    (receive,sendflow) = flow()
    recev = []
    send = []
    allflow = []
    print(len(receive))
    for i in range(len(receive)-1):
        recev.append((int(receive[i+1]) - int(receive[i]))//1024)
        send.append((int(sendflow[i+1]) - int(sendflow[i]))//1024)
        allflow.append(recev[i]+send[i])
    print(recev,send,allflow)
    return recev,send,allflow

其他的相對簡單,直接把獲取到的值,最后一個append到textedit中即可以了

QTimer的使用

加入QTimer主要是為了解決,在寫數(shù)據(jù)的過程中,不斷往原有數(shù)據(jù)上append新采集到數(shù)據(jù)的問題,同時不至于是應用無響應。

初始化一個定時器,把定時器的timeout信號和slotadd()槽函數(shù)連接。

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.slotadd)

slotadd()往五個textedit中寫數(shù)據(jù)
由于返回的數(shù)據(jù)是一個列表,所以每次只需要取最新的即最后一個數(shù)據(jù)即可。

    def slotadd(self):
        '''
        往mem、cpu、flow寫數(shù)據(jù)
        :return:
        '''
        memlist = adb.mem()
        mem = 'mem占用:'+ str(memlist[-1])
        cpulist = adb.cpu()
        cpu = 'cpu占用:'+ str(cpulist[-1])
        self.ui.mem.append(mem)
        self.ui.cpu.append(cpu)
        (recevice,send,allflow)=adb.getflow()
        receflow = '下載流量:' + str(int(recevice[-1]))
        sendflow = '上傳流量:' + str(int(send[-1]))
        alladd = '總流量:' + str(int(allflow[-1]))
        self.ui.recv.append(receflow)
        self.ui.send.append(sendflow)
        self.ui.all.append(alladd)

點擊開始按鈕,啟動定時器,并使開始按鈕失效


    def startTimer(self):
        '''
        設置時間間隔并啟動定時器
        :return:
        '''
        self.timer.start(self.wait_time())
        self.ui.start.setEnabled(False)
        self.ui.end.setEnabled(True)

點擊結(jié)束按鈕,停止定時器,并使開始按鈕生效。

    def endTimer(self):
        self.timer.stop()
        self.ui.start.setEnabled(True)

Matplotlib的應用

Matplotlib是python常用的繪圖模塊,提供了一套與MATLAB 相似的命令API,用來交互式的繪圖,非常方便。

設置繪圖類

新增一個MatplotlibWidget.py文件,創(chuàng)建FigureCanvas類,在初始化過程中建立一個空白圖像。

class MyMplCanvas(FigureCanvas):
    """FigureCanvas的最終的父類其實是QWidget。"""

    def __init__(self, parent=None, width=5, height=4, dpi=100):

        # 配置中文顯示
        plt.rcParams['font.family'] = ['SimHei']  # 用來正常顯示中文標簽
        plt.rcParams['axes.unicode_minus'] = False  # 用來正常顯示負號

        self.fig = plt.figure(figsize=(width, height), dpi=dpi)  # 新建一個figure

        self.axes = self.fig.add_subplot(111)  # 建立一個子圖,如果要建立復合圖,可以在這里修改

        self.axes.hold(False)  # 每次繪圖的時候不保留上一次繪圖的結(jié)果
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)

        '''定義FigureCanvas的尺寸策略,這部分的意思是設置FigureCanvas,使之盡可能的向外填充空間。'''
        FigureCanvas.setSizePolicy(self,
                                   QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

定義繪圖函數(shù),調(diào)用這個函數(shù)可以在上面所創(chuàng)建的空白圖像中繪圖。

    def start_static_plot(self):

        self.fig.suptitle('圖表')
        a=[1,2,4,2,3,1,2,3,4,2]
        self.axes.plot(a)
        self.axes.set_ylabel('number')
        self.axes.grid(True)
封裝繪圖類

這部分主要把上面的繪圖類和工具欄封裝到MatplotlibWidget中,只需要調(diào)用MatplotlibWidget這個類就可以實現(xiàn)繪圖功能;

class MatplotlibWidget(QWidget):
    def __init__(self, parent=None):
        super(MatplotlibWidget, self).__init__(parent)
        self.initUi()

    def initUi(self):
        self.layout = QVBoxLayout(self)
        self.mpl = MyMplCanvas(self, width=5, height=4, dpi=100)
        self.mpl.start_static_plot() 
        self.mpl_ntb = NavigationToolbar(self.mpl, self)  # 添加完整的 toolbar

        self.layout.addWidget(self.mpl)
        self.layout.addWidget(self.mpl_ntb)

測試程序:


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui = MatplotlibWidget()
    ui.mpl.start_static_plot()  # 測試靜態(tài)圖效果
    ui.show()
    sys.exit(app.exec_())

結(jié)果運行,如圖所示:


圖表.png

設置提升窗口控件

在QT Designer中右擊提升窗口部件,新建一個QWidget類,名稱和頭文件均為 MatplotlibWidget


升級.png

在.ui文件中加入widget并升級


升級widget.png

MatplotlibWidget的使用

首先初始化模型:

class Main(QMainWindow,Ui_Form):

    def __init__(self,parent=None):
        super(Main,self).__init__(parent)
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.setWindowTitle('Waiqin365-AATT-V1.1.0')
        self.ui.mem_plot.setVisible(False)

初始化中隱藏圖像,設置按鈕的出發(fā)操作,同時使得圖像可見并出發(fā)繪圖函數(shù)

    @pyqtSlot()
    def on_pushButton_clicked(self):
        self.ui.mem_plot.setVisible(True)
        self.ui.mem_plot.mpl.start_static_plot()

測試程序:

if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    ui = Main()
    ui.show()
    sys.exit(app.exec_())

運行結(jié)果如下所示:


頁面.png

思考

雖然工具優(yōu)化到V1.1.0版本,但是仍存在很多不足的情況,目前遇到的問題:
1.打包成exe文件后,無法使用
2.缺少對手機狀態(tài)的監(jiān)控,斷開連接后,沒有自動停止
3.還不能動態(tài)展示圖表
后面有時間將一一攻破這些難題,歡迎有ideal的小伙伴多提提意見

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容