Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android之——獲取進程總數、內存、任務列表

Android之——獲取進程總數、內存、任務列表

編輯:關於Android編程

 

如今,基於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;
	//進程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 + ];
	}
	
}

 

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; //單位是byte
		return availMem;
	}
	
	/**
	 * 獲取系統所有的進程信息列表
	 * @param context
	 * @return
	 */
	public static List getTaskInfos(Context context){
		List taskInfos  = new ArrayList();
		PackageManager pm = context.getPackageManager();
		ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		List 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;
	}
}

 

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 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();
		}
		@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;
	}

 

3)onCreate方法

這個方法主要實現的是,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();
	}

 

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 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;
	}
}

 

5、頁面布局

具體代碼如下:

 




    

    
	
    
        
        
        
        
    

    <framelayout android:layout_height="fill_parent" android:layout_width="fill_parent">

        
        

        

            

                

                
            
        
    </framelayout>

 

6、ListView條目布局

具體代碼如下:

 




    

    
    
    

 

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

我們在這個文件中定義了一些樣式,具體代碼如下:

 



 

 

8、授權

最後別忘了,在 AndroidManifest.xml進行權限注冊。

具體如下:

 

 

 

三、運行效果

height=352

height=393

四、溫馨提示

本實例中,為了方面,我把一些文字直接寫在了布局文件中和相關的類中,大家在真實的項目中要把這些文字寫在string.xml文件中,在外部引用這些資源,切記,這是作為一個Android程序員最基本的開發常識和規范,我在這裡只是為了方便直接寫在了類和布局文件中。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved