Android项目实战--手机卫士28--读取进程的信息并显示出来

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011485531/article/details/12879389



最新实战教程,让你了解Android自动化刷量、作弊与防作弊的那些事,案例:刷友盟统计、批量注册苹果帐号




今天呢,我们就继续我们的进程管理啦,昨天我们就讲到了拿到进程数目,以及可用的内存,那么今天,我们就把那些进程一个个的显示出来,

但在做今天这个之前,我先给大家提个醒,我觉得那个程序锁的界面有点不好看,所以就修改了一下,大家到时可以看看源码,我们就先把今天要做的,和那个程序锁的给大家看看先吧

     

大家可以看到,我们这个界面也是挺简单的,有一个标签把系统的进程和用户的进程给区分开来,所以我们到时在显示在listview的时候就要小心处理了,


首先,我们要先新建一个model类,用来存放那些进程的信息

com.xiaobin.security.domain.TaskInfo

package com.xiaobin.security.domain;

import android.graphics.drawable.Drawable;

public class TaskInfo
{
	private String name;
	private Drawable icon;
	private int id;
	//以KB作为单位
	private int memory;
	private boolean isCheck;
	private String packageName;
	
	//是否为系统进程
	private boolean isSystemProcess;
	
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	public Drawable getIcon()
	{
		return icon;
	}
	public void setIcon(Drawable icon)
	{
		this.icon = icon;
	}
	public int getId()
	{
		return id;
	}
	public void setId(int id)
	{
		this.id = id;
	}
	public boolean isCheck()
	{
		return isCheck;
	}
	public void setCheck(boolean isCheck)
	{
		this.isCheck = isCheck;
	}
	public String getPackageName()
	{
		return packageName;
	}
	public void setPackageName(String packageName)
	{
		this.packageName = packageName;
	}
	public int getMemory()
	{
		return memory;
	}
	public void setMemory(int memory)
	{
		this.memory = memory;
	}
	public boolean isSystemProcess()
	{
		return isSystemProcess;
	}
	public void setSystemProcess(boolean isSystemProcess)
	{
		this.isSystemProcess = isSystemProcess;
	}

}

好啦,写完model类之后,我们就要写一个类来读取我们的进程信息啦

com.xiaobin.security.engine.TaskInfoProvider

package com.xiaobin.security.engine;

import java.util.ArrayList;
import java.util.List;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Debug.MemoryInfo;

import com.xiaobin.security.domain.TaskInfo;

public class TaskInfoProvider
{
	private PackageManager packageManager;
	private ActivityManager activityManager;

	public TaskInfoProvider(Context context)
	{
		packageManager = context.getPackageManager();
		activityManager = (ActivityManager) context
				.getSystemService(Context.ACTIVITY_SERVICE);
	}

	public List<TaskInfo> getAllTask(
			List<RunningAppProcessInfo> runningAppProcessInfos)
	{
		List<TaskInfo> taskInfos = new ArrayList<TaskInfo>();
		for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcessInfos)
		{
			TaskInfo taskInfo = new TaskInfo();
			int id = runningAppProcessInfo.pid;
			taskInfo.setId(id);
			String packageName = runningAppProcessInfo.processName;
			taskInfo.setPackageName(packageName);
			try
			{
				// ApplicationInfo是AndroidMainfest文件里面整个Application节点的封装
				ApplicationInfo applicationInfo = packageManager
						.getPackageInfo(packageName, 0).applicationInfo;
				// 应用的图标
				Drawable icon = applicationInfo.loadIcon(packageManager);
				taskInfo.setIcon(icon);
				// 应用的名字
				String name = applicationInfo.loadLabel(packageManager)
						.toString();
				taskInfo.setName(name);
				
				//设置是否为系统应用
				taskInfo.setSystemProcess(!filterApp(applicationInfo));

				// 可以返回一个内存信息的数组,传进去的id有多少个,就返回多少个对应id的内存信息
				MemoryInfo[] memoryInfos = activityManager
						.getProcessMemoryInfo(new int[] { id });
				// 拿到占用的内存空间
				int memory = memoryInfos[0].getTotalPrivateDirty();
				taskInfo.setMemory(memory);
				taskInfos.add(taskInfo);
				taskInfo = null;
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
		return taskInfos;
	}

	// 判断某一个应用程序是不是用户的应用程序,如果是返回true,否则返回false
	public boolean filterApp(ApplicationInfo info)
	{
		// 有些系统应用是可以更新的,如果用户自己下载了一个系统的应用来更新了原来的,
		// 它就不是系统应用啦,这个就是判断这种情况的
		if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)
		{
			return true;
		}
		else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0)// 判断是不是系统应用
		{
			return true;
		}
		return false;
	}

}

读取进程的信息,其实也很简单的,我们上一次已经拿到了RunningAppProcessInfo的集合啦,那么我们只要遍历这个集合,那就可以拿到这些进程啦,

那么,我们就可以读取到它们的processName字段啦,其实这个字段就是这个应用的包名啦,那么, 拿到了包名之后,我们就可以拿到很多信息的啦。

如上面写到的,通过PackageManager来拿到一个applicationInfo,拿到这个对象也好办啦,什么应用名字啦,图标啦,都可以拿到啦,这些我们之前在程序锁啊,应用管理这些都写过啦,上面也再写了一次,当复习啦。

接下来,我们就要读取这个进程占用的内存啦,其实这个操作也很简单啦,就是通过ActivityManager对象来调用它里面的方法getProcessMemoryInfo,通过传递

一个id的数组进去,就可以拿到,对应id数组里面的占用内存信息啦,所以还是挺简单的。


大家还会看到,我们上面有个方法,就是判断是不是系统应用的,其实这个方法,我们之前在应用管理那里也有写过的,但是我当时没怎么说,造成了不少人的误解,那我今天就和大家说一下吧

我们拿到的ApplicationInfo对象里面有个flags,就是标记我们应用的类别的,如FLAG_SYSTEM就是一个系统应用啦,FLAG_UPDATED_SYSTEM_APP就是一个可升级的系统应用啦,但如果用户把它升级了,那么,就应该把它当成是用户的应用的啦,所以我们上面就返回true啦


好啦,写完这个读取进程信息的类之后,我们就要回到我们的界面,显示出来的啦

因为我们读取这些信息都是很久的,所以我们就和程序锁啊,应用管理这些一样,用一个线程来加载这些东西,并显示一个进度条

	private void initData()
	{
		//因为这个title是要显示当前进程数目和可用内存的,所以我们每次在这里都调用一下,以更新数据
		initTitle();
		ll_process_load.setVisibility(View.VISIBLE);
		new Thread(new Runnable()
		{
			@Override
			public void run()
			{
				taskInfoProvider = new TaskInfoProvider(ProcessManagerActivity.this);
				taskInfos = taskInfoProvider.getAllTask(runningAppProcessInfos);
				
				Message msg = new Message();
				msg.what = LOAD_FINISH;
				handler.sendMessage(msg);
			}
		}).start();
	}

完成加载之后,就会发送一个消息给handler,然后就进来显示的操作的

	private Handler handler = new Handler()
	{
		public void handleMessage(Message msg) 
		{
			switch(msg.what)
			{
				case LOAD_FINISH : 
					ll_process_load.setVisibility(View.INVISIBLE);
					adapter = new TaskInfoAdapter();
					lv_process_list.setAdapter(adapter);
					break;
					
				default : 
					break;
			}
		}
	};

那么,接下来,我们就是要进行我们最麻烦的那个操作啦,就是listview的操作啦,也就是adapter的编写啦

因为我们要区分系统进程和用户进程嘛,还要加两个标签,所以那就处理起来有点麻烦的啦

首先,我们要区分系统进程,和用户进程,那么我们就用两个list来分别存放它们,在adapter的构造方法里面,对它们进行初始化

		public TaskInfoAdapter()
		{
			//存放用户的应用进程
			userTaskInfo = new ArrayList<TaskInfo>();
			//存放系统的应用进程
			systemTaskInfo = new ArrayList<TaskInfo>();
			
			for(TaskInfo taskInfo : taskInfos)
			{
				if(taskInfo.isSystemProcess())
				{
					systemTaskInfo.add(taskInfo);
				}
				else
				{
					userTaskInfo.add(taskInfo);
				}
			}
		}

