Android之——获取进程总数、内存、任务列表

来源:互联网 发布:手机淘宝开店要不要钱 编辑:程序博客网 时间:2024/06/05 09:08
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47263863

如今,基于Android平台的应用越来越多,不乏这样一些应用程序,这些应用可以对手机中的进程,内存和任务列表进行管理。Android系统中没有自带的应用程序对这些数据进行管理。大家不禁会说,Android的应用设置里面有这些功能啊!是的,虽然应用设置里面有,但是我们如果想看一下系统的进程,还要跑到系统设置里面去看吗?这样是不是很麻烦?是不是很挫呢?那获取Android系统的进程总数、内存、任务列表是怎样实现的呢?亲们,别着急,下面我们就一起来实现这些功能吧!注意看哦,不要偷懒!

一、原理

首先,我们还是要来说说这些所谓的原理级别的东东吧,不然说了半天,大家可能也是一知半解的。

任务尽可能长时间的保存一个应用。内存出现不足的时候,就会去由操作系统杀死进程:
进程的重要级别:
1 Foreground process 前台进程
  1.1 activity  onResume()
  1.2 一个前台进程的activity绑定了另外一个进程的service
  1.3 service里面调用startForeground
  1.4 service onCreate()  onStart()  onDestory()
  1.5 BroadcastReceiver  onReceive()
2 Visible process 可视进程
  2.1  activity  onPause()
  2.2  一个可视的activity绑定了另一进程的服务
3 Service process 服务进程  
  后台的服务   播放器  下载  复制文件 
4 Background process 后台进程
  任务栈里面还有activity实例的引用,但是该应用在后台
5 Empty process 空进程
1 如果是去获取系统里面安装的信息,这个信息不是动态变化的  PackageManager 

2 如果该信息是变化的   ActivityManager  任务管理器

在这个示例中,我们会通过List将获取到的任务进程列表显示到UI上。

好了,原理啰嗦完了,这里的原理我不同于以往的写法,而是将重要的知识点列出来了,亲们,是不是很简单?看完原理,咱们一起实现这些功能吧。

二、实现

1、数据格式化类TextFormat

考虑到我们获取内存大小,和每个任务进程占用的内存大小时,会出现数据单位不统一的情况,这时,我们自己定义一个数据格式化类,来帮助我们实现数据单位的格式化。

具体代码如下:

package cn.lyz.mobilesafe.utils;import java.text.DecimalFormat;/** * 文本格式化工具类 * @author liuyazhuang * */public class TextFormat {/** * 格式化数据 * @param data * @return */public static String formatByte(long data){DecimalFormat format = new DecimalFormat("##.##");if(data < 1024){return data+"bytes";}else if(data < 1024 * 1024){return format.format(data/1024f) +"KB";}else if(data < 1024 * 1024 * 1024){return format.format(data/1024f/1024f) +"MB";}else if(data < 1024 * 1024 * 1024 * 1024){return format.format(data/1024f/1024f/1024f) +"GB";}else{return "超出统计范围";}}}

2、任务信息实体类TaskInfo

在我们这个任务列表中会显示的内容有图标、名称、每个应用占用的内存、包名、进程id等信息,为了使程序更加面向对象化,也更加体现面向对象的封装性,我将这些信息封装为一个java实体类。

具体实现代码如下:

package cn.lyz.mobilesafe.domain;import android.graphics.drawable.Drawable;/** * 任务信息 * @author liuyazhuang * */public class TaskInfo {//图标private Drawable task_icon;//名称private String task_name;//占用的内存private long task_memory;//包名private String packageName;//进程idprivate int pid;public TaskInfo() {super();// TODO Auto-generated constructor stub}public TaskInfo(Drawable task_icon, String task_name, long task_memory,String packageName, int pid) {super();this.task_icon = task_icon;this.task_name = task_name;this.task_memory = task_memory;this.packageName = packageName;this.pid = pid;}public Drawable getTask_icon() {return task_icon;}public void setTask_icon(Drawable task_icon) {this.task_icon = task_icon;}public String getTask_name() {return task_name;}public void setTask_name(String task_name) {this.task_name = task_name;}public long getTask_memory() {return task_memory;}public void setTask_memory(long task_memory) {this.task_memory = task_memory;}public String getPackageName() {return packageName;}public void setPackageName(String packageName) {this.packageName = packageName;}public int getPid() {return pid;}public void setPid(int pid) {this.pid = pid;}@Overridepublic String toString() {return "TaskInfo [task_icon=" + task_icon + ", task_name=" + task_name+ ", task_memory=" + task_memory + ", packageName="+ packageName + ", pid=" + pid + "]";}}

3、获取进程与内存信息的工具类TaskUtils

我把获取进程与内存信息的方法全部封装在了TaskUtils类中。

具体实现代码如下:

package cn.lyz.mobilesafe.utils;import java.util.ArrayList;import java.util.List;import android.app.ActivityManager;import android.app.ActivityManager.MemoryInfo;import android.app.ActivityManager.RunningAppProcessInfo;import android.content.Context;import android.content.pm.ApplicationInfo;import android.content.pm.PackageManager;import android.content.pm.PackageManager.NameNotFoundException;import android.graphics.drawable.Drawable;import cn.lyz.mobilesafe.R;import cn.lyz.mobilesafe.domain.TaskInfo;/** * 任务相关工具类 * @author liuyazhuang * */public class TaskUtils {/** * 获取当前正在进行的进程数 * @param context * @return */public static int getRunningAppProcessInfoSize(Context context){ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);return am.getRunningAppProcesses().size();}/** * 获取系统可用内存 * @param context * @return */public static long getAvailMem(Context context){ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);//得到可用内存MemoryInfo outInfo = new MemoryInfo();am.getMemoryInfo(outInfo);long availMem = outInfo.availMem; //单位是bytereturn availMem;}/** * 获取系统所有的进程信息列表 * @param context * @return */public static List<TaskInfo> getTaskInfos(Context context){List<TaskInfo> taskInfos  = new ArrayList<TaskInfo>();PackageManager pm = context.getPackageManager();ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();for(RunningAppProcessInfo info : runningAppProcesses){TaskInfo taskInfo = new TaskInfo();//进程名称String packageName = info.processName;taskInfo.setPackageName(packageName);try {ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName, 0);//图标Drawable task_icon = applicationInfo.loadIcon(pm);if(task_icon == null){taskInfo.setTask_icon(context.getResources().getDrawable(R.drawable.ic_launcher));}else{taskInfo.setTask_icon(task_icon);}//名称String task_name = applicationInfo.loadLabel(pm).toString();taskInfo.setTask_name(task_name);} catch (NameNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}//进程idint pid = info.pid;taskInfo.setPid(pid);//获取进程占用的内存android.os.Debug.MemoryInfo[] processMemoryInfo = am.getProcessMemoryInfo(new int[]{pid});android.os.Debug.MemoryInfo memoryInfo  = processMemoryInfo[0];long totalPrivateDirty = memoryInfo.getTotalPrivateDirty(); //KBtaskInfo.setTask_memory(totalPrivateDirty);taskInfos.add(taskInfo);}return taskInfos;}}

4、程序显示界面TaskManagerActivity

这个类中的内容比较多,我们分解来看吧。

1)属性字段

以下代码是我们这个类中,所有的属性字段

protected static final int SUCCESS_GETTASKINFO = 0;private TextView tv_task_manager_task_count;private TextView tv_task_manager_task_memory;private ListView lv_taskmanage;private RelativeLayout rl_loading;private ProgressBar pb;private List<TaskInfo> taskInfos;private TaskManagerAdapter mAdapter;

2)自定义适配器类TaskManagerAdapter

我在TaskManagerActivity类中,自定义了ListView的适配器。这里我用到了ListView的优化策略,使用了ViewHolder来优化ListView。有关ListView优化的策略,大家可以参考《Android之——ListView优化》一文。

具体代码如下:

/** * 自定义适配器 * @author liuyazhuang * */private class TaskManagerAdapter extends BaseAdapter{private LayoutInflater mInflater;public TaskManagerAdapter(){mInflater = getLayoutInflater();}@Overridepublic int getCount() {return taskInfos.size();}@Overridepublic Object getItem(int position) {return taskInfos.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view = null;ViewHolder holder = null;if(convertView != null){view = convertView;holder = (ViewHolder) view.getTag();}else{view = mInflater.inflate(R.layout.task_manager_item, null);holder = new ViewHolder();holder.iv_task_manager_icon = (ImageView) view.findViewById(R.id.iv_task_manager_icon);holder.iv_task_manager_name = (TextView) view.findViewById(R.id.tv_task_manager_name);holder.iv_task_manager_memory = (TextView) view.findViewById(R.id.tv_task_manager_memory);view.setTag(holder);}TaskInfo taskInfo = taskInfos.get(position);holder.iv_task_manager_icon.setImageDrawable(taskInfo.getTask_icon());holder.iv_task_manager_memory.setText("占用的内存:"+TextFormat.formatByte(taskInfo.getTask_memory()*1024));holder.iv_task_manager_name.setText(taskInfo.getTask_name());return view;}}static class ViewHolder{ImageView iv_task_manager_icon;TextView iv_task_manager_name;TextView iv_task_manager_memory;}

3)onCreate方法

这个方法主要实现的是,UI控件的初始化,由于或许进程列表是一个耗时的操作,所以我将它放在一个线程中,获取到进程信息后通过Handler将信息传递到UI线程显示数据。

具体实现代码如下:

@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.task_manager);tv_task_manager_task_count  = (TextView) findViewById(R.id.tv_task_manager_task_count);tv_task_manager_task_memory = (TextView) findViewById(R.id.tv_task_manager_task_memory);lv_taskmanage = (ListView) findViewById(R.id.lv_taskmanage);rl_loading = (RelativeLayout) findViewById(R.id.rl_loading);pb = (ProgressBar) findViewById(R.id.pb);//获取ActivityManager系统服务int size = TaskUtils.getRunningAppProcessInfoSize(this);tv_task_manager_task_count.setText("进程数:"+size);new Thread(new Runnable() {@Overridepublic void run() {taskInfos = TaskUtils.getTaskInfos(getApplicationContext());Message msg = new Message();msg.what = SUCCESS_GETTASKINFO;mHandler.sendMessage(msg);}}).start();}

4)Handler

用于接收子线程传递过来的数据。

具体代码实现如下:

private Handler mHandler = new Handler(){public void handleMessage(android.os.Message msg) {switch (msg.what) {case SUCCESS_GETTASKINFO:long total = TaskUtils.getAvailMem(TaskManagerActivity.this);for(TaskInfo info : taskInfos){total += info.getTask_memory() * 1024;}//可用内存String availMemStr = TextFormat.formatByte(TaskUtils.getAvailMem(TaskManagerActivity.this));//总内存String totalMemStr = TextFormat.formatByte(total);tv_task_manager_task_memory.setText("可用/总内存:"+availMemStr+"/"+totalMemStr);mAdapter = new TaskManagerAdapter();rl_loading.setVisibility(View.GONE);lv_taskmanage.setAdapter(mAdapter);break;default:break;}};};

5)整体代码如下

package cn.lyz.mobilesafe.activity;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.RelativeLayout;import android.widget.TextView;import cn.lyz.mobilesafe.R;import cn.lyz.mobilesafe.domain.TaskInfo;import cn.lyz.mobilesafe.utils.TaskUtils;import cn.lyz.mobilesafe.utils.TextFormat;/** * 任务管理 * @author liuyazhuang * */public class TaskManagerActivity extends Activity {protected static final int SUCCESS_GETTASKINFO = 0;private TextView tv_task_manager_task_count;private TextView tv_task_manager_task_memory;private ListView lv_taskmanage;private RelativeLayout rl_loading;private ProgressBar pb;private List<TaskInfo> taskInfos;private TaskManagerAdapter mAdapter;private Handler mHandler = new Handler(){public void handleMessage(android.os.Message msg) {switch (msg.what) {case SUCCESS_GETTASKINFO:long total = TaskUtils.getAvailMem(TaskManagerActivity.this);for(TaskInfo info : taskInfos){total += info.getTask_memory() * 1024;}//可用内存String availMemStr = TextFormat.formatByte(TaskUtils.getAvailMem(TaskManagerActivity.this));//总内存String totalMemStr = TextFormat.formatByte(total);tv_task_manager_task_memory.setText("可用/总内存:"+availMemStr+"/"+totalMemStr);mAdapter = new TaskManagerAdapter();rl_loading.setVisibility(View.GONE);lv_taskmanage.setAdapter(mAdapter);break;default:break;}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.task_manager);tv_task_manager_task_count  = (TextView) findViewById(R.id.tv_task_manager_task_count);tv_task_manager_task_memory = (TextView) findViewById(R.id.tv_task_manager_task_memory);lv_taskmanage = (ListView) findViewById(R.id.lv_taskmanage);rl_loading = (RelativeLayout) findViewById(R.id.rl_loading);pb = (ProgressBar) findViewById(R.id.pb);//获取ActivityManager系统服务int size = TaskUtils.getRunningAppProcessInfoSize(this);tv_task_manager_task_count.setText("进程数:"+size);new Thread(new Runnable() {@Overridepublic void run() {taskInfos = TaskUtils.getTaskInfos(getApplicationContext());Message msg = new Message();msg.what = SUCCESS_GETTASKINFO;mHandler.sendMessage(msg);}}).start();}/** * 自定义适配器 * @author liuyazhuang * */private class TaskManagerAdapter extends BaseAdapter{private LayoutInflater mInflater;public TaskManagerAdapter(){mInflater = getLayoutInflater();}@Overridepublic int getCount() {return taskInfos.size();}@Overridepublic Object getItem(int position) {return taskInfos.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view = null;ViewHolder holder = null;if(convertView != null){view = convertView;holder = (ViewHolder) view.getTag();}else{view = mInflater.inflate(R.layout.task_manager_item, null);holder = new ViewHolder();holder.iv_task_manager_icon = (ImageView) view.findViewById(R.id.iv_task_manager_icon);holder.iv_task_manager_name = (TextView) view.findViewById(R.id.tv_task_manager_name);holder.iv_task_manager_memory = (TextView) view.findViewById(R.id.tv_task_manager_memory);view.setTag(holder);}TaskInfo taskInfo = taskInfos.get(position);holder.iv_task_manager_icon.setImageDrawable(taskInfo.getTask_icon());holder.iv_task_manager_memory.setText("占用的内存:"+TextFormat.formatByte(taskInfo.getTask_memory()*1024));holder.iv_task_manager_name.setText(taskInfo.getTask_name());return view;}}static class ViewHolder{ImageView iv_task_manager_icon;TextView iv_task_manager_name;TextView iv_task_manager_memory;}}

5、页面布局

具体代码如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <TextView        style="@style/text_title_style"        android:text="任 务 管 理" />    <View style="@style/view_divide_line_style" />    <RelativeLayout         android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="5dip">                <TextView             android:id="@+id/tv_task_manager_task_count"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="进程数:20"/>                <TextView             android:id="@+id/tv_task_manager_task_memory"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:text="可用/总内存:50MB/700MB"/>    </RelativeLayout>    <FrameLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent" >        <!--       android:cacheColorHint="#00000000" 缓存的颜色  默认是黄色       android:divider="#00ffffff" 分割线       android:dividerHeight="3.0dip" 分割线的宽度        -->        <ListView            android:id="@+id/lv_taskmanage"            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:cacheColorHint="#00000000"            android:divider="#fff"            android:fastScrollEnabled="true"            android:dividerHeight="1.0dip"            android:paddingLeft="3.0dip"            android:paddingRight="3.0dip" />        <RelativeLayout            android:id="@+id/rl_loading"            android:layout_width="fill_parent"            android:layout_height="fill_parent" >            <LinearLayout                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:orientation="vertical"                 android:layout_centerInParent="true">                <ProgressBar                    android:id="@+id/pb"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_gravity="center"                    />                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_marginTop="10dip"                    android:text="正在加载应用程序。。"                    android:textColor="#fff"                    android:textSize="22sp" />            </LinearLayout>        </RelativeLayout>    </FrameLayout></LinearLayout>

6、ListView条目布局

具体代码如下:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:orientation="horizontal"    android:paddingBottom="8.0dip"    android:paddingLeft="6.0dip"    android:paddingRight="5.0dip"    android:paddingTop="8.0dip" >    <ImageView        android:id="@+id/iv_task_manager_icon"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerVertical="true"        android:src="@drawable/ic_launcher" />    <TextView        android:id="@+id/tv_task_manager_name"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="4.0dip"        android:layout_toRightOf="@id/iv_task_manager_icon"        android:textColor="#fff"        android:text="我最摇摆"        android:textSize="18.0dip" />        <TextView        android:id="@+id/tv_task_manager_memory"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_toRightOf="@id/iv_task_manager_icon"        android:layout_below="@id/tv_task_manager_name"        android:textColor="#fff"        android:text="占用内存:20KB"        android:textSize="15sp" /></RelativeLayout>

7、res/values下新建styles.xml文件

我们在这个文件中定义了一些样式,具体代码如下:

<?xml version="1.0" encoding="utf-8"?><resources>    <style name="text_title_style">        <item name="android:layout_width">fill_parent</item>        <item name="android:layout_height">wrap_content</item>        <item name="android:gravity">center</item>        <item name="android:textColor">#42E700</item>        <item name="android:textSize">25sp</item>    </style>        <style name="view_divide_line_style">        <item name="android:layout_width">fill_parent</item>        <item name="android:layout_height">1dip</item>        <item name="android:layout_marginTop">5dip</item>        <item name="android:background">@drawable/devide_line</item>    </style>        <style name="text_content_style">        <item name="android:layout_width">wrap_content</item>        <item name="android:layout_height">wrap_content</item>        <item name="android:textSize">20sp</item>        <item name="android:textColor">#42E700</item>        <item name="android:layout_marginTop">5dip</item>    </style>    <style name="image_start_online_style">        <item name="android:layout_width">wrap_content</item>        <item name="android:layout_height">wrap_content</item>        <item name="android:layout_marginRight">5dip</item>        <item name="android:src">@android:drawable/presence_online</item>    </style>        <style name="image_start_offline_style" parent="image_start_online_style">        <item name="android:src">@android:drawable/presence_invisible</item>    </style>        <style name="button_next_style">        <item name="android:layout_width">wrap_content</item>        <item name="android:layout_height">wrap_content</item>        <item name="android:layout_alignParentRight">true</item>        <item name="android:layout_alignParentBottom">true</item>        <item name="android:text">下一步</item>        <item name="android:drawableRight">@drawable/next</item>    </style>    <style name="button_pre_style">        <item name="android:layout_width">wrap_content</item>        <item name="android:layout_height">wrap_content</item>        <item name="android:layout_alignParentLeft">true</item>        <item name="android:layout_alignParentBottom">true</item>        <item name="android:text">上一步</item>        <item name="android:drawableLeft">@drawable/previous</item>    </style> </resources>

8、授权

最后别忘了,在 AndroidManifest.xml进行权限注册。

具体如下:

 <uses-permission android:name="android.permission.GET_TASKS"/>

三、运行效果

四、温馨提示

本实例中,为了方面,我把一些文字直接写在了布局文件中和相关的类中,大家在真实的项目中要把这些文字写在string.xml文件中,在外部引用这些资源,切记,这是作为一个Android程序员最基本的开发常识和规范,我在这里只是为了方便直接写在了类和布局文件中。

1 0
原创粉丝点击