Android进程性能监控工具Honeybadger实现
2015-02-07 19:52
2646 查看
Android进程性能监控工具Honeybadger实现
这是一个Android平台上的进程监控工具,可以实现对本机上安装的非系统app的进程的CPU利用率、PSS、网络上下行流量等数据进行准实时监控,并展示图形化结果(折线图)。
工具名称为:Honeybadger
百度移动下载地址:http://as.baidu.com/a/item?docid=6528832&pre=web_am_se
腾讯应用宝下载地址:
http://m4.qq.com/app/appDetails.htm?apkName=com.winstonwu.honeybadger&apkCode=1&dp=2&kword=&appId=10623688#
运行的效果图如下:
![](https://173.255.143.197/browse.php?u=hxejFmQwlqJa6iCCYLt%2BmaXM%2FrVELWeISMfmlRcQJc4zsDjw%2B3pCl7w6mf8eMLWQljxgf5BnsCK1Sd4Ob5PTJoAqEtHfR6XWMe6rbhYIw5b4XNxDIWW%2BejHxmQl8HORo%2BloWDw105OYBTI2j3Oehf0GAfav2YDEKSOaRfLZplFwfrxHM8CP8y71S121LgEGwod1YJwBB3Km7tVhU%2FE3TQB006gARJXGue3Axw2xwrQ%3D%3D&b=14)
![](https://173.255.143.197/browse.php?u=hxejFmQwlqJa6iCCYLt%2BmaXM%2FrVELWeISMfmlRcQJc4ytjT483tCl7w6mf8eMLWQljxgf5BnsCK1Sd4Ob5PTJoAqEtHfR6XWMe6rbhYIw5b4XNxDIWW%2BejHxmQl8HORo%2BloWDw105OYBTI2j3Oehf0GAfav2YDEKSOaRfLZplFwfrxHM8CP8y71S121LgEGwod1YJwBB3Km7tVhU%2FE3TQB006gARJXGue3Axw2xwrQ%3D%3D&b=14)
![](https://173.255.143.197/browse.php?u=hxejFmQwlqJa6iCCYLt%2BmaXM%2FrVELWeISMfmlRcQJc4wtTLw83hCl7w6mf8eMLWQljxgf5BnsCK1Sd4Ob5PTJoAqEtHfR6XWMe6rbhYIw5b4XNxDIWW%2BejHxmQl8HORo%2BloWDw105OYBTI2j3Oehf0GAfav2YDEKSOaRfLZplFwfrxHM8CP8y71S121LgEGwod1YJwBB3Km7tVhU%2FE3TQB006gARJXGue3Axw2xwrQ%3D%3D&b=14)
![](https://173.255.143.197/browse.php?u=hxejFmQwlqJa6iCCYLt%2BmaXM%2FrVELWeISMfmlRcQJc4wtjL8%2FHRCl7w6mf8eMLWQljxgf5BnsCK1Sd4Ob5PTJoAqEtHfR6XWMe6rbhYIw5b4XNxDIWW%2BejHxmQl8HORo%2BloWDw105OYBTI2j3Oehf0GAfav2YDEKSOaRfLZplFwfrxHM8CP8y71S121LgEGwod1YJwBB3Km7tVhU%2FE3TQB006gARJXGue3Axw2xwrQ%3D%3D&b=14)
![](https://173.255.143.197/browse.php?u=hxejFmQwlqJa6iCCYLt%2BmaXM%2FrVELWeISMfmlRcQJc4wsDP5%2FX5Cl7w6mf8eMLWQljxgf5BnsCK1Sd4Ob5PTJoAqEtHfR6XWMe6rbhYIw5b4XNxDIWW%2BejHxmQl8HORo%2BloWDw105OYBTI2j3Oehf0GAfav2YDEKSOaRfLZplFwfrxHM8CP8y71S121LgEGwod1YJwBB3Km7tVhU%2FE3TQB006gARJXGue3Axw2xwrQ%3D%3D&b=14)
![](https://173.255.143.197/browse.php?u=hxejFmQwlqJa6iCCYLt%2BmaXM%2FrVELWeISMfmlRcQJc43tDDx%2FHlCl7w6mf8eMLWQljxgf5BnsCK1Sd4Ob5PTJoAqEtHfR6XWMe6rbhYIw5b4XNxDIWW%2BejHxmQl8HORo%2BloWDw105OYBTI2j3Oehf0GAfav2YDEKSOaRfLZplFwfrxHM8CP8y71S121LgEGwod1YJwBB3Km7tVhU%2FE3TQB006gARJXGue3Axw2xwrQ%3D%3D&b=14)
关键点总结:
1.进程CPU的利用率如何计算
Android应用是以Linux用户的模式运行在Linux之上,Linux的/proc路径下有相关统计文件,如/proc/stat文件记录了系统自开机以来的CPU时间片使用情况,该文件的第一行记录即为总的CPU使用情况记录,而如果想要查看某一指定进程的时间片段使用情况,需要首先查询到该进程的pid(可以在运行app后,通过adb shell 查询),之后/proc/pid/stat文件中便记录了该进程的时间片使用情况。(更进一步,线程级的时间片使用情况记录在/proc/pid/task/tid/stat文件中)。文件的具体格式这里不多叙述,网上有很多介绍。
某进程CPU使用率计算的方法就是:分别读出某一初始时间CPU总的时间片使用情况,以及该时间点某一进程的时间片使用情况,然后经过一个很短的时间片段,比如800毫秒,再一次读取CPU总的时间片使用情况以及该待测进程的时间片使用情况。那么在这800毫秒内该进程的CPU占用率可以通过该段时间内该进程时间片的增量与CPU总的时间片增量作商得到。
分析CPU文件的类实现如下,pickOne方法用来实现一次取样:
2.实际物理内存占用以及网络流量情况如何计算
内存占用情况同样可以通过分析/proc下的文件得到,不过Android已经提供了现成的API封装了这些操作:
计算指定pid的PSS占用:
计算指定uid当前已发送的字节数:
TrafficStats.getUidTxBytes(uid);
已接收的字节数:
TrafficStats.getUidRxBytes(uid);
取样两次,作差,便能得到某一时间段内的上下行流量情况。
注意,这里需要传入的参数是进程的uid而不是pid。
3.读取当前设备上已安装应用的列表,将包名、应用名、版本信息等显示到一个ListView控件中,实现选中具体项的功能:
布局文件内容为:
后台代码为:
4.创建悬浮窗,并使其始终显示在前端,不会因为打开其他应用,内存不足而被关闭
工具实现了一个悬浮窗,准实时地显示当前的取样数据,为了保证在操作待测应用的过程中,悬浮窗不会因为内存短缺而被系统回收,所以将悬浮窗的实现挂在一个Service上(而不是Activity),并且将Service设置为前台Service:
绘制悬浮窗:
设置前台Service:
5.由应用包名获取进程pid
因为进程没有运行时是无法获取到pid的,所以在点击开始测试的按钮后,应该先判断一下待测应用当前是否在运行,如果没有,需要先打开待测应用,并设置一个时间延长让系统初始化相应的目录。
6.定时器的代码片段如下
主要完成两件工作:一是获取采样数据并存入静态ArrayList以便后续导出使用,二是修改悬浮窗上的数据。
参考文献:
android ListView详解:http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html
Android 进程内存、CPU使用查看:http://blog.csdn.net/hgl868/article/details/6793041
Linux平台Cpu使用率的计算:http://www.blogjava.net/fjzag/articles/317773.html
android悬浮窗口的实现:http://blog.csdn.net/stevenhu_223/article/details/8504058
Android新手之旅(9) 自定义的折线图:
http://www.cnblogs.com/jetz/archive/2011/07/24/2115238.html
内存耗用:VSS/RSS/PSS/USS:http://blog.csdn.net/adaptiver/article/details/7084364
What is dirty memory?:http://www.linuxformat.com/forums/viewtopic.php?p=56436
这是一个Android平台上的进程监控工具,可以实现对本机上安装的非系统app的进程的CPU利用率、PSS、网络上下行流量等数据进行准实时监控,并展示图形化结果(折线图)。
工具名称为:Honeybadger
百度移动下载地址:http://as.baidu.com/a/item?docid=6528832&pre=web_am_se
腾讯应用宝下载地址:
http://m4.qq.com/app/appDetails.htm?apkName=com.winstonwu.honeybadger&apkCode=1&dp=2&kword=&appId=10623688#
运行的效果图如下:
关键点总结:
1.进程CPU的利用率如何计算
Android应用是以Linux用户的模式运行在Linux之上,Linux的/proc路径下有相关统计文件,如/proc/stat文件记录了系统自开机以来的CPU时间片使用情况,该文件的第一行记录即为总的CPU使用情况记录,而如果想要查看某一指定进程的时间片段使用情况,需要首先查询到该进程的pid(可以在运行app后,通过adb shell 查询),之后/proc/pid/stat文件中便记录了该进程的时间片使用情况。(更进一步,线程级的时间片使用情况记录在/proc/pid/task/tid/stat文件中)。文件的具体格式这里不多叙述,网上有很多介绍。
某进程CPU使用率计算的方法就是:分别读出某一初始时间CPU总的时间片使用情况,以及该时间点某一进程的时间片使用情况,然后经过一个很短的时间片段,比如800毫秒,再一次读取CPU总的时间片使用情况以及该待测进程的时间片使用情况。那么在这800毫秒内该进程的CPU占用率可以通过该段时间内该进程时间片的增量与CPU总的时间片增量作商得到。
分析CPU文件的类实现如下,pickOne方法用来实现一次取样:
importjava.io.BufferedReader; import java.io.File; importjava.io.FileReader; importjava.io.IOException; import java.lang.Thread; public class ParseStatFile { private int pid; public ParseStatFile(int i){ pid = i; } public float pickOne() throwsInterruptedException{ try{ CPU c1 = new CPU(); CPUofProccp1 = new CPUofProc(pid); c1.fillCPU(); cp1.fillCPUofProc(); Thread.sleep(800); CPU c2 = new CPU(); CPUofProccp2 = new CPUofProc(pid); c2.fillCPU(); cp2.fillCPUofProc(); returncpuRateOfProc(c1,c2,cp1,cp2); } catch (Exception ex){ return 0; } } public static StringgetStringFromFile(String filename){ StringFileName=filename; StringfileStr = ""; File myFile=new File(FileName); if(!myFile.exists()) { System.err.println("Can't Find " + FileName); } try { BufferedReader in = new BufferedReader(newFileReader(myFile)); String str; while ((str =in.readLine()) !=null) { fileStr+=str; } in.close(); } catch (IOException e) { e.getStackTrace(); } return fileStr; } private class CPU{ int user =0; int nice =0; int system = 0; int idle = 0; int iowait=0; int irq = 0; int softtirq = 0; int stealstolen = 0; int guest = 0; public CPU(){ } public void fillCPU(){ StringfileName = "/proc/stat"; StringstrOfFile = getStringFromFile(fileName); String[]arr= strOfFile.split("\\s+");//@ user = Integer.parseInt(arr[1]); nice = Integer.parseInt(arr[2]); system = Integer.parseInt(arr[3]); idle = Integer.parseInt(arr[4]); iowait = Integer.parseInt(arr[5]); irq = Integer.parseInt(arr[6]); softtirq = Integer.parseInt(arr[7]); stealstolen = Integer.parseInt(arr[8]); guest = Integer.parseInt(arr[9]); } public int sum(){ returnuser+nice+system+idle+iowait+irq+softtirq+stealstolen+guest; } } private class CPUofProc{ int pid; int utime=0; int stime=0; int cutime=0; int cstime=0; public CPUofProc(int i){ pid=i; } public void fillCPUofProc(){ StringfileName = "/proc/"+Integer.toString(pid)+"/stat"; StringstrOfFile = getStringFromFile(fileName); String[]arr= strOfFile.split("\\s+"); utime = Integer.parseInt(arr[13]); stime = Integer.parseInt(arr[14]); cutime = Integer.parseInt(arr[15]); cstime = Integer.parseInt(arr[16]); } public int sum(){ returnutime+stime+cutime+cstime; } } private float cpuRateOfProc(CPUc1,CPU c2,CPUofProc cp1,CPUofProc cp2){ float x =(float)(cp2.sum()-cp1.sum()); float y = (float)(c2.sum()-c1.sum()); float r = x/y; if(r<0){ return 0; } if(r>1){ return 0.9999f; } return x/y; } }
2.实际物理内存占用以及网络流量情况如何计算
内存占用情况同样可以通过分析/proc下的文件得到,不过Android已经提供了现成的API封装了这些操作:
计算指定pid的PSS占用:
private ActivityManageram; am = (ActivityManager)FxService.this.getSystemService(ACTIVITY_SERVICE); MemoryInfo pidMemoryInfo=am.getProcessMemoryInfo(pids)[0]; int totalPss =pidMemoryInfo.getTotalPss();
计算指定uid当前已发送的字节数:
TrafficStats.getUidTxBytes(uid);
已接收的字节数:
TrafficStats.getUidRxBytes(uid);
取样两次,作差,便能得到某一时间段内的上下行流量情况。
注意,这里需要传入的参数是进程的uid而不是pid。
3.读取当前设备上已安装应用的列表,将包名、应用名、版本信息等显示到一个ListView控件中,实现选中具体项的功能:
布局文件内容为:
<?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tmptv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:textColor="#000000" android:textSize="16sp" android:text="@string/waitchoose"/> <Button android:id="@+id/button_back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_alignParentRight="true" android:background="@drawable/btn_selector" android:text="@string/commit"/> </RelativeLayout> <ListView android:id="@+id/lv" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/row_selector" android:scrollbars="vertical"/> </LinearLayout>
后台代码为:
public class AUTListActivity extends Activity { private StringpackageName =""; private StringappName =""; private Buttonbtn; private TextViewtv; private ProgressDialogprogressDialog =null; private ListViewlv; List<Map<String, Object>> listData=null; Handler handler = null; class myThreadimplements Runnable{ public void run() { getData(); handler.post(runnableUi); //把该runnable对象放到handle对象关联的线程中执行。因为runnable中是对UI的处理,所以该handler对象一定要与UI线程关联 } } Runnable runnableUi=new Runnable(){ @Override public void run() { //更新界面 progressDialog.dismiss(); bindDataToListView(); } }; @Override protected void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_autlist); setTitle("选择测试对象"); progressDialog =ProgressDialog.show(AUTListActivity.this, "请稍等...","正在读取本机上安装的App...",true); btn =(Button)findViewById(R.id.button_back); btn.setOnClickListener(newView.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(); if(AUTListActivity.this.packageName!=null){ intent.putExtra("packageName",AUTListActivity.this.packageName); Log.v("放进去的package name为",packageName); intent.putExtra("appName",AUTListActivity.this.appName); intent.setClass(AUTListActivity.this,OptionActivity.class); startActivity(intent); overridePendingTransition(R.anim.new_dync_in_from_right, R.anim.new_dync_out_to_left); } else{ Toast.makeText(getApplicationContext(), "请从列表选择待测试的应用", Toast.LENGTH_SHORT).show(); } finish(); } }); tv =(TextView)findViewById(R.id.tmptv); lv = (ListView)findViewById(R.id.lv); lv.setScrollContainer(true);//---------------否则不能滚动 handler = new Handler(); //一定要在UI线程中创建该Handler对象,因为Handler对象总是与创建它的线程的事件队列相关联 new Thread(newmyThread()).start(); lv.setOnItemClickListener(newOnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, Viewarg1, int arg2,long arg3) { HashMap<String,String> map=(HashMap<String,String>)lv.getItemAtPosition(arg2); String name=map.get("name"); String packagename=map.get("packagename"); tv.setText("已选择:"+name); AUTListActivity.this.packageName = packagename; AUTListActivity.this.appName = name; } }); } private voidbindDataToListView(){ SimpleAdapteradapter = new SimpleAdapter(this,listData,R.layout.item_layout, new String[]{"icon","name","version","packagename"}, new int[]{R.id.icon,R.id.name,R.id.version,R.id.packagename}); adapter.setViewBinder(newSimpleAdapter.ViewBinder(){ //显示图标,不能直接绑定Drawable public boolean setViewValue(Viewview,Object data,String textRepresentation){ if(viewinstanceof ImageView && datainstanceof Drawable){ ImageView iv=(ImageView)view; iv.setImageDrawable((Drawable)data); returntrue; } else return false; } }); lv.setAdapter(adapter); } private void getData() { ArrayList<AppEntity>appList = getAppEntityList(); List<Map<String,Object>> list = new ArrayList<Map<String, Object>>(); for(int i=0;i<appList.size(); i++){ AppEntityapp = (AppEntity)appList.get(i); Map<String,Object> map = new HashMap<String, Object>(); //BitmapDrawable bd = (BitmapDrawable)app.appIcon; //Bitmap bm = bd.getBitmap(); map.put("icon", app.appIcon); map.put("name", app.appName); map.put("version", app.versionName); map.put("packagename", app.packageName); list.add(map); } listData = list; } private ArrayList<AppEntity>getAppEntityList(){ List<PackageInfo>packages = getPackageManager().getInstalledPackages(0); //@ ArrayList<AppEntity>appList = new ArrayList<AppEntity>();//用来存储获取的应用信息数据 AppEntitytmpEntity; for(inti=0;i<packages.size();i++) { PackageInfopackageInfo = packages.get(i); if((packageInfo.applicationInfo.flags &ApplicationInfo.FLAG_SYSTEM)==ApplicationInfo.FLAG_SYSTEM){//过滤掉系统程序 //Log.d("System software","We met System"+i+"th software: "+packageInfo.packageName); continue; } tmpEntity=new AppEntity(); tmpEntity.appName = packageInfo.applicationInfo.loadLabel(getPackageManager()).toString(); tmpEntity.packageName = packageInfo.packageName; tmpEntity.versionName ="版本:"+packageInfo.versionName; tmpEntity.versionCode = packageInfo.versionCode; tmpEntity.appIcon = packageInfo.applicationInfo.loadIcon(getPackageManager()); appList.add(tmpEntity); } return appList; } @Override public boolean onCreateOptionsMenu(Menumenu) { getMenuInflater().inflate(R.menu.menu, menu); return true; } @Override public booleanonOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { //响应每个菜单项(通过菜单项的ID) case R.id.item1: Intentintent = new Intent(); intent.setClass(AUTListActivity.this,InfoActivity.class); startActivity(intent); break; case R.id.item2: Toast.makeText(AUTListActivity.this,"分享至微信", Toast.LENGTH_SHORT).show(); break; default: //对没有处理的事件,交给父类来处理 return super.onOptionsItemSelected(item); } //返回true表示处理完菜单项的事件,不需要将该事件继续传播下去了 return true; }
4.创建悬浮窗,并使其始终显示在前端,不会因为打开其他应用,内存不足而被关闭
工具实现了一个悬浮窗,准实时地显示当前的取样数据,为了保证在操作待测应用的过程中,悬浮窗不会因为内存短缺而被系统回收,所以将悬浮窗的实现挂在一个Service上(而不是Activity),并且将Service设置为前台Service:
绘制悬浮窗:
private void createFloatView() { wmParams = new WindowManager.LayoutParams(); mWindowManager =(WindowManager)getApplication().getSystemService(getApplication().WINDOW_SERVICE); wmParams.type = LayoutParams.TYPE_PHONE; wmParams.format = PixelFormat.RGBA_8888; wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE; wmParams.gravity = Gravity.LEFT | Gravity.TOP; wmParams.x = 300; wmParams.y = 300; wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT; wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT; LayoutInflater inflater =LayoutInflater.from(getApplication()); mFloatLayout =(LinearLayout)inflater.inflate(R.layout.float_layout,null); mWindowManager.addView(mFloatLayout,wmParams); mFloatView = (LinearLayout)mFloatLayout.findViewById(R.id.float_id); btnArrow = (ImageButton)mFloatLayout.findViewById(R.id.btn_float); float_info =(TextView)mFloatLayout.findViewById(R.id.float_info); float_title=(TextView)mFloatLayout.findViewById(R.id.float_title); btnArrow.setOnClickListener(newOnClickListener() { @Override public void onClick(View v) { Intentintent = new Intent(FxService.this, ResultActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//@@@@@@@@@@ startActivity(intent); } }); mFloatLayout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),View.MeasureSpec .makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED)); //设置监听浮动窗口的触摸移动 mFloatView.setOnTouchListener(newOnTouchListener() { @Override public boolean onTouch(View v, MotionEventevent) { wmParams.x = (int) event.getRawX() -mFloatView.getMeasuredWidth()/2; wmParams.y = (int) event.getRawY() -mFloatView.getMeasuredHeight()/2 -25; mWindowManager.updateViewLayout(mFloatLayout,wmParams); returnfalse; //此处必须返回false,否则OnClickListener获取不到监听 } }); }
设置前台Service:
Notification notification = newNotification(R.drawable.ic_launcher,"Honeybadger is working!",System.currentTimeMillis()); notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT; Intent notificationIntent = new Intent(this, ResultActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,notificationIntent, 0); notification.setLatestEventInfo(FxService.this,"Honeybadger is working!","正在测试"+targetPackage,pendingIntent); startForeground(ONGOING_NOTIFICATION, notification);
5.由应用包名获取进程pid
因为进程没有运行时是无法获取到pid的,所以在点击开始测试的按钮后,应该先判断一下待测应用当前是否在运行,如果没有,需要先打开待测应用,并设置一个时间延长让系统初始化相应的目录。
public static boolean isRunning(Contextcontext,String packageName){ ActivityManager am = (ActivityManager)context.getSystemService(ACTIVITY_SERVICE); List<RunningAppProcessInfo> infos= am.getRunningAppProcesses(); for(RunningAppProcessInfo rapi : infos){ if(rapi.processName.equals(packageName)) returntrue; } return false; } public int getPidFromPackagename(String p){ Log.v("查看","进入getPidFromPackagename"); Log.v("查看","待匹配包为"+p.trim()); int pid = -1; if(!isRunning(FxService.this,p)){ //先打开应用 PackageManager packageManager = this.getPackageManager(); Intent intent=new Intent(); try{ intent=packageManager.getLaunchIntentForPackage(p.trim()); //intent=packageManager.getLaunchIntentForPackage("com.tencent.mm"); if(intent ==null){ Log.v("错误","intent为null"); } startActivity(intent); Toast.makeText(FxService.this,"正在打开待测对象,请稍等...", Toast.LENGTH_LONG).show(); Thread.sleep(5000); } catch(Exception ex){ Log.v("错误","未能成功打开待测应用"); ex.printStackTrace(); return pid; } } //再获取id ActivityManager am = (ActivityManager)this.getSystemService(this.ACTIVITY_SERVICE); List<RunningAppProcessInfo> infos =am.getRunningAppProcesses(); Log.v("查看","准备进入匹配循环"); for (RunningAppProcessInfo runningAppProcessInfo : infos) { //Log.v("查看","匹配"+runningAppProcessInfo.processName); if(runningAppProcessInfo.processName.indexOf("android") != -1){ continue; } if(runningAppProcessInfo.processName.equals(p.trim())){ //Log.v("查看","匹配到了包名"+p); pid = runningAppProcessInfo.pid; //Log.v("查看","pid为"+String.valueOf(pid)); break; } } return pid; }
6.定时器的代码片段如下
主要完成两件工作:一是获取采样数据并存入静态ArrayList以便后续导出使用,二是修改悬浮窗上的数据。
Handler handler=null; public Runnable runnable = new Runnable(){ public void run(){ if(FxService.float_info!=null){ try { String tmpStr = ""; if(CPU==true){ float f =psf.pickOne()*100; DecimalFormat fnum = new DecimalFormat("##0.00"); String s=fnum.format(f); DataStall.ratesOfCPU.add(s); tmpStr+="CPU: "+s+" %\n"; } if(PSS==true){ MemoryInfo pidMemoryInfo=am.getProcessMemoryInfo(pids)[0]; int totalPss = pidMemoryInfo.getTotalPss(); DataStall.ratesOfPSS.add(String.valueOf(totalPss)); tmpStr+="PSS: "+String.valueOf(totalPss)+" KB\n"; } if(NET==true){ end_send =TrafficStats.getUidTxBytes(uid); end_recv =TrafficStats.getUidRxBytes(uid); tmpStr+="SEND: "+String.valueOf(end_send-begin_send)+" b\n"; tmpStr+="RECV: "+String.valueOf(end_recv-begin_recv)+" b"; DataStall.ratesOfNET_SEND.add(String.valueOf(end_send-begin_send)); DataStall.ratesOfNET_RECV.add(String.valueOf(end_recv-begin_recv)); } FxService.float_info.setText(tmpStr); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else{ Toast.makeText(FxService.this, "FxService.float_info为空", Toast.LENGTH_SHORT).show(); } } };
参考文献:
android ListView详解:http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html
Android 进程内存、CPU使用查看:http://blog.csdn.net/hgl868/article/details/6793041
Linux平台Cpu使用率的计算:http://www.blogjava.net/fjzag/articles/317773.html
android悬浮窗口的实现:http://blog.csdn.net/stevenhu_223/article/details/8504058
Android新手之旅(9) 自定义的折线图:
http://www.cnblogs.com/jetz/archive/2011/07/24/2115238.html
内存耗用:VSS/RSS/PSS/USS:http://blog.csdn.net/adaptiver/article/details/7084364
What is dirty memory?:http://www.linuxformat.com/forums/viewtopic.php?p=56436
相关文章推荐
- Android进程性能监控工具Honeybadger实现
- erlang性能分析及进程监控工具
- Android性能优化之实现双缓存的图片异步加载工具(LruCache+SoftReference) - 拿来即用
- jstat工具_对Java进程的资源&性能进行监控
- erlang性能分析及进程监控工具
- 腾讯优测优分享 | Android性能测试工具化实现
- android app性能监控工具,同时支持monkey测试
- python实现监控linux性能及进程消耗性能的方法
- 进程管理及性能监控工具:PS/Top/Htop/Dstat
- python实现监控linux性能及进程消耗性能的方法
- Android 性能测试实践(二) 实时监控工具
- Android性能监控小工具
- Android性能测试工具实现介绍
- Android性能测试:CPU内存监控工具APT
- Android性能优化之实现双缓存的图片异步加载工具(LruCache+SoftReference) - 拿来即用
- 腾讯优测优分享 | Android性能测试工具化实现
- Android 性能测试实践(二) 实时监控工具
- Android 性能测试实践(二) 实时监控工具
- Android的性能监控工具StrictMode
- Android性能测试工具实现介绍