转载请注明出处: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上。
好了,原理啰嗦完了,这里的原理我不同于以往的写法,而是将重要的知识点列出来了,亲们,是不是很简单?看完原理,咱们一起实现这些功能吧。
考虑到我们获取内存大小,和每个任务进程占用的内存大小时,会出现数据单位不统一的情况,这时,我们自己定义一个数据格式化类,来帮助我们实现数据单位的格式化。
具体代码如下:
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 "超出统计范围"; } } }
在我们这个任务列表中会显示的内容有图标、名称、每个应用占用的内存、包名、进程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; //进程id private 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; } @Override public String toString() { return "TaskInfo [task_icon=" + task_icon + ", task_name=" + task_name + ", task_memory=" + task_memory + ", packageName=" + packageName + ", pid=" + pid + "]"; } }
我把获取进程与内存信息的方法全部封装在了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; //单位是byte return 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 block e.printStackTrace(); } //进程id int 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(); //KB taskInfo.setTask_memory(totalPrivateDirty); taskInfos.add(taskInfo); } return taskInfos; } }
这个类中的内容比较多,我们分解来看吧。
以下代码是我们这个类中,所有的属性字段
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;
我在TaskManagerActivity类中,自定义了ListView的适配器。这里我用到了ListView的优化策略,使用了ViewHolder来优化ListView。有关ListView优化的策略,大家可以参考《Android之——ListView优化》一文。
具体代码如下:
/** * 自定义适配器 * @author liuyazhuang * */ private class TaskManagerAdapter extends BaseAdapter{ private LayoutInflater mInflater; public TaskManagerAdapter(){ mInflater = getLayoutInflater(); } @Override public int getCount() { return taskInfos.size(); } @Override public Object getItem(int position) { return taskInfos.get(position); } @Override public long getItemId(int position) { return position; } @Override public 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; }
这个方法主要实现的是,UI控件的初始化,由于或许进程列表是一个耗时的操作,所以我将它放在一个线程中,获取到进程信息后通过Handler将信息传递到UI线程显示数据。
具体实现代码如下:
@Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.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() { @Override public void run() { taskInfos = TaskUtils.getTaskInfos(getApplicationContext()); Message msg = new Message(); msg.what = SUCCESS_GETTASKINFO; mHandler.sendMessage(msg); } }).start(); }
用于接收子线程传递过来的数据。
具体代码实现如下:
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; } }; };
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; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.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() { @Override public 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(); } @Override public int getCount() { return taskInfos.size(); } @Override public Object getItem(int position) { return taskInfos.get(position); } @Override public long getItemId(int position) { return position; } @Override public 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; } }
具体代码如下:
<?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>
具体代码如下:
<?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>
我们在这个文件中定义了一些样式,具体代码如下:
<?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>
最后别忘了,在 AndroidManifest.xml进行权限注册。
具体如下:
<uses-permission android:name="android.permission.GET_TASKS"/>
本实例中,为了方面,我把一些文字直接写在了布局文件中和相关的类中,大家在真实的项目中要把这些文字写在string.xml文件中,在外部引用这些资源,切记,这是作为一个Android程序员最基本的开发常识和规范,我在这里只是为了方便直接写在了类和布局文件中。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/l1028386804/article/details/47263863