因为我们要加两个标签来显示是用户进程还是系统进程嘛(也就是两个TextView),所以返回的条目就要加2啦

		@Override
		public int getCount()
		{
			//加上两个标签,一个是系统标签,一个是用户标签
			return taskInfos.size() + 2;
		}

因为多了两个条目,所以返回值也要特别处理一下啦

		@Override
		public Object getItem(int position)
		{
			if(position == 0)
			{
				return 0;	//显示成用户应用的标签
			}
			else if(position <= userTaskInfo.size())
			{
				return userTaskInfo.get(position - 1);	//用户应用进程的条目
			}
			else if(position == userTaskInfo.size() + 1)
			{
				return position;	//显示成系统进程的标签
			}
			else if(position <= taskInfos.size() + 2)
			{
				//系统应用进程的条目
				return systemTaskInfo.get(position - userTaskInfo.size() - 2);
			}
			else
			{
				return position;
			}
		}

最后,就是我们的getView方法啦,这个是非常的重要的,关系到我们的显示

		@Override
		public View getView(int position, View convertView, ViewGroup parent)
		{
			View view;
			TaskInfoViews views;
			TaskInfo taskInfo;
			if(position == 0)
			{
				//显示成用户应用的标签
				return newTextView("用户进程(" + userTaskInfo.size() + ")");	
			}
			else if(position <= userTaskInfo.size())
			{
				//用户应用进程的条目
				taskInfo = userTaskInfo.get(position - 1);
			}
			else if(position == userTaskInfo.size() + 1)
			{
				//显示成系统进程的标签
				return newTextView("系统进程(" +  systemTaskInfo.size() + ")");	
			}
			else if(position <= taskInfos.size() + 2)
			{
				//系统应用进程的条目
				taskInfo = systemTaskInfo.get(position - userTaskInfo.size() - 2);
			}
			else
			{
				taskInfo = new TaskInfo();
			}
			if(convertView == null || convertView instanceof TextView)
			{
				view = View.inflate(ProcessManagerActivity.this, R.layout.process_manager_item, null);
				
				views = new TaskInfoViews();
				views.iv_process_icon = (ImageView) view.findViewById(R.id.iv_process_manager_icon);
				views.tv_process_name = (TextView) view.findViewById(R.id.tv_process_manager_name);
				views.tv_process_memory = (TextView) view.findViewById(R.id.tv_process_manager_memory);
				views.cb_process_state = (CheckBox) view.findViewById(R.id.cb_process_manager_state);
				view.setTag(views);
			}
			else
			{
				view = convertView;
				views = (TaskInfoViews) view.getTag();
			}
			views.iv_process_icon.setImageDrawable(taskInfo.getIcon());
			views.tv_process_name.setText(taskInfo.getName());
			views.tv_process_memory.setText("占用内存:" + TextFormater.getSizeFromKB(taskInfo.getMemory()));
			views.cb_process_state.setChecked(taskInfo.isCheck());
			return view;
		}

在里面,我们用到一个生成TextView的方法

		private TextView newTextView(String title)
		{
			TextView tv_title = new TextView(ProcessManagerActivity.this);
			tv_title.setText(title);
			return tv_title;
		}

好啦,这个adapter比较复杂,不像我们之前写的那样,直接显示就行啦,这次,多了很多判断,但实际开发中,这种情况是很常见的,所以大家最好懂得这样来定义自己复杂的adapter,不然就会很麻烦的了

如果对上面代码有什么不明白的,可以说出来


好啦,写到这里,我们的逻辑就基本上完成的啦,下面把activity的完整类和布局文件粘出来

process_manager.item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="65dip"
    android:background="@drawable/item_background_selector">
    
    <ImageView 
        android:id="@+id/iv_process_manager_icon"
        android:layout_width="60dip"
        android:layout_height="60dip"
        android:layout_alignParentLeft="true"
        android:scaleType="fitXY"
        android:src="@drawable/app"
        android:contentDescription="@string/hello_world"/>
    
    <LinearLayout 
        android:layout_width="wrap_content"
        android:layout_height="65dip"
        android:layout_toRightOf="@id/iv_process_manager_icon"
        android:layout_marginLeft="10dip"
        android:gravity="center_vertical"
        android:orientation="vertical">
        
	    <TextView 
	        android:id="@+id/tv_process_manager_name"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:textSize="18sp"
	        android:textColor="#ff000000"
	        android:text="@string/hello_world"/>
	    
	    <TextView 
	        android:id="@+id/tv_process_manager_memory"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:textSize="16sp"
	        android:textColor="#ff000000"
	        android:text="@string/hello_world"/>
        
    </LinearLayout>
    
    <CheckBox 
        android:id="@+id/cb_process_manager_state"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dip"/>
    
