Android平台下实现一个进程管理器

54
回复
1105768
查看
  [复制链接]

2826

主题

7684

帖子

9588

安币

管理员

Rank: 9Rank: 9Rank: 9

QQ达人最佳新人活跃会员热心会员推广达人灌水之王突出贡献

QQ
版主推荐 发表于 2011-5-1 09:31:01 | 显示全部楼层 |阅读模式
《枚举Android系统的进程、任务和服务的息》中,实现了一个简单的监控Android平台下的系统进程,任务,服务信息的小工具。在本文中,我将对这个小工具中的系统进程信息部分,进一步的完善。从用户的角度出发,将系统的任务信息Task和服务信息Service全部显示出来的意义不是很大,因此本文将不会对任务和服务两部分内容对任何更新。
  介绍之前,先给大家看看程序执行后的界面,首先了解大致的功能,然后理解起来,会更加得心应手。
1、  获取系统进程列表,并加载进程名、CPU占用情况、内存使用情况


2、  点击某一个进程之后,让用户选择操作:“查看详情”和“结束进程”


3、  显示进程的详细信息:包括了进程的安装包路径、版权信息、用户权限、拥有的服务、和拥有的活动,等
      


4、  程序退出的方式



5、  任务列表 和 服务列表

   
   

  在对界面和主要功能有一个大致了解之后,我们就开始编写我们的代码了。
一、界面布局
  本文对整个功能界面采用了选项卡式的布局,布局文件如下:
main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:id="@android:id/tabhost"
  4.     android:layout_width="fill_parent"
  5.     android:layout_height="fill_parent">
  6.     <LinearLayout android:orientation="vertical"
  7.         android:layout_width="fill_parent"
  8.         android:layout_height="fill_parent"
  9.         android:padding="2dp">
  10.         <TabWidget android:id="@android:id/tabs"
  11.             android:layout_width="fill_parent"
  12.             android:layout_height="wrap_content" />
  13.         <FrameLayout android:id="@android:id/tabcontent"
  14.             android:layout_width="fill_parent"
  15.             android:layout_height="fill_parent"
  16.             android:padding="5dp" />
  17.     </LinearLayout>

  18. </TabHost>
