本文主要介绍Android移动终端的滑动性能测试方法,核心原理是通过 自动滑动+fps值

背景:

随着android手机的普及,大量的应用出现在android手机上。手机界面也随着手机硬件的发展越来越复杂化,随着用户对手机的体验越来越挑剔,一些界面也越来越美观,包含的元素也越来越多,比如电话本模块,在联系人列表上从原来简单的只显示姓名和电话,到现在得还要显示头像,显示微信和微博的绑定信息。还比如在主界面上的各种插件,及大量的应用图标等。当用户操作触屏手机时,需要在屏幕上滑动,如果手机性能不好,会出现卡顿的情况,这种情况会导致手机给用户留下不好的体验,所以我们需要一种可以量化滑动性能的方式。常见的方式是通过开启手机fps(每秒刷新帧率)的数值监测,再通过手动滑动,记录下滑动的fps数值。通过数值来决定某个界面的性能情况。但是这种方法不够准确,每次手动滑动的情况不能确定也会导致数值的变化较大。本文通过提出一种新的fps的数值的算法,先在测试模块自动填充模拟数据,再通过自动进入相应模块进行滑动的并记录fps自动生成更直观的数据写入到excel中。



关于FPS值:

FPS值一般用来在游戏运行等动画表现力的评测上,一般FPS数值越大,则反映系统处理动画的效果越好。但是在滑动界面的情况下,超过40左右人眼是很难区分出来是否有卡顿现象,所以需要获取真实的数值并且记录起来。

通过去找Android的底层方法,发现SurfaceFlinger这个类可以提供动画的绘制帧率数据。

通过adb命令:adb shell dumpsys SurfaceFlinger --latency,会出现如下的数据buffer

Android 监测nestscrollview 是否滑动到底部 手机滑动测试_时间戳

其中第二列我大概判断是unix的时间戳值,这里的每行数据即为当前实时的每帧生成的时间,这个命令生成的数据buffer大概有120+行,所以大概是2s左右的一个数据段。

其中我还发现有如下几个命令生成不一样的数据:


dumpsys SurfaceFlinger --latency   

获取默认的帧数据(128行帧生成时间戳的数据,取其中数值最高的1列作为计算的值)

dumpsys SurfaceFlinger --latency-clear

清除buffer区

dumpsys SurfaceFlinger  --list

当前界面的view列表

dumpsys SurfaceFlinger --latency <view name>

指定view的帧数据

dumpsys SurfaceFlinger --latency <package name>

指定包名的帧数据

dumpsys SurfaceFlinger --latency <package name>/<activity class name>

指定activity的帧数据



获取buffer后,再通过下面的处理


public void do_exec(final String cmd) {
		Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					// init data
					bufferArray = new ArrayList<String>();
					timeSpaceArray = new ArrayList<Double>();
					Process p = Runtime.getRuntime().exec(cmd);
					BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
					String line = null;
					while ((line = in.readLine()) != null) {
						String tt[] = line.split("\\s{1,}");
						// must match :length>10,is number
						if (tt.length > 1 && tt[1].length() >= 10 && mFunction.isNumeric(tt[1])) {
							bufferArray.add(tt[1]);
						}
					}
					computeFps();
					writeExcelOther();
					writeExcelFinal();
					if (p != null) {
						p.destroy();
					}
					if (in != null) {
						in.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
		thread.start();
	}
private void computeFps() {
		for (int i = bufferArray.size() / 2; i < bufferArray.size() - 1; i++) {
			// compute
			double timeSpace = Long.parseLong(bufferArray.get(i + 1)) - Long.parseLong(bufferArray.get(i));
			timeSpace /= 1000000000;
			// if timespace is too big ,set the value
			if (timeSpace > 1) {
				timeSpace = 1;
			} else {
				timeSpaceArray.add(timeSpace);
				allTimeSpace += timeSpace;
			}
		}
	}



最终将fps值写入到excel表格中


// write excel other
	private void writeExcelOther() {
		DecimalFormat df1 = new DecimalFormat("0.0000");
		double aveTimeSpace = allTimeSpace / (timeSpaceArray.size());
		String aveTimeSpaceString = df1.format(aveTimeSpace);
		DecimalFormat df = new DecimalFormat("0.00");
		String aveFps = df.format(1 / aveTimeSpace);
		// first title and result
		writeString(row, 0, StaticData.caseList.get(testNumber - 1).getName());
		writeString(row, 1, TEST_PACKAGE);
		writeString(row, 2, TEST_ACTIVITY);
		writeString(row, 3, aveFps);
	}





关于自动测试:



这块的内容比较多,因为获取fps值还不够,我们需要每次测试固定滑动手法,以及需要自动化填充数据来保证测试的环境,所以自动化执行滑动操作时必须的。