android性能测试工具Emmagee介绍

转自:http://qa.blog.163.com/blog/static/19014700220126105354565/

Emmagee是基于Android开发的用于测试指定android应用性能的小工具。

Emmagee已开源:https://github.com/NetEase/Emmagee

大家在使用过程中有问题,欢迎反馈,后续我们会持续跟进。

支持SDK: Emmagee支持android2.2以及以上版本。

功能点:

1、检测当前时间被测应用占用的CPU使用率以及总体CPU使用量

2、检测当前时间被测应用占用的内存量,以及占用的总体内存百分比,剩余内存量

3、检测应用从启动开始到当前时间消耗的流量数

4、测试数据写入到CSV文件中,同时存储在手机中

5、在所有应用的最上层浮窗显示以上的实时数据信息,浮窗可以移动,同时可以在设置选项配置是否显示浮窗。

6、在浮窗中可以快速启动或者关闭手机的wifi网络。


CSV文件内容的输出格式:

android性能测试工具Emmagee介绍_第1张图片
 


实现原理:


选择并且启动需要监控的应用

参考资料:http://www.cnblogs.com/feng88724/archive/2011/02/21/1961222.html

思路:先找出所有已安装的非系统的应用程序,使用ListView显示,已启动或者已有服务运行的程序显示图标,方便区分

重要的类:ActivityManagerPackageManager

重要代码: 

1.获取所有安装的程序(包括系统的程序):PackageManager类下的getInstalledApplications方法

2.获取正在运行的应用程序:ActivityManager下的getRunningAppProcesses方法,与1比较将正在运行的程序的图标显示出来

3.过滤掉系统的程序和程序自身:

if (((appinfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0)|| (appinfo.processName.equals("com.netease.qa.ptt"))) {    

              continue;

           }

4.继承于baseAdapterListAdapter(自己写)来输出ListView并显示所有安装的非系统程序 

  重点:getView(int position, View convertView, ViewGroup parent)方法,里面是ListView的显示

5.getPackageManager.getLaunchIntentForPackage(packageName),返回一个intent,这个intent用来启动这个packageName包中的一个activity的主要口(front-

  door),该方法通过获得packageName启动选中的应用程序

6.保证RadioButton按钮在ListView中实现单选功能:

  public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {

    if (isChecked) {

       hasChecked = true;

         if (temp != -1) {

             RadioButton tempButton = (RadioButton) findViewById(temp);

             if (tempButton != null) {

                  tempButton.setChecked(false);

             }

         }

           if (temp == position) {

              holder.rb.setChecked(true);

           }

监控应用CPU 

参考链接: http://www.blogjava.net/fjzag/articles/317773.html

数据全部都是jiffies为单位的,jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在Linux中,一个节拍大致可理解为操作

系统进程调度的最小时间片,不同linux内核可能值有不同,通常在1ms10ms之间)

重要的类:RandomAccessFile,BufferWriter,OutputStreamWriter,FileOutputStream

主要代码:RandomAccessFile(File_name, "r");

1.总体CPU监控 

原理:由于Android系统是基于Linux内核的,所以系统文件的结构和Linux下一样,系统总体CPU使用信息是放在/proc/stat/文件下,/proc/cpuinfo文件下是

存放CPU的其他信息,包括CPU名称,直接读取即可

android性能测试工具Emmagee介绍_第2张图片
 

user (480826)     从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。 

nice (6665)       从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间

system (236914)   从系统启动开始累计到当前时刻,处于核心态的运行时间 

idle (7212750)   从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间 

iowait (211630)   从系统启动开始累计到当前时刻,IO等待时间 

irq (39)          从系统启动开始累计到当前时刻,硬中断时间

softirq (1876)    从系统启动开始累计到当前时刻,软中断时间

注意:其中cpu480003中间有两个空格的,如果用split("")分割则会有一个空字符串

其中toks数组中存放第一行字符串用空格分隔后的字符串

CPU时间:totalCputime=Long.parseLong(toks[2]) + Long.parseLong(toks[3])+ Long.parseLong(toks[4]) + Long.parseLong(toks[6])

+ Long.parseLong(toks[5]) +  Long.parseLong(toks[7])+ Long.parseLong(toks[8])

CPU空闲时间:idle=Long.parseLong(toks[5])

2.单个程序CPU监控

原理:将选中的RadioButton对应程序的PID传入,读取/proc/PID/stat文件信息即可获得该PID对应程序的CPU信息

Android性能测试工具实现介绍 - kevinkong - 风之云的足迹
 

PID=15916                      程序PID

PackageName=<d.process.acore>  程序包名

utime=1026                     该任务在用户态运行的时间

stime=2687                     该任务在核心态运行的时间

cutime=0                       所有已死线程在用户态运行的时间

cstime=0                       所有已死在核心态运行的时间

tok数组中存放该文件中的信息用空格分隔后的字符串

单个程序CPU使用率:threadCpuTime=Long.parseLong(tok[13]) + Long.parseLong(tok[14]) + Long.parseLong(tok[15]) + 

Long.parseLong(tok[16]) 

3.计算方法:

设定一个时间差,比如5s,取出六个值totalCputime1totalCputime2idle1idle2processCpuTime2processCpuTime1,其中计算公式如下:

CPU总使用率(%)  100*((totalCputime2- totalCputime1)-(idle2-idle1))/(totalCputime2-totalCputime1) 

单个程序的CPU使用率(%) = 100*(processCpuTime2-processCpuTime1)/(totalCpuTime2-totalCpuTime1) 

监控应用消耗流量

重要的类:TrafficStats,RandomAccessFile

首先要获取选中程序的UID,流量文件和API都是需要用到

UID:每个程序只要安装后都会存在一个UID,未运行的也存在,

(1)方法一:直接使用TrafficStats类中的方法获取: (只在Android2.2以及以上版本中在存在此API)

总接受流量TrafficStats.getTotalRxBytes()

总发送流量TrafficStats.getTotalTxBytes())

不包含WIFI的手机GPRS接收量TrafficStats.getMobileRxBytes())