复制代码
 每一个选项卡的内容都是一个列表ListView,分别用于显示系统的进程、任务和服务列表,布局文件我们就此略过了。  在进程的详情中,我们使用不同背景色的TextView作为一个数据部分的标题,这样给人视觉上一个比较清晰的层次感,代码如下:整个详情信息是一个ScrollView,在第一行中嵌入了一个Button,其他行的数据显示都比较简单,大家看看我的控件ID就差不多知道这个控件的意思了。proc_detail.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <ScrollView
  3.     xmlns:android="http://schemas.android.com/apk/res/android"
  4.     android:layout_height="wrap_content"
  5.     android:layout_width="match_parent"
  6.     android:scrollbars="none">
  7.     <LinearLayout
  8.         android:id="@+id/linearlayout1"
  9.         android:layout_width="fill_parent"
  10.         android:layout_height="fill_parent"
  11.         android:orientation="vertical"
  12.         android:paddingLeft="3dip"
  13.         android:paddingRight="3dip"
  14.         android:paddingTop="1dip"
  15.         android:paddingBottom="1dip">
  16.         <RelativeLayout android:layout_width="match_parent"
  17.             android:layout_height="27dip"  
  18.             android:background="#555555"
  19.             android:id="@+id/relativeLayout1">
  20.             <TextView android:textSize="7pt"
  21.                 android:layout_alignParentLeft="true"
  22.                 android:id="@+id/textView1"
  23.                 android:layout_width="wrap_content"
  24.                 android:layout_height="fill_parent"
  25.                 android:gravity="center_vertical"
  26.                 android:text="@string/detail_process_name"></TextView>
  27.             <Button android:id="@+id/btn_kill_process"
  28.                 android:textSize="6pt"
  29.                 android:layout_alignParentRight="true"
  30.                 android:layout_width="wrap_content"
  31.                 android:layout_height="fill_parent"
  32.                 android:paddingTop="0dip"
  33.                 android:paddingBottom="0dip"
  34.                 android:paddingRight="10dip"
  35.                 android:paddingLeft="10dip"
  36.                 android:layout_marginTop="2dip"
  37.                 android:textStyle="bold"
  38.                 android:text="@string/kill_process"
  39.                 android:textColor="#5555EE"></Button>
  40.         </RelativeLayout>
  41.         <TextView
  42.             android:id="@+id/detail_process_name"
  43.             android:layout_height="wrap_content"
  44.             android:layout_width="fill_parent"
  45.             android:paddingTop="3dip"
  46.             android:paddingBottom="3dip" />
  47.             
  48.         <TextView
  49.             android:text="@string/detail_process_copyright"
  50.             android:textSize="7pt"
  51.             android:layout_alignParentLeft="true"
  52.             android:layout_width="fill_parent"
  53.             android:layout_height="25dip"   
  54.             android:gravity="center_vertical"
  55.             android:background="#555555"
  56.             android:paddingTop="3dip"
  57.             android:paddingBottom="3dip" />
  58.         <TextView
  59.             android:id="@+id/detail_process_copyright"
  60.             android:layout_height="wrap_content"
  61.             android:layout_width="fill_parent"
  62.             android:paddingTop="3dip"
  63.             android:paddingBottom="3dip" />
  64.             
  65.         <TextView
  66.             android:text="@string/detail_process_install_dir"
  67.             android:textSize="7pt"
  68.             android:layout_alignParentLeft="true"
  69.             android:layout_width="fill_parent"
  70.             android:layout_height="25dip"   
  71.             android:gravity="center_vertical"
  72.             android:background="#555555"
  73.             android:paddingTop="3dip"
  74.             android:paddingBottom="3dip" />
  75.         <TextView
  76.             android:id="@+id/detail_process_install_dir"
  77.             android:layout_height="wrap_content"
  78.             android:layout_width="fill_parent"
  79.             android:paddingTop="3dip"
  80.             android:paddingBottom="3dip" />
  81.             
  82.         <TextView
  83.             android:text="@string/detail_process_data_dir"
  84.             android:textSize="7pt"
  85.             android:layout_alignParentLeft="true"
  86.             android:layout_width="fill_parent"
  87.             android:layout_height="25dip"   
  88.             android:gravity="center_vertical"
  89.             android:background="#555555"
  90.             android:paddingTop="3dip"
  91.             android:paddingBottom="3dip" />
  92.         <TextView
  93.             android:id="@+id/detail_process_data_dir"
  94.             android:layout_height="wrap_content"
  95.             android:layout_width="fill_parent"
  96.             android:paddingTop="3dip"
  97.             android:paddingBottom="3dip" />
  98.         
  99.         <TextView
  100.             android:text="@string/detail_process_package_size"
  101.             android:textSize="7pt"
  102.             android:layout_alignParentLeft="true"
  103.             android:layout_width="fill_parent"
  104.             android:layout_height="25dip"   
  105.             android:gravity="center_vertical"
  106.             android:background="#555555"
  107.             android:paddingTop="3dip"
  108.             android:paddingBottom="3dip" />
  109.         <TextView
  110.             android:id="@+id/detail_process_package_size"
  111.             android:layout_height="wrap_content"
  112.             android:layout_width="fill_parent"
  113.             android:paddingTop="3dip"
  114.             android:paddingBottom="3dip" />
  115.             
  116.         <TextView
  117.             android:text="@string/detail_process_permission"
  118.             android:textSize="7pt"
  119.             android:layout_alignParentLeft="true"
  120.             android:layout_width="fill_parent"
  121.             android:layout_height="25dip"   
  122.             android:gravity="center_vertical"
  123.             android:background="#555555"
  124.             android:paddingTop="3dip"
  125.             android:paddingBottom="3dip" />
  126.         <TextView
  127.             android:id="@+id/detail_process_permission"
  128.             android:layout_height="wrap_content"
  129.             android:layout_width="fill_parent"
  130.             android:paddingTop="3dip"
  131.             android:paddingBottom="3dip" />
  132.             
  133.         <TextView
  134.             android:text="@string/detail_process_service"
  135.             android:textSize="7pt"
  136.             android:layout_alignParentLeft="true"
  137.             android:layout_width="fill_parent"
  138.             android:layout_height="25dip"   
  139.             android:gravity="center_vertical"
  140.             android:background="#555555"
  141.             android:paddingTop="3dip"
  142.             android:paddingBottom="3dip" />
  143.         <TextView
  144.             android:id="@+id/detail_process_service"
  145.             android:layout_height="wrap_content"
  146.             android:layout_width="fill_parent"
  147.             android:paddingTop="3dip"
  148.             android:paddingBottom="3dip" />
  149.             
  150.         <TextView
  151.             android:text="@string/detail_process_activity"
  152.             android:textSize="7pt"
  153.             android:layout_alignParentLeft="true"
  154.             android:layout_width="fill_parent"
  155.             android:layout_height="25dip"   
  156.             android:gravity="center_vertical"
  157.             android:background="#555555"
  158.             android:paddingTop="3dip"
  159.             android:paddingBottom="3dip" />
  160.         <TextView
  161.             android:id="@+id/detail_process_activity"
  162.             android:layout_height="wrap_content"
  163.             android:layout_width="fill_parent"
  164.             android:paddingTop="3dip"
  165.             android:paddingBottom="3dip" />
  166.     </LinearLayout>
  167. </ScrollView>
复制代码

