MobileSafeNotes Day09

本文介绍了如何在Android应用中获取正在运行的进程信息,处理界面中checkbox的复用和状态管理,实现全选、反选功能,以及清理进程和内存的详细步骤,包括用户进程、系统进程和不同类型的内存管理。
摘要由CSDN通过智能技术生成

##Day09##

#9.1获取正在运行的进程的信息#

/**
 * 获取正在运行的进程的信息
 */
public static List<TaskInfo> getTaskInfos(Context context){
	List<TaskInfo> list  = new ArrayList<TaskInfo>();
	//进程的管理者
	ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
	PackageManager pm = context.getPackageManager();
	//获取正在运行进程信息
	List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();
	for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) {
		TaskInfo taskInfo = new TaskInfo();
		//获取进程的名称,就是包名
		String packagName = runningAppProcessInfo.processName;
		taskInfo.setPackagname(packagName);
		//获取相应的进程所占用的空间,int[]  你传入几个进程pid就返回几个进程所占用的空间
		MemoryInfo[] processMemoryInfo = am.getProcessMemoryInfo(new int[]{runningAppProcessInfo.pid});
		//将获取的内存信息转化kb的形式
		int totalPss = processMemoryInfo[0].getTotalPss();
		//获取进程所占用的内存信息
		long ramsize  = totalPss*1024;
		taskInfo.setRamsize(ramsize);
		try {
			//获取applicationinfo,根据进程的名称获取相应进程的applicationinfo信息
			ApplicationInfo applicationInfo = pm.getApplicationInfo(packagName, 0);
			//获取图标
			Drawable icon = applicationInfo.loadIcon(pm);
			taskInfo.setIcon(icon);
			//获取应用的名称
			String name = applicationInfo.loadLabel(pm).toString();
			taskInfo.setName(name);
			//获取application的所有标签
			int flags = applicationInfo.flags;
			boolean isUser;
			//判断是否用户进程
			if ((flags & applicationInfo.FLAG_SYSTEM) == applicationInfo.FLAG_SYSTEM) {
				//系统进程
				isUser = false;
			}else{
				//用户进程
				isUser = true;
			}
			taskInfo.setUser(isUser);
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		//添加到集合中
		list.add(taskInfo);
	}
	return list;
}

#9.2界面布局及bug的处理#

选中checkbox发现,复用的条目也选中,原因:是因为在复用checkbox的时候也把checkbox状态给复用了,所以一般在复用的时候,经常操作的控件的值,我们是不会复用的,一般会将复用的空间的值保存到bean对象中
	
条目点击事件中进行
1.在bean类中设置保存checkbox的状态的变量
2.在getview中根据保存的值去设置checkbox的状态
		//根据bean类中保存的checkbox状态来设置条目的checkbox的状态
		if (appInfo.isChecked()) {
			viewHolder.cb_itemtaskmanager_ischecked.setChecked(true);
		}else{
			viewHolder.cb_itemtaskmanager_ischecked.setChecked(false);
		}
3.在条目点击事件中进行点击修改操作
	lv_taskmanager_process.setOnItemClickListener(new OnItemClickListener() {
		//view :条目的view对象
		@Override
		public void onItemClick(AdapterView<?> parent, View view,
				int position, long id) {
			//1.屏蔽用户程序多少个和系统程序多少个点击事件
			if (position == 0 || position == userAppInfos.size()+1) {
				return;
			}
			//2.获取进程信息
			//获取条目对应的信息
			//判断用户程序是否展示完
			if (position <= userAppInfos.size()) {
				//获取用户程序
				appInfo = userAppInfos.get(position-1);
			}else{
				//系统程序
				appInfo = systemAppInfos.get(position - userAppInfos.size()-2);
			}
			//3.设置checkbox的状态,保存checkbox的状态
			//根据保存的状态来判断,选中就改为不选中,不选中就改为选中
			if (appInfo.isChecked()) {
				appInfo.setChecked(false);
			}else{
				appInfo.setChecked(true);
			}
			//4.更新界面
			//第一种方式
			//myAdapter.notifyDataSetChanged();
			//第二种方式,刷新单个条目
			ViewHolder viewHolder = (ViewHolder) view.getTag();
			viewHolder.cb_itemtaskmanager_ischecked.setChecked(appInfo.isChecked());
		}
	});

#9.3全选&反选#

	/**
	 * 全选
	 */
	public void all(View v){
		//设置用户程序的checkbox为true
		for (TaskInfo taskinfo : userAppInfos) {
			taskinfo.setChecked(true);
		}
		//系统程序的checkbox为true
		for (TaskInfo taskinfo : systemAppInfos) {
			taskinfo.setChecked(true);
		}
		//更新界面
		myAdapter.notifyDataSetChanged();
	}
	/**
	 * 反选
	 * @param v
	 */
	public void cancel(View v){
		//用户程序
		for (TaskInfo taskInfo : userAppInfos) {
			//true改为false,false改为true
			taskInfo.setChecked(!taskInfo.isChecked());
		}
		//系统程序
		for (TaskInfo taskInfo : systemAppInfos) {
			//true改为false,false改为true
			taskInfo.setChecked(!taskInfo.isChecked());
		}
		//更新界面
		myAdapter.notifyDataSetChanged();
	}

#9.4清理#

前台进程 : 在通知栏上的都是前台进程,前台杀不死,程序一直在运行
可见进程 : 现在用的进程,这个进程也杀不死
服务进程	: 运行服务的进程,当内存不足的时候杀死服务进程,当内存充足的时候不杀死,当内存不足杀死之后,在内存充足的时候,系统会自动重启服务
后台进程 : 运行在后台进程,杀死
空进程	: 程序退出之后,它的进程就会变成空进程,是为了方便下次启动的时候能快速启动,杀死
优先进程
前台进程 -> 可见进程 -> 服务进程 -> 后台进程 -> 空进程

清理
	/**
	 * 清理
	 * @param v
	 */
	public void clear(View v){
		//杀死进程
		//1.获取进程的管理者
		ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
		//保存被杀死的进程的信息
		List<TaskInfo> deletinfos = new ArrayList<TaskInfo>();
		//2.杀死用户进程,不能再集合循环的时候,从集合中移出数据
		for (TaskInfo taskInfo : userAppInfos) {
			//判断进程是否选中,选中杀死,没选中不杀死
			if (taskInfo.isChecked()) {
				//杀死后台进程
				//packageName : 包名
				am.killBackgroundProcesses(taskInfo.getPackagname());
				deletinfos.add(taskInfo);
			}
		}
		//3.杀死系统进程
		for (TaskInfo taskInfo : systemAppInfos) {
			//判断进程是否选中,选中杀死,没选中不杀死
			if (taskInfo.isChecked()) {
				//杀死后台进程
				//packageName : 包名
				am.killBackgroundProcesses(taskInfo.getPackagname());
				deletinfos.add(taskInfo);
			}
		}
		//根据杀死进程集合中的信息,去删除用户进程和系统进程集合中的数据
		for (TaskInfo taskInfo : deletinfos) {
			if (taskInfo.isUser()) {
				userAppInfos.remove(taskInfo);
			}else{
				systemAppInfos.remove(taskInfo);
			}
		}
		//更新界面
		myAdapter.notifyDataSetChanged();
	}
	权限:<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>

#9.5进程的细节处理#

1.在清理操作中,添加提醒用户杀死进程和释放内存的操作
	long memory=0;
	//根据杀死进程集合中的信息,去删除用户进程和系统进程集合中的数据
	for (TaskInfo taskInfo : deletinfos) {
		if (taskInfo.isUser()) {
			userAppInfos.remove(taskInfo);
		}else{
			systemAppInfos.remove(taskInfo);
		}
		memory+=taskInfo.getRamsize();
	}
	//b -> mb
	String size = Formatter.formatFileSize(getApplicationContext(), memory);
	Toast.makeText(getApplicationContext(), "共杀死"+deletinfos.size()+"个进程,释放"+size+"内存", 0).show();
	//杀死进程做准备
	deletinfos.clear();
	deletinfos = null;
2.处理不能选中自己的效果
	a.在条目点击事件中
			if (appInfo.isChecked()) {
				appInfo.setChecked(false);
			}else{
				if (!appInfo.getPackagname().equals(getPackageName())) {
					appInfo.setChecked(true);
				}
			}
	b.在全选中进行操作
			//设置用户程序的checkbox为true
			for (TaskInfo taskinfo : userAppInfos) {
				if (!appInfo.getPackagname().equals(getPackageName())) {
					taskinfo.setChecked(true);
				}
			}
	c.在反选中操作
		//用户程序
		for (TaskInfo taskInfo : userAppInfos) {
			if (!appInfo.getPackagname().equals(getPackageName())) {
				//true改为false,false改为true
				taskInfo.setChecked(!taskInfo.isChecked());
			}
		}

#9.6获取进程个数和内存#

proc -> meminfo(存储的就是内存的信息)
@deprecated : 可以将方法设置成过时的方法

1.创建一个工具类,创建获取进程数和内存的方法
	/**
	 * 获取正在运行的进程的个数
	 * @return
	 */
	public static int getAvailableProcess(Context context){
		ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningAppProcessInfo> processes = am.getRunningAppProcesses();
		return processes.size();
	}
	/**
	 * 获取空闲的内存信息
	 * @param context
	 * @return
	 */
	public static long getAvaliableRam(Context context){
		ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		MemoryInfo outInfo = new MemoryInfo();//创建一个白纸
		am.getMemoryInfo(outInfo);//将内存的信息写到白纸上
		return outInfo.availMem;//空闲内存
//		outInfo.totalMem;//总共内存
//		return 0;
	}
	/**
	 * 获取总的内存信息
	 * @param context
	 * @return
	 * 在高版本中使用的
	 */
	public static long getTotalRam(Context context){
		ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		MemoryInfo outInfo = new MemoryInfo();//创建一个白纸
		am.getMemoryInfo(outInfo);//将内存的信息写到白纸上
//		return outInfo.availMem;//空闲内存
		return outInfo.totalMem;//总共内存,高版本中有的字段,在低版本中不能使用
//		return 0;
	} 
	/**
	 * 获取总的内存信息
	 * @param context
	 * @return
	 * 在低版本中使用的
	 * @deprecated
	 */
	public static long getTotalRam(){
		StringBuilder sb = new StringBuilder();
		File file = new File("/proc/meminfo");
		try {
			BufferedReader br = new BufferedReader(new FileReader(file));
			//读取出一行信息
			String readLine = br.readLine();
			//解析出数字
			//转化成字符数组
			char[] charArray = readLine.toCharArray();
			//拿出string类型中的所有数字
			for (char c : charArray) {
				//判断字符数组中的元素是否数字
				if (c >='0' && c<='9') {
					//添加组合
					sb.append(c);
				}
			}
			String string = sb.toString();//数字
			//转化成int
			long parseInt = Integer.parseInt(string);
			return parseInt*1024;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}
2.使用,着重掌握根据sdk执行不同方法操作
	//获取进程个数
	int availableProcess = ProcessUtils.getAvailableProcess(getApplicationContext());
	tv_taskmanager_process_count.setText("运行中进程:"+availableProcess+"个");
	//获取空闲内存和总内存
	long avaliableRam = ProcessUtils.getAvaliableRam(getApplicationContext());
	//转成成字符串
	String freesize = Formatter.formatFileSize(getApplicationContext(), avaliableRam);
	//获取总内存
	//获取sdk的版本
	int sdk = android.os.Build.VERSION.SDK_INT;
	//根据sdk的版本执行相应的方法,来避免程序出错
	long totalRam;
	if (sdk >= 16) {
		totalRam = ProcessUtils.getTotalRam(getApplicationContext());
	}else{
		totalRam = ProcessUtils.getTotalRam();
	}
	//转化成字符串
	String totalsize = Formatter.formatFileSize(getApplicationContext(), totalRam);
	tv_taskmanager_ramortotal.setText("剩余/总内存:"+freesize+"/"+totalsize);

#9.7清理进程的细节处理#

原因:程序运行就需要内存,程序退出内存会释放的,但是android系统为了快速启动应用,不会完成释放,当我们再次打开的时候,会获取内存,这时候就会把原来的内存加上去,

细节的处理
	//修改显示的进程数
	availableProcess = availableProcess - deletinfos.size();
	tv_taskmanager_process_count.setText("运行中进程:"+availableProcess);
	memory = avaliableRam+memory;
	//转化成字符串
	String formatFileSize = Formatter.formatFileSize(getApplicationContext(), memory);
	//空闲空间处理
	tv_taskmanager_ramortotal.setText("剩余/总内存:"+formatFileSize+"/"+totalsize);
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值