2016年7月

上一章完成了FPS的命令行版本的查看工具,这一章节开始学习绘制FPS的曲线。

在编写之前,谷歌了一圈,发现有一个叫mathplot的插件不错。开始读文档开战,插件官网地址:http://matplotlib.org/,看完demo,目标是能动态显示曲线。

废话少说,贴代码:

#coding:utf-8
import os,time
import matplotlib.pyplot as plt

def checkadb():
	return os.path.exists('adb')

def checkdevices():
	rt = os.popen('adb devices')
	t = rt.readline()
	rt.close()
	return t

def getframe():
	cmd = "adb shell \"service call SurfaceFlinger 1013|busybox cut -d \( -f 2|busybox cut -d \\' -f 0 \""
	r = os.popen(cmd)
	text = r.read()
	r.close()
	return text

def getfps():
	starttime = round(time.time()*1000)
	startframe = int(getframe(), 16)
	time.sleep(0.001)
	endtime = round(time.time()*1000)
	endframe = int(getframe(),16)
	fps = (endframe - startframe)*1000/(endtime - starttime)
	return fps

def draw():
	plt.ion()
	plt.xlabel("Time(s)")
	plt.ylabel("FPS")
	plt.title("FPS Test Tool For root android device v1.0 \n By Wanyor")
	plt.xlim(0,60)  #首先得设置一个x轴的区间 这个是必须的
	plt.ylim(0,100) # y轴区间 
	m = []
	x=0
	while True:
		x=x+1
		if x>60:
			plt.xlim(x-59,x)
		m.append(getfps())  #存入list里面
		plt.plot(m,label="$fps$",color="red",linewidth=1) #将list传入plot画图
		plt.pause(0.0001) # 这个为停顿0.01s,能得到产生实时的

def usage():
	print 'Print fps realtime for a rooted android device.'
	print ''
	print 'Author: wangyong11@qiku.com 2016-6-15 17:38:43\n'	
	print 'You can stop it use ctrl+c \n'


def main():
	#if checkadb():
	usage()
	try:
		draw()
	except Exception, e:
		raise e
	finally:
		print "Buddy, android devices must root!!!"
	'''
	else:
		print 'Please install adb toolkit!'
	'''

if __name__ == '__main__':
	main()

前提:
最近做APP测试需要测FPS来评估流畅度,检查应用是否有卡顿。

开始干活:
0x00.首先谷歌一圈看看FPS原理,找到TesterHome上面有介绍FPS测数据的,还有一个就是腾讯开源的GT随身调,git clone下来源代码学习一番。GT源码地址:Github
0x01.开始看源码,但是它这个实现方式需要root权限才能读取相关数据。
参考Q博士的文章:http://blog.csdn.net/itfootball/article/details/43084527
大概的原理是:
1.adb shell dumpsys SurfaceFlinger --latency命令产生fps数据.
2.通过service call SurfaceFlinger 1013 来得到当前帧的索引以及时间戳,设置为A = {indexA,timeA}.
3.公式:
设上一次的数据为B = {indexB,timeB}
FPS = (indexA-indexB)/(timeA-timeB)
0x02.开工,拿自己稍微熟一些的Python开始coding。
以下是Python写的获取FPS的demo,代码写的很差。

    #coding:utf-8
    import os,time

    def checkadb():
        return os.path.exists('adb')

    def checkdevices():
        rt = os.popen('adb devices')
        t = rt.readline()
        rt.close()
        return t

    def getframe():
        cmd = "adb shell \"service call SurfaceFlinger 1013|busybox cut -d \( -f 2|busybox cut -d \\' -f 0 \""
        r = os.popen(cmd)
        text = r.read()
        r.close()
        return text

    def getfps():
        starttime = round(time.time()*1000)
        startframe = int(getframe(), 16)
        time.sleep(0.001)
        endtime = round(time.time()*1000)
        endframe = int(getframe(),16)
        fps = (endframe - startframe)*1000/(endtime - starttime)
        return fps

    def usage():
        print 'Print fps realtime for a rooted android phone.'
        print ''
        print 'Author: wangyong11@qiku.com 2016-6-15 17:38:43\n'    
        print 'You can stop it use ctrl+c \n'


    def main():
        usage()
        try:
            while 1:
                print getfps()
        except:
            print "Stop by yourself!"
        finally:
            print "Buddy, android devices must root!!!"        

    if __name__ == '__main__':
        main()

大概讲解下:通过上述的命令直接获取单位时间的帧索引差值,然后除以时间,即为FPS。
ps:以上的demo只能实时查看fps,不够直观,下一节完善下,做成实时滚动的曲线图。