二、获取进程的图标、进程名、Application名字、和CPU内存信息  我在程序中使用了一个类BasicProgramUtil来存放进程列表中显示的摘要信息,包括了进程图标、进程名、Application名、CPU和内存信息。  BasicProgramUtil.java
  1. /**
  2. * 应用程序包的简要信息
  3. */
  4. package crazypebble.sysassist.procmgr;

  5. import android.graphics.drawable.Drawable;

  6. public class BasicProgramUtil{
  7.    
  8.     /*
  9.      * 定义应用程序的简要信息部分
  10.      */
  11.     private Drawable icon;                            // 程序图标
  12.     private String programName;                        // 程序名称
  13.     private String processName;
  14.    
  15.     private String cpuMemString;
  16.    
  17.     public BasicProgramUtil() {
  18.         icon = null;
  19.         programName = "";   
  20.         processName = "";   
  21.         cpuMemString = "";
  22.     }
  23.    
  24.     public Drawable getIcon() {
  25.         return icon;
  26.     }
  27.    
  28.     public void setIcon(Drawable icon) {
  29.         this.icon = icon;
  30.     }
  31.    
  32.     public String getProgramName() {
  33.         return programName;
  34.     }
  35.    
  36.     public void setProgramName(String programName) {
  37.         this.programName = programName;
  38.     }

  39.     public String getCpuMemString() {
  40.         return cpuMemString;
  41.     }

  42.     public void setCpuMemString(String cpuMemString) {
  43.         this.cpuMemString = cpuMemString;
  44.     }
  45.    
  46.     public String getProcessName() {
  47.         return processName;
  48.     }

  49.     public void setProcessName(String processName) {
  50.         this.processName = processName;
  51.     }
  52. }
复制代码
1、进程图标  每一个进程,都属于一个应用程序,每个应用程序都有一个图标信息。我们通过ApplicationInfo.loadIcon(PackageManager)方法返回一个Drawable对象实例,可以获取到一个应用程序的图标,这里我们直接作为进程的图标进行显示。2、进程名和Application名字
  首先要弄清进程名和Application名字的区别。在Android平台下,一个进程的进程名实际上以“.”作为分隔符的,类似包名的字符串,这个字符串并不能被普通用户所理解。而Application名字,就是我们刚开始新建工程时,填入Application部分的内容,是可以被用户接受的应用程序的名字。
  由于Application Name更容易被用户接受和读懂,因此我们将Application Name作为进程信息的主显部分。   通过ActivityManager.getRunningAppProcesses()方法可以得到当前正在运行的所有进程列表,该方法返回一个List<RunningAppProcessInfo>,在RunningAppProcessInfo对象中存放有进程名信息;再通过进程名获取到ApplicationInfo,通过方法ApplicationInfo.loadLabel(PackageManager).toString()就返回了应用程序的名字。3、CPU和内存信息  获取每个进程的CPU和内存信息,可能就没有API函数给我们使用了。我们需要通过执行adb shell指令,进入shell命令模式,执行命令”top –n 1”来获取所有进程运行状态的列表。Android平台下的很多系统信息可能是无法通过API函数获取到的,这时通过执行shell命令,并解析输出结果。相关链接:《Android的CPU、硬盘、内存、网络设置、系统信息、硬件信息》  先来看看top –n 1(这个地方不是字母L,是数字1,请各位小心)命令执行的结果吧。
第一行:CPU的总的使用情况第二行:总内存的使用情况从第三行开始,就是每个进程所占用内存和CPU的情况PID:进程ID,CPU%:CPU占用比例,#THR:进程的线程数,VSS:虚拟内存,RSS:物理内存,PCY:浮云,我也不知道什么意思,UID:用户ID,Name:进程名  了解了上面这些信息之后,想必大家也知道怎么获取这个进程的CPU和内存信息了。要是大家有兴趣,还是好好看看《Android的CPU、硬盘、内存、网络设置、系统信息、硬件信息》,相信这个文章对大家有有用的。  好了,这一部分的功能就做好了,接下来编码了,这里放出主要的代码,其他的代码,希望同学们自己去完善了。  PackageUtil.java
  1. /**
  2. * PackageUtils 用于某进程的ApplicationInfo对象,目的为了获取图标和应用程序名称
  3. */
  4. package crazypebble.sysassist.procmgr;

  5. import java.util.List;

  6. import android.content.Context;
  7. import android.content.pm.ApplicationInfo;
  8. import android.content.pm.PackageManager;

  9. public class PackageUtil {
  10.     // ApplicationInfo 类,保存了普通应用程序的信息,主要是指Manifest.xml中application标签中的信息
  11.     private List<ApplicationInfo> allAppList;
  12.    
  13.     public PackageUtil(Context context) {
  14.         // 通过包管理器,检索所有的应用程序(包括卸载)与数据目录
  15.         PackageManager pm = context.getApplicationContext().getPackageManager();
  16.         allAppList = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
  17.         pm.getInstalledPackages(0);
  18.     }
  19.    
  20.     /**
  21.      * 通过一个程序名返回该程序的一个ApplicationInfo对象
  22.      * @param name 程序名
  23.      * @return ApplicationInfo
  24.      */
  25.     public ApplicationInfo getApplicationInfo(String appName) {
  26.         if (appName == null) {
  27.             return null;
  28.         }
  29.         
  30.         for (ApplicationInfo appinfo : allAppList) {
  31.             if (appName.equals(appinfo.processName)) {
  32.                 return appinfo;
  33.             }
  34.         }
  35.         return null;
  36.     }
  37. }
复制代码
  ProcessMemoryUtil.java
  1. /**
  2. * 获取某进程的CPU和内存使用情况
  3. */
  4. package crazypebble.sysassist.procmgr;

  5. import java.io.IOException;
  6. import java.util.ArrayList;
  7. import java.util.Iterator;
  8. import java.util.List;

  9. import android.util.Log;
  10. import crazypebble.sysassist.common.CMDExecute;

  11. public class ProcessMemoryUtil {
  12.    
  13.     private static final int INDEX_FIRST = -1;
  14.     private static final int INDEX_PID = INDEX_FIRST + 1;
  15.     private static final int INDEX_CPU = INDEX_FIRST + 2;
  16.     private static final int INDEX_STAT = INDEX_FIRST + 3;
  17.     private static final int INDEX_THR = INDEX_FIRST + 4;
  18.     private static final int INDEX_VSS = INDEX_FIRST + 5;
  19.     private static final int INDEX_RSS = INDEX_FIRST + 6;
  20.     private static final int INDEX_PCY = INDEX_FIRST + 7;
  21.     private static final int INDEX_UID = INDEX_FIRST + 8;
  22.     private static final int INDEX_NAME = INDEX_FIRST + 9;
  23.     private static final int Length_ProcStat = 9;
  24.    
  25.     private List<String[]> PMUList = null;
  26.    
  27.     public ProcessMemoryUtil() {
  28.         
  29.     }
  30.    
  31.     private String getProcessRunningInfo() {
  32.         Log.i("fetch_process_info", "start. . . . ");
  33.         String result = null;
  34.         CMDExecute cmdexe = new CMDExecute();
  35.         try {
  36.             String[] args = {"/system/bin/top", "-n", "1"};
  37.             result = cmdexe.run(args, "/system/bin/");
  38.         } catch (IOException ex) {
  39.             Log.i("fetch_process_info", "ex=" + ex.toString());
  40.         }
  41.         return result;
  42.     }
  43.    
  44.     private int parseProcessRunningInfo(String infoString) {
  45.         String tempString = "";
  46.         boolean bIsProcInfo = false;
  47.         
  48.         String[] rows = null;
  49.         String[] columns = null;
  50.         rows = infoString.split("[\n]+");        // 使用正则表达式分割字符串
  51.         
  52.         for (int i = 0; i < rows.length; i++) {
  53.             tempString = rows[i];
  54.             if (tempString.indexOf("PID") == -1) {
  55.                 if (bIsProcInfo == true) {
  56.                     tempString = tempString.trim();
  57.                     columns = tempString.split("[ ]+");
  58.                     if (columns.length == Length_ProcStat) {
  59.                         PMUList.add(columns);   
  60.                     }
  61.                 }
  62.             } else {
  63.                 bIsProcInfo = true;
  64.             }
  65.         }
  66.         
  67.         return PMUList.size();
  68.     }
  69.    
  70.     // 初始化所有进程的CPU和内存列表,用于检索每个进程的信息
  71.     public void initPMUtil() {
  72.         PMUList = new ArrayList<String[]>();
  73.         String resultString = getProcessRunningInfo();
  74.         parseProcessRunningInfo(resultString);
  75.     }
  76.    
  77.     // 根据进程名获取CPU和内存信息
  78.     public String getMemInfoByName(String procName) {
  79.         String result = "";
  80.         
  81.         String tempString = "";
  82.         for (Iterator<String[]> iterator = PMUList.iterator(); iterator.hasNext();) {
  83.             String[] item = (String[]) iterator.next();
  84.             tempString = item[INDEX_NAME];
  85.             if (tempString != null && tempString.equals(procName)) {
  86.                 result = "CPU:" + item[INDEX_CPU]
  87.                        + "  Mem:" + item[INDEX_RSS];
  88.                 break;
  89.             }
  90.         }
  91.         return result;
  92.     }

  93.     // 根据进程ID获取CPU和内存信息
  94.     public String getMemInfoByPid(int pid) {
  95.         String result = "";
  96.         
  97.         String tempPidString = "";
  98.         int tempPid = 0;
  99.         int count = PMUList.size();
  100.         for (int i = 0; i < count; i++) {
  101.             String[] item = PMUList.get(i);
  102.             tempPidString = item[INDEX_PID];
  103.             if (tempPidString == null) {
  104.                 continue;
  105.             }
  106.             tempPid = Integer.parseInt(tempPidString);
  107.             if (tempPid == pid) {
  108.                 result = "CPU:" + item[INDEX_CPU]
  109.                        + "  Mem:" + item[INDEX_RSS];
  110.                 break;
  111.             }
  112.         }
  113.         return result;
  114.     }
  115. }
