【0070】【项目实战】-【手机安全卫士】-【10】进程管理
1. 界面及效果

2. 页面跳转/页面布局
【主页面跳转】



【页面布局】


【listView的展示占位】默认的listView没有占用的权重;需要增加该权重;





【源码】
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 <TextView 7 android:text="进程管理" 8 style="@style/TitleStyle"/> 9 <RelativeLayout 10 android:padding="5dp" 11 android:layout_width="match_parent" 12 android:layout_height="wrap_content"> 13 <TextView 14 android:id="@+id/tv_process_count" 15 android:text="进程总数" 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content"/> 18 <TextView 19 android:id="@+id/tv_memory_info" 20 android:text="剩余/总共" 21 android:layout_alignParentRight="true" 22 android:layout_width="wrap_content" 23 android:layout_height="wrap_content"/> 24 </RelativeLayout> 25 <!-- ListView默认不占有高度 --> 26 <FrameLayout 27 android:layout_width="match_parent" 28 android:layout_height="0dp" 29 android:layout_weight="1"> 30 <TextView 31 android:background="#ccc" 32 android:id="@+id/tv_des" 33 android:textColor="#000" 34 android:textSize="18sp" 35 android:layout_width="match_parent" 36 android:layout_height="wrap_content"/> 37 38 <ListView 39 android:id="@+id/lv_process_list" 40 android:layout_width="match_parent" 41 android:layout_height="match_parent" > 42 </ListView> 43 44 </FrameLayout> 45 <LinearLayout 46 android:layout_width="match_parent" 47 android:layout_height="wrap_content" 48 android:orientation="horizontal"> 49 <Button 50 android:id="@+id/bt_select_all" 51 android:layout_width="0dp" 52 android:text="全选" 53 android:textSize="14sp" 54 android:layout_weight="1" 55 android:layout_height="wrap_content"/> 56 <Button 57 android:id="@+id/bt_select_reverse" 58 android:layout_width="0dp" 59 android:text="反选" 60 android:textSize="14sp" 61 android:layout_weight="1" 62 android:layout_height="wrap_content"/> 63 <Button 64 android:id="@+id/bt_clear" 65 android:layout_width="0dp" 66 android:text="一键清理" 67 android:textSize="14sp" 68 android:layout_weight="1" 69 android:layout_height="wrap_content"/> 70 <Button 71 android:layout_width="0dp" 72 android:text="设置" 73 android:id="@+id/bt_setting" 74 android:textSize="14sp" 75 android:layout_weight="1" 76 android:layout_height="wrap_content"/> 77 </LinearLayout> 78 </LinearLayout>
3.获取可用内存数&总内存数
【创建引擎类】对应四个功能四个方法

3.1【获取进程总数的方法】

3.2【获取可用内存空间】

3.3【获取内存总空间】






1 /** 2 * @param ctx 3 * @return 返回总的内存数 单位为bytes 返回0说明异常 4 */ 5 public static long getTotalSpace(Context ctx){ 6 /*//1,获取activityManager 7 ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); 8 //2,构建存储可用内存的对象 9 MemoryInfo memoryInfo = new MemoryInfo(); 10 //3,给memoryInfo对象赋(可用内存)值 11 am.getMemoryInfo(memoryInfo); 12 //4,获取memoryInfo中相应可用内存大小 13 return memoryInfo.totalMem;*/ 14 15 //内存大小写入文件中,读取proc/meminfo文件,读取第一行,获取数字字符,转换成bytes返回 16 FileReader fileReader = null; 17 BufferedReader bufferedReader = null; 18 try { 19 fileReader= new FileReader("proc/meminfo"); 20 bufferedReader = new BufferedReader(fileReader); 21 String lineOne = bufferedReader.readLine(); 22 //将字符串转换成字符的数组 23 char[] charArray = lineOne.toCharArray(); 24 //循环遍历每一个字符,如果此字符的ASCII码在0到9的区域内,说明此字符有效 25 StringBuffer stringBuffer = new StringBuffer(); 26 for (char c : charArray) { 27 if(c>='0' && c<='9'){ 28 stringBuffer.append(c); 29 } 30 } 31 return Long.parseLong(stringBuffer.toString())*1024; //将拼接的数字转换为long类型
32 } catch (Exception e) { 33 e.printStackTrace(); 34 }finally{ 35 try { 36 if(fileReader!=null && bufferedReader!=null){ 37 fileReader.close(); 38 bufferedReader.close(); 39 } 40 } catch (IOException e) { 41 e.printStackTrace(); 42 } 43 } 44 return 0; //返回0说明异常 45 }
3.4【进程信息的获取】
【获取的进程信息】

【每个条目的信息组成一个javabean】
1 package com.itheima.mobilesafe74.db.domain; 2 3 import android.graphics.drawable.Drawable; 4 5 public class ProcessInfo { 6 public String name;//应用名称 7 public Drawable icon;//应用图标 8 public long memSize;//应用已使用的内存数 9 public boolean isCheck;//是否被选中 10 public boolean isSystem;//是否为系统应用 11 public String packageName;//如果进程没有名称,则将其所在应用的包名最为名称 12 13 public String getName() { 14 return name; 15 } 16 public void setName(String name) { 17 this.name = name; 18 } 19 public Drawable getIcon() { 20 return icon; 21 } 22 public void setIcon(Drawable icon) { 23 this.icon = icon; 24 } 25 public long getMemSize() { 26 return memSize; 27 } 28 public void setMemSize(long memSize) { 29 this.memSize = memSize; 30 } 31 public boolean isCheck() { 32 return isCheck; 33 } 34 public void setCheck(boolean isCheck) { 35 this.isCheck = isCheck; 36 } 37 public boolean isSystem() { 38 return isSystem; 39 } 40 public void setSystem(boolean isSystem) { 41 this.isSystem = isSystem; 42 } 43 public String getPackageName() { 44 return packageName; 45 } 46 public void setPackageName(String packageName) { 47 this.packageName = packageName; 48 } 49 }
【源码】
1 /** 2 * @param ctx 上下文环境 3 * @return 当前手机正在运行的进程的相关信息 4 */ 5 public static List<ProcessInfo> getProcessInfo(Context ctx){ 6 //获取进程相关信息 7 List<ProcessInfo> processInfoList = new ArrayList<ProcessInfo>(); 8 //1,activityManager管理者对象和PackageManager管理者对象 9 ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); 10 PackageManager pm = ctx.getPackageManager(); 11 //2,获取正在运行的进程的集合 12 List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses(); 13 14 //3,循环遍历上诉集合,获取进程相关信息(名称,包名,图标,使用内存大小,是否为系统进程(状态机)) 15 for (RunningAppProcessInfo info : runningAppProcesses) { 16 ProcessInfo processInfo = new ProcessInfo(); 17 //4,获取进程的名称 == 应用的包名 18 processInfo.packageName = info.processName; 19 //5,获取进程占用的内存大小(传递一个进程对应的pid数组) 20 android.os.Debug.MemoryInfo[] processMemoryInfo = am.getProcessMemoryInfo(new int[]{info.pid}); 21 //6,返回数组中索引位置为0的对象,为当前进程的内存信息的对象 22 android.os.Debug.MemoryInfo memoryInfo = processMemoryInfo[0]; 23 //7,获取已使用的大小 24 processInfo.memSize = memoryInfo.getTotalPrivateDirty()*1024; 25 26 try { 27 ApplicationInfo applicationInfo = pm.getApplicationInfo(processInfo.packageName, 0); 28 //8,获取应用的名称 29 processInfo.name = applicationInfo.loadLabel(pm).toString(); 30 //9,获取应用的图标 31 processInfo.icon = applicationInfo.loadIcon(pm); 32 //10,判断是否为系统进程 33 if((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM){ 34 processInfo.isSystem = true; 35 }else{ 36 processInfo.isSystem = false; 37 } 38 } catch (NameNotFoundException e) { 39 //需要处理 40 processInfo.name = info.processName; 41 processInfo.icon = ctx.getResources().getDrawable(R.drawable.ic_launcher); 42 processInfo.isSystem = true; 43 e.printStackTrace(); 44 } 45 processInfoList.add(processInfo); 46 } 47 return processInfoList; 48 }
3.5 显示进程数&内存使用情况


【源码】/mobilesafe74/src/com/itheima/mobilesafe74/activity/ProcessManagerActivity.java
1 private void initTitleData() { 2 mProcessCount = ProcessInfoProvider.getProcessCount(this); 3 tv_process_count.setText("进程总数:"+mProcessCount); 4 5 //获取可用内存大小,并且格式化 6 mAvailSpace = ProcessInfoProvider.getAvailSpace(this); 7 String strAvailSpace = Formatter.formatFileSize(this, mAvailSpace); 8 9 //总运行内存大小,并且格式化 10 long totalSpace = ProcessInfoProvider.getTotalSpace(this); 11 mStrTotalSpace = Formatter.formatFileSize(this, totalSpace); 12 13 tv_memory_info.setText("剩余/总共:"+strAvailSpace+"/"+mStrTotalSpace); 14 } 15 16 private void initUI() { 17 tv_process_count = (TextView) findViewById(R.id.tv_process_count); 18 tv_memory_info = (TextView) findViewById(R.id.tv_memory_info); 19 20 tv_des = (TextView) findViewById(R.id.tv_des); 21 22 lv_process_list = (ListView) findViewById(R.id.lv_process_list); 23 24 bt_select_all = (Button) findViewById(R.id.bt_select_all); 25 bt_select_reverse = (Button) findViewById(R.id.bt_select_reverse); 26 bt_clear = (Button) findViewById(R.id.bt_clear); 27 bt_setting = (Button) findViewById(R.id.bt_setting); 28 29 bt_select_all.setOnClickListener(this); 30 bt_select_reverse.setOnClickListener(this); 31 bt_clear.setOnClickListener(this); 32 bt_setting.setOnClickListener(this); 33 }
【效果】

3.6 进程管理界面处理
【数据的获取】

【消息机制】

【适配器的修改】



【布局修改】在每个条目的右侧具有checkBox选择框;





【控件中的信息的填充】




【checkBox的控件的设置】本应用的的checkBox是不能被选中进行操作的;

【完善】



【效果】

4. 进程管理界面常驻悬浮框
【悬浮窗】需要使用帧布局,将要悬浮的文本TextView放置在ListView的上方层叠;
【布局的修改】增加悬浮窗文本;


【文本内容的设置】

【监听】


【效果】

5 单选框屏蔽bug



【效果】

6 单选框的状态的切换


【效果】

7.全选&反选操作
7.1 全选的效果


【效果】

7.2 反选的效果


【效果】

8.一键清理
8.1 一键清理的功能效果
【说明】会报杀死多少进程,清理了多少空间;
8.2 功能的完成

【注意】现在循环的查询集合,但是还在不停的删除集合中的元素,这种操作对于集合是不安全的;

【解决办法】在创建一个list,专门用于记录需要杀死的进程;


【目前的效果】集合中的数据删除没有问题,界面也可以更新;目前还没有真正的将进程杀死;

【杀死进程】





【杀死进程的动作的信息的报告】
【说明】被杀死的进程,其实只限于可以被杀死的进程,重要的系统进程是无法被删除的;
【方法1】



【方法2】第二种显示的方式


9. 设置按钮功能完善
9.1 功能及效果
【说明】
【1】显示隐藏系统进程功能;

【2】锁屏清理功能:在锁屏的时候会杀死系统中的一些进程;

9.2 隐藏显示系统进程
【页面的跳转】


【跳转的页面】

【设置的布局】


1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 <TextView 7 android:text="进程设置" 8 style="@style/TitleStyle"/> 9 <CheckBox 10 android:id="@+id/cb_show_system" 11 android:text="隐藏系统进程" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content"/> 14 <CheckBox 15 android:id="@+id/cb_lock_clear" 16 android:text="锁屏清理已关闭" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content"/> 19 20 </LinearLayout>




【效果】

【隐藏系统条目功能完善源码】是否显示/隐藏系统的进程,只需要更改返回的条目的数据即可;

【方法触发被调用的时机】
在开启设置界面的时候,调用startActivityForResult()等待新的页面返回消息;
然后在刷新之后的页面调用onResult()方法,刷新页面的数据;



【效果】完成了显示隐藏进程的效果;

9.3 锁屏清理功能
【说明】锁屏清理的功能是在屏幕关闭之后执行的功能,因此需要放在服务中执行,可以在后台运行;
需要将服务和状态进行绑定




【说明】找到checkBox的控件的状态,然后选择开启还是关闭服务;


【服务的创建】


【杀死所有进程的方法】

【广播接收者的注册和注销】

【测试效果】首先需要勾选锁屏设置的checkBox 然后再锁屏;
【完善】需要根据服务是否开启,决定是否选中单选框;

【bug】checkBox的选择框无法选择设置

【原因】存在空格

【修改之后的效果】

浙公网安备 33010602011771号