不包含Wifi的手机GPRS发送量TrafficStats.getMobileTxBytes())

某一个进程的总接收量TrafficStats.getUidRxBytes(Uid))

某一个进程的总发送量TrafficStats.getUidTxBytes(Uid))

注意:这些都是从一次开机到一次关机的统计量,所以,做某一个程序的流量统计的时候,一定要注意开关机,和本次开机后是第几次启动本程序。

(2)方法二:同样的,系统自带的也有文件存放整体的流量和针对单个程序的流量统计

/proc/net/dev/proc/uid_stat/UID下面有tcp_rcvtcp_snd文件分别存放下行流量和上行流量

监控内存实现原理

参考资料:http://blog.csdn.net/qinjuning/article/details/6978560

                http://blog.csdn.net/kieven2008/article/details/6445421

实现原理:
1、获取当前被测应用占用的内存

首先获取到当前被测应用的PID(进程id),然后按照pid调用android的API获取当前被测应用占用的内存。

   //生成 ActivityManager  对象

   ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);  // 获得该进程占用的内存 

int[] myMempid = new int[]? ?( ?pid );  

// 此MemoryInfo位于android.os.Debug.MemoryInfo包中,用来统计进程的内存信息  

Debug.MemoryInfo[] memoryInfo = am.getProcessMemoryInfo(myMempid);  

// 获取进程占内存用信息 kb单位  

memoryInfo[0].getTotalSharedDirty();

  //这里使用getTotalPss返回的消耗内存值和其它相应软件做对比是最接近

 int memSize = memoryInfo[0].getTotalPss();

   关于VSS、RSS、PSS、USS介绍

 VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)

? RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)

? PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)

? USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)

一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

2、获取当前设备剩余内存

ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo(); 

ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 

am.getMemoryInfo(outInfo); 

long avaliMem = outInfo.availMem;

long avaliKbMem = avaliMem/1024;   //转换成KB  

3、获取当前设备的内存总数

 “/proc/meminfo”文件记录了android手机的一些内存信息,在命令行窗口里输入”adb shell”,进入shell环境,输入”cat /proc/meminfo”即可在命令行

里显示meminfo文件的内容。cat /proc/meminfo

MemTotal:          94096 kB
MemFree:            1684 kB
Buffers:              16 kB

  只需要读取这个文件就可以,获取到的MemTotal的值就是内存的总数

android悬浮窗口实现原理

android中可以拖动的悬浮窗口的实现参考如下文章  http://blog.csdn.net/wljie2008/article/details/6654141

你可能感兴趣的:(android,性能测试)