复制代码

  buildProgramUtilSimpleInfo()
  1. /*
  2.      * 为进程获取基本的信息
  3.      */
  4.     public BasicProgramUtil buildProgramUtilSimpleInfo(int procId, String procNameString) {

  5.         BasicProgramUtil programUtil = new BasicProgramUtil();
  6.         programUtil.setProcessName(procNameString);
  7.         
  8.         // 根据进程名,获取应用程序的ApplicationInfo对象
  9.         ApplicationInfo tempAppInfo = packageUtil.getApplicationInfo(procNameString);

  10.         if (tempAppInfo != null) {
  11.             // 为进程加载图标和程序名称
  12.             programUtil.setIcon(tempAppInfo.loadIcon(packageManager));
  13.             programUtil.setProgramName(tempAppInfo.loadLabel(packageManager).toString());
  14.         }
  15.         else {
  16.             // 如果获取失败,则使用默认的图标和程序名
  17.             programUtil.setIcon(getApplicationContext().getResources().getDrawable(R.drawable.unknown));
  18.             programUtil.setProgramName(procNameString);
  19.             Log.v(ProcMgrActivity.TAG_SYSTEMASSIST, procNameString);
  20.         }
  21.         
  22.         String str = processMemoryUtil.getMemInfoByPid(procId);
  23.         Log.v(TAG_SYSTEMASSIST, "Time --- > " + Calendar.getInstance().getTimeInMillis());
  24.         programUtil.setCpuMemString(str);
  25.         return programUtil;
  26.     }
复制代码