</RelativeLayout>


com.xiaobin.security.ui.ProcessManagerActivity

package com.xiaobin.security.ui;

import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.xiaobin.security.R;
import com.xiaobin.security.domain.TaskInfo;
import com.xiaobin.security.engine.TaskInfoProvider;
import com.xiaobin.security.utils.TextFormater;

public class ProcessManagerActivity extends Activity implements OnClickListener
{
	private static final int LOAD_FINISH = 1;

	private TextView tv_process_count;
	private TextView tv_process_memory;

	private LinearLayout ll_process_load;
	private ListView lv_process_list;
	private Button bt_process_clear;
	private Button bt_process_setting;

	private ActivityManager activityManager;
	private List<RunningAppProcessInfo> runningAppProcessInfos;
	private TaskInfoProvider taskInfoProvider;
	private List<TaskInfo> taskInfos;
	private TaskInfoAdapter adapter;

	@SuppressLint("HandlerLeak")
	private Handler handler = new Handler()
	{
		public void handleMessage(Message msg)
		{
			switch (msg.what)
			{
				case LOAD_FINISH:
					ll_process_load.setVisibility(View.INVISIBLE);
					adapter = new TaskInfoAdapter();
					lv_process_list.setAdapter(adapter);
					break;

				default:
					break;
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

		// 请求一个自己定义的title,但有一些Android系统是被修改过的,
		// 所以有可能是无法请求的,如乐Phone或小米的手机,这些系统是被修改过的,
		// 所以就要判断一下是否请求成功
		boolean flags = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

		setContentView(R.layout.process_manager);

		if (flags)
		{
			// 设置自定义的title
			getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
					R.layout.process_manager_title);
		}

		tv_process_count = (TextView) findViewById(R.id.tv_process_count);
		tv_process_memory = (TextView) findViewById(R.id.tv_process_memory);

		ll_process_load = (LinearLayout) findViewById(R.id.ll_process_load);
		lv_process_list = (ListView) findViewById(R.id.lv_process_list);
		bt_process_clear = (Button) findViewById(R.id.bt_process_clear);
		bt_process_setting = (Button) findViewById(R.id.bt_process_setting);
		bt_process_clear.setOnClickListener(this);
		bt_process_setting.setOnClickListener(this);

		initData();
	}

	@Override
	public void onClick(View v)
	{
		switch (v.getId())
		{
			case R.id.bt_process_clear:
				break;

			case R.id.bt_process_setting:
				break;

			default:
				break;
		}
	}

	private void initData()
	{
		// 因为这个title是要显示当前进程数目和可用内存的,所以我们每次在这里都调用一下,以更新数据
		initTitle();
		ll_process_load.setVisibility(View.VISIBLE);
		new Thread(new Runnable()
		{
			@Override
			public void run()
			{
				taskInfoProvider = new TaskInfoProvider(
						ProcessManagerActivity.this);
				taskInfos = taskInfoProvider.getAllTask(runningAppProcessInfos);

				Message msg = new Message();
				msg.what = LOAD_FINISH;
				handler.sendMessage(msg);
			}
		}).start();
	}

	// 拿到当前运行的进程数目
	private int getRunningAppCount()
	{
		runningAppProcessInfos = activityManager.getRunningAppProcesses();
		return runningAppProcessInfos.size();
	}

	// 拿到系统剩余的内存
	private String getAvailMemory()
	{
		// new一个内存的对象
		MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
		// 拿到现在系统里面的内存信息
		activityManager.getMemoryInfo(memoryInfo);
		// 拿到有效的内存空间
		long size = memoryInfo.availMem;
		return TextFormater.dataSizeFormat(size);
	}

	// 设置title的信息
	private void initTitle()
	{
		tv_process_count.setText("进程数目:" + getRunningAppCount());
		tv_process_memory.setText("剩余内存:" + getAvailMemory());
	}

	// ===========================================================================

	private class TaskInfoAdapter extends BaseAdapter
	{
		private List<TaskInfo> userTaskInfo;
		private List<TaskInfo> systemTaskInfo;

		public TaskInfoAdapter()
		{
			// 存放用户的应用进程
			userTaskInfo = new ArrayList<TaskInfo>();
			// 存放系统的应用进程
			systemTaskInfo = new ArrayList<TaskInfo>();

			for (TaskInfo taskInfo : taskInfos)
			{
				if (taskInfo.isSystemProcess())
				{
					systemTaskInfo.add(taskInfo);
				}
				else
				{
					userTaskInfo.add(taskInfo);
				}
			}
		}

		@Override
		public int getCount()
		{
			// 加上两个标签,一个是系统标签,一个是用户标签
			return taskInfos.size() + 2;
		}

		@Override
		public Object getItem(int position)
		{
			if (position == 0)
			{
				return 0; // 显示成用户应用的标签
			}
			else if (position <= userTaskInfo.size())
			{
				return userTaskInfo.get(position - 1); // 用户应用进程的条目
			}
			else if (position == userTaskInfo.size() + 1)
			{
				return position; // 显示成系统进程的标签
			}
			else if (position <= taskInfos.size() + 2)
			{
				// 系统应用进程的条目
				return systemTaskInfo.get(position - userTaskInfo.size() - 2);
			}
			else
			{
				return position;
			}
		}

		@Override
		public long getItemId(int position)
		{
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent)
		{
			View view;
			TaskInfoViews views;
			TaskInfo taskInfo;
			if (position == 0)
			{
				// 显示成用户应用的标签
				return newTextView("用户进程(" + userTaskInfo.size() + ")");
			}
			else if (position <= userTaskInfo.size())
			{
				// 用户应用进程的条目
				taskInfo = userTaskInfo.get(position - 1);
			}
			else if (position == userTaskInfo.size() + 1)
			{
				// 显示成系统进程的标签
				return newTextView("系统进程(" + systemTaskInfo.size() + ")");
			}
			else if (position <= taskInfos.size() + 2)
			{
				// 系统应用进程的条目
				taskInfo = systemTaskInfo.get(position - userTaskInfo.size()
						- 2);
			}
			else
			{
				taskInfo = new TaskInfo();
			}
			if (convertView == null || convertView instanceof TextView)
			{
				view = View.inflate(ProcessManagerActivity.this,
						R.layout.process_manager_item, null);

				views = new TaskInfoViews();
				views.iv_process_icon = (ImageView) view
						.findViewById(R.id.iv_process_manager_icon);
				views.tv_process_name = (TextView) view
						.findViewById(R.id.tv_process_manager_name);
				views.tv_process_memory = (TextView) view
						.findViewById(R.id.tv_process_manager_memory);
				views.cb_process_state = (CheckBox) view
						.findViewById(R.id.cb_process_manager_state);
				view.setTag(views);
			}
			else
			{
				view = convertView;
				views = (TaskInfoViews) view.getTag();
			}
			views.iv_process_icon.setImageDrawable(taskInfo.getIcon());
			views.tv_process_name.setText(taskInfo.getName());
			views.tv_process_memory.setText("占用内存:"
					+ TextFormater.getSizeFromKB(taskInfo.getMemory()));
			views.cb_process_state.setChecked(taskInfo.isCheck());
			return view;
		}

		private TextView newTextView(String title)
		{
			TextView tv_title = new TextView(ProcessManagerActivity.this);
			tv_title.setText(title);
			return tv_title;
		}

	}

	private class TaskInfoViews
	{
		ImageView iv_process_icon;
		TextView tv_process_name;
		TextView tv_process_memory;
		CheckBox cb_process_state;
	}

}


好啦,今天就讲到这里啦,有什么不明白的,可以留言


最后,和大家说一下

为了方便大家的交流,我创建了一个群,这样子大家有什么疑问也可以在群上交流

群号是298440981



今天源码下载



猜你喜欢

转载自blog.csdn.net/u011485531/article/details/12879389