三、获取进程的详细信息  我将进程的详细信息封装在一个类DetailProgramUtil中,主要包括了进程ID,进程名,版权信息、程序的安装目录和数据目录,安装时间和更新时间、应用程序的权限、应用程序包含的活动Activity、应用程序包含的服务Service、和安装包的大小信息。  DetailProgramUtil.java
  1. /**
  2. * 应用程序包的详细信息
  3. */
  4. package crazypebble.sysassist.procmgr;

  5. import java.io.Serializable;
  6. import java.text.DecimalFormat;

  7. import android.content.pm.ActivityInfo;
  8. import android.content.pm.ServiceInfo;
  9. import android.text.format.DateFormat;

  10. public class DetailProgramUtil implements Serializable{

  11.     private static final long serialVersionUID = 1L;
  12.     /*
  13.      * 定义应用程序的扩展信息部分
  14.      */
  15.     private int pid;
  16.     private String processName;                        // 程序运行的进程名
  17.    
  18.     private String companyName;                        // 公司名称
  19.     private int versionCode;                        // 版本代号
  20.     private String versionName;                        // 版本名称
  21.    
  22.     private String dataDir;                            // 程序的数据目录
  23.     private String sourceDir;                        // 程序包的源目录
  24.    
  25.     private String firstInstallTime;                // 第一次安装的时间
  26.     private String lastUpdateTime;                    // 最近的更新时间
  27.    
  28.     private String userPermissions;                    // 应用程序的权限
  29.     private String activities;                        // 应用程序包含的Activities
  30.     private String services;                        // 应用程序包含的服务
  31.    
  32.     // android.content.pm.PackageState类的包信息
  33.     // 此处只是安装包的信息
  34.     private String codeSize;
  35.     private long dataSize;
  36.     private long cacheSize;
  37.     private long externalDataSize;
  38.     private long externalCacheSize;
  39.     private long externalMediaSize;
  40.     private long externalObbSize;

  41.     public DetailProgramUtil() {
  42.         pid = 0;
  43.         processName = "";
  44.         companyName = "";
  45.         versionCode = 0;
  46.         versionName = "";
  47.         dataDir = "";
  48.         sourceDir = "";
  49.         firstInstallTime = "";
  50.         lastUpdateTime = "";
  51.         userPermissions = "";
  52.         activities = "";
  53.         services = "";
  54.         
  55.         initPackageSize();
  56.     }
  57.    
  58.     private void initPackageSize() {
  59.         codeSize = "0.00";
  60.         dataSize = 0;
  61.         cacheSize = 0;
  62.         externalCacheSize = 0;
  63.         externalDataSize = 0;
  64.         externalMediaSize = 0;
  65.         externalObbSize = 0;
  66.     }
  67.    
  68.     public int getPid() {
  69.         return pid;
  70.     }
  71.    
  72.     public void setPid(int pid) {
  73.         this.pid = pid;
  74.     }
  75.    
  76.     public int getVersionCode() {
  77.         return versionCode;
  78.     }

  79.     public void setVersionCode(int versionCode) {
  80.         this.versionCode = versionCode;
  81.     }

  82.     public String getVersionName() {
  83.         return versionName;
  84.     }

  85.     public void setVersionName(String versionName) {
  86.         this.versionName = versionName;
  87.     }

  88.     public String getCompanyName() {
  89.         return companyName;
  90.     }

  91.     public void setCompanyName(String companyString) {
  92.         this.companyName = companyString;
  93.     }
  94.    
  95.     public String getFirstInstallTime() {
  96.         if (firstInstallTime == null || firstInstallTime.length() <= 0) {
  97.             firstInstallTime = "null";
  98.         }
  99.         return firstInstallTime;
  100.     }

  101.     public void setFirstInstallTime(long firstInstallTime) {
  102.         this.firstInstallTime = DateFormat.format(
  103.                 "yyyy-MM-dd", firstInstallTime).toString();
  104.     }

  105.     public String getLastUpdateTime() {
  106.         if (lastUpdateTime == null || lastUpdateTime.length() <= 0) {
  107.             lastUpdateTime = "null";
  108.         }
  109.         return lastUpdateTime;
  110.     }

  111.     public void setLastUpdateTime(long lastUpdateTime) {
  112.         this.lastUpdateTime = DateFormat.format(
  113.                 "yyyy-MM-dd", lastUpdateTime).toString();
  114.     }

  115.     public String getActivities() {
  116.         if (activities == null || activities.length() <= 0) {
  117.             activities = "null";
  118.         }
  119.         return activities;
  120.     }

  121.     public void setActivities(ActivityInfo[] activities) {
  122.         this.activities = Array2String(activities);
  123.     }

  124.     public String getUserPermissions() {
  125.         if (userPermissions == null || userPermissions.length() <= 0) {
  126.             userPermissions = "null";
  127.         }
  128.         return userPermissions;
  129.     }

  130.     public void setUserPermissions(String[] userPermissions) {
  131.         this.userPermissions = Array2String(userPermissions);   
  132.     }

  133.     public String getServices() {
  134.         if (services == null || services.length() <= 0) {
  135.             services = "null";
  136.         }
  137.         return services;
  138.     }

  139.     public void setServices(ServiceInfo[] services) {
  140.         this.services = Array2String(services);
  141.     }

  142.     public String getProcessName() {
  143.         if (processName == null || processName.length() <= 0) {
  144.             processName = "null";
  145.         }
  146.         return processName;
  147.     }

  148.     public void setProcessName(String processName) {
  149.         this.processName = processName;
  150.     }

  151.     public String getDataDir() {
  152.         if (dataDir == null || dataDir.length() <= 0) {
  153.             dataDir = "null";
  154.         }
  155.         return dataDir;
  156.     }

  157.     public void setDataDir(String dataDir) {
  158.         this.dataDir = dataDir;
  159.     }

  160.     public String getSourceDir() {
  161.         if (sourceDir == null || sourceDir.length() <= 0) {
  162.             sourceDir = "null";
  163.         }
  164.         return sourceDir;
  165.     }

  166.     public void setSourceDir(String sourceDir) {
  167.         this.sourceDir = sourceDir;
  168.     }
  169.    
  170.     /*
  171.      * 三个重载方法,参数不同,调用不同的方法,用于将object数组转化成要求的字符串
  172.      */
  173.     // 用户权限信息
  174.     public String Array2String(String[] array) {
  175.         
  176.         String resultString = "";
  177.         if (array != null && array.length > 0) {
  178.             resultString = "";
  179.             for (int i = 0; i < array.length; i++) {
  180.                 resultString += array[i];
  181.                 if (i < (array.length - 1)) {
  182.                     resultString += "\n";
  183.                 }
  184.             }
  185.         }
  186.         return resultString;
  187.     }
  188.    
  189.     // 服务信息
  190.     public String Array2String(ServiceInfo[] array) {
  191.         String resultString = "";
  192.         if (array != null && array.length > 0) {
  193.             resultString = "";
  194.             for (int i = 0; i < array.length; i++) {
  195.                 if (array[i].name == null) {
  196.                     continue;
  197.                 }
  198.                 resultString += array[i].name.toString();
  199.                 if (i < (array.length - 1)) {
  200.                     resultString += "\n";
  201.                 }
  202.             }
  203.         }
  204.         return resultString;
  205.     }
  206.    
  207.     // 活动信息
  208.     public String Array2String(ActivityInfo[] array) {
  209.         String resultString = "";
  210.         if (array != null && array.length > 0) {
  211.             resultString = "";
  212.             for (int i = 0; i < array.length; i++) {
  213.                 if (array[i].name == null) {
  214.                     continue;
  215.                 }
  216.                 resultString += array[i].name.toString();
  217.                 if (i < (array.length - 1)) {
  218.                     resultString += "\n";
  219.                 }
  220.             }
  221.         }
  222.         return resultString;
  223.     }

  224.     public String getCodeSize() {
  225.         return codeSize;
  226.     }
  227.    
  228.     public void setCodeSize(long codeSize) {
  229.         DecimalFormat df = new DecimalFormat("###.00");  
  230.         this.codeSize = df.format((double)(codeSize/1024.0));
  231.     }

  232.     public long getDataSize() {
  233.         return dataSize;
  234.     }

  235.     public void setDataSize(long dataSize) {
  236.         this.dataSize = dataSize;
  237.     }

  238.     public long getCacheSize() {
  239.         return cacheSize;
  240.     }

  241.     public void setCacheSize(long cacheSize) {
  242.         this.cacheSize = cacheSize;
  243.     }

  244.     public long getExternalDataSize() {
  245.         return externalDataSize;
  246.     }

  247.     public void setExternalDataSize(long externalDataSize) {
  248.         this.externalDataSize = externalDataSize;
  249.     }

  250.     public long getExternalCacheSize() {
  251.         return externalCacheSize;
  252.     }

  253.     public void setExternalCacheSize(long externalCacheSize) {
  254.         this.externalCacheSize = externalCacheSize;
  255.     }

  256.     public long getExternalMediaSize() {
  257.         return externalMediaSize;
  258.     }

  259.     public void setExternalMediaSize(long externalMediaSize) {
  260.         this.externalMediaSize = externalMediaSize;
  261.     }

  262.     public long getExternalObbSize() {
  263.         return externalObbSize;
  264.     }

  265.     public void setExternalObbSize(long externalObbSize) {
  266.         this.externalObbSize = externalObbSize;
  267.     }
  268.    
  269.     public String getPackageSize() {
  270.         String resultString = "";
  271.         resultString = "Code Size: " + codeSize + "KB\n"
  272.                      + "Data Size: " + dataSize + "KB\n"
  273.                      + "Cache Size: " + cacheSize + "KB\n"
  274.                      + "External Data Size: " + externalDataSize + "KB\n"
  275.                      + "External Cache Size: " + externalCacheSize + "KB\n"
  276.                      + "External Media Size: " + externalMediaSize + "KB\n"
  277.                      + "External Obb Size: " + externalObbSize + "KB";
  278.         return resultString;
  279.     }
  280. }
复制代码

目录信息:通过进程的ApplicationInfo对象获取,获取进程ApplicationInfo的方法在类PackageUtil.java中。     版权信息、权限、活动、服务信息:通过PackageInfo对象获取,获取进程PackageInfo的方法:PackageManager.getPackageInfo(packageName, flags)。这个方法需要一定flags信息,我在代码中已经用注释写明了所需要的flags,请各位还是查阅一下SDK的开发文档,里面会有更详细的解释。   方法buildProgramUtilComplexInfo用于为需要查看详情的进程生成一个DetailProgramUtil对象,通过Bundle.putSerializable(key, (Serializable)DetaiProgramUtil),将这个对象传递给另一个活动进行显示。所以在上面DetailProgramUtil.java文件的一开始,该类实现了Serializable的接口。  buildProgramUtilComplexInfo()
  1. /*
  2.      * 为进程获取安装包的详情
  3.      */
  4.     public DetailProgramUtil buildProgramUtilComplexInfo(String procNameString) {

  5.         DetailProgramUtil complexProgramUtil = new DetailProgramUtil();
  6.         // 根据进程名,获取应用程序的ApplicationInfo对象
  7.         ApplicationInfo tempAppInfo = packageUtil.getApplicationInfo(procNameString);
  8.         if (tempAppInfo == null) {
  9.             return null;
  10.         }
  11.         
  12.         PackageInfo tempPkgInfo = null;
  13.         try {
  14.             tempPkgInfo = packageManager.getPackageInfo(
  15.                     tempAppInfo.packageName,
  16.                     PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_ACTIVITIES
  17.                     | PackageManager.GET_SERVICES | PackageManager.GET_PERMISSIONS);
  18.         } catch (NameNotFoundException e) {
  19.             e.printStackTrace();
  20.         }
  21.         if (tempPkgInfo == null) {
  22.             return null;
  23.         }
  24.         
  25.         complexProgramUtil.setProcessName(procNameString);
  26.         complexProgramUtil.setCompanyName(getString(R.string.no_use));
  27.         complexProgramUtil.setVersionName(tempPkgInfo.versionName);
  28.         complexProgramUtil.setVersionCode(tempPkgInfo.versionCode);
  29.         complexProgramUtil.setDataDir(tempAppInfo.dataDir);
  30.         complexProgramUtil.setSourceDir(tempAppInfo.sourceDir);
  31.         
  32.         // 以下注释部分的信息暂时获取不到
  33. //        complexProgramUtil.setFirstInstallTime(tempPkgInfo.firstInstallTime);
  34. //        complexProgramUtil.setLastUpdateTime(tempPkgInfo.lastUpdateTime);
  35.         
  36. //        complexProgramUtil.setCodeSize(packageStats.codeSize);
  37. //        complexProgramUtil.setDataSize(packageStats.dataSize);
  38. //        complexProgramUtil.setCacheSize(packageStats.cacheSize);
  39. //        complexProgramUtil.setExternalDataSize(0);
  40. //        complexProgramUtil.setExternalCacheSize(0);
  41. //        complexProgramUtil.setExternalMediaSize(0);
  42. //        complexProgramUtil.setExternalObbSize(0);
  43.         
  44.         // 获取以下三个信息,需要为PackageManager进行授权(packageManager.getPackageInfo()方法)
  45.         complexProgramUtil.setUserPermissions(tempPkgInfo.requestedPermissions);
  46.         complexProgramUtil.setServices(tempPkgInfo.services);
  47.         complexProgramUtil.setActivities(tempPkgInfo.activities);
  48.         
  49.         return complexProgramUtil;
  50.     }
复制代码
四、实现进程列表的刷新
  进程列表的刷新是一个比较费时的操作,我们将其放在一个独立的线程中执行,并且在刷新过程进行时使用一个ProgressDialog进度对话框覆盖住主视图,等待刷新完成后再返回到主视图。
  这一部分使用到了Handler类和线程的相关知识,各位可以参考文章《在Android中使用Handler和Thread线程执行后台操作》。这些不做过多解释,直接上代码,相信大家都能够懂的。

  refreshProcessList
  1. private void updateProcessList() {
  2.         // 新建一个进度对话框,在更新列表时,覆盖在父视图之上        
  3.         pd = new ProgressDialog(ProcMgrActivity.this);
  4.         pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
  5.         pd.setTitle(getString(R.string.progress_tips_title));
  6.         pd.setMessage(getString(R.string.progress_tips_content));
  7.         
  8.         // 启动新线程,执行更新列表操作
  9.         handler = new RefreshHandler();
  10.         RefreshThread thread = new RefreshThread();
  11.         thread.start();
  12.         
  13.         // 显示进度对话框
  14.         pd.show();
  15.     }
  16.    
  17.     private class RefreshHandler extends Handler {
  18.         @Override
  19.         public void handleMessage(Message msg) {
  20.             // TODO : Update your UI
  21.             getListView().setAdapter(procListAdapter);
  22.             // 取消进度框
  23.             pd.dismiss();
  24.         }
  25.     }
  26.    
  27.     class RefreshThread extends Thread {
  28.         @Override
  29.         public void run() {
  30.             // TODO : Do your Stuff here.
  31.             procListAdapter = buildProcListAdapter();
  32.             Message msg = handler.obtainMessage();
  33.             handler.sendMessage(msg);
  34.         }
  35.     }
复制代码
五、结束其他进程和退出本程序
  这一部分的内容,也已经在我的博客中写了一篇文章《Android下结束进程的方法》,我们在这个任务管理器中使用到的“退出”按钮的实现,强制结束其他进程的方法,都是来自这篇文章。为了方便那些不想点击链接的同学们,我们还是再贴一下代码吧。
  退出本程序,主要是通过方法returnToHome方法,该方法将直接退出到主屏幕,请清除当前的活动:
  returnToHome
  1.   private void returnToHome() {
  2.         Intent home = new Intent(Intent.ACTION_MAIN);
  3.         home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
  4.         home.addCategory(Intent.CATEGORY_HOME);
  5.         startActivity(home);
  6.     }
复制代码

结束其他进程,主要是通过ActivityManager.killBackgroundProcesses(PackageName)方法来实现,还是强烈建议各位看看SDK的开发文档,或者上面的那篇文章。六、任务列表和服务列表
  任务列表和服务列表的信息获取,已经在之前的一篇博客中讲到了,这些再不厌其烦的介绍一下方法,至于原理部分,请各位去看看开发文档吧。

1、任务列表

  任务列表功能所显示的全部信息都来自一个类RunningTaskInfo。
  ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
  taskList = activityManager.getRunningTasks(maxTaskNum);

2、服务列表
  服务列表功能所显示的全部信息都来自一个类RunningServiceInfo。
  ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
  serviceList = activityManager.getRunningServices(maxServiceNum);

       好了,这个任务管理到这里就告一段落了。这个程序算是本人自学习Android开发以来的处女作,完全是自己动手开发的一个小工具,写下总结,以留作纪念,也希望可以与更多的同道中人交流技术。





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

0

主题

15

帖子

1

安币

初级码农

Rank: 1

发表于 2011-6-10 11:38:43 | 显示全部楼层
强!!!  学习了

0

主题

33

帖子

136

安币

程序猿

Rank: 2

发表于 2011-7-7 10:30:49 | 显示全部楼层
学习中,谢谢了

0

主题

69

帖子

119

安币

程序猿

..

Rank: 2

QQ达人

QQ
发表于 2011-7-7 16:52:04 | 显示全部楼层
学习是永无止境滴...:(:)
..

0

主题

0

帖子

2

安币

初级码农

Rank: 1

发表于 2011-7-17 09:56:59 | 显示全部楼层
正在学习中

0

主题

13

帖子

16

安币

初级码农

Rank: 1

发表于 2011-10-1 20:50:44 | 显示全部楼层
很希望楼主提供源码,这样学习起来就更加好了

26

主题

103

帖子

513

安币

代码手工艺人

Rank: 4

发表于 2011-10-7 10:58:50 | 显示全部楼层
不错不错 管理员出手 必是精品

0

主题

220

帖子

1762

安币

Android大神

Rank: 6Rank: 6

发表于 2011-10-9 18:16:53 | 显示全部楼层

强!!!  学习了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )