Android开发——查询/杀死手机里正在运行的进程

时间:2021-11-09 05:01:39

0. 前言

以前有同学好像做过一个叫“自习君”的App,开启后自动检测用户这一天的自习时间,在学校里宣传广告还打了不少。其实实现原理非常简单,在SQlite数据库(也可以通过文件)先预置众多应用的PackageName,比如QQ,微信等等,然后开启一个线程,不间断的获取到手机里的所有进程信息,如果检测到其中有processInfo.processName和预置的某个应用的PackageName相同,那么就认定为用户没有在“认真学习”,最后通过网络把数据上传到服务器,加上基于好友功能的“学霸时间”排行榜,最后集成社会化SDK的分享功能,这个App就完成了。

PS:其实很多功能从技术角度来看,真的很简单。做应用还得看创意点,从这个角度来看的话,有些产品经理做的事情,并不是一个开发者那么容易就可以替代的。(*^__^*)  

最后吐槽一下上面的应用,因为它必定是耗电的,检测进程的子进程必定是频繁进行的(至少是一秒检测一次),不过用这个应用的学霸估计也不怎么玩手机,所以那点耗电估计也不会被在意吧。⊙﹏⊙‖∣

废话不多说,介绍本文的主要内容。本文原创,转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/51930645


1. 获取手机里的所有进程信息

以前写过一个ProcessInfoProviderUtil工具类,拿出来分享一个。通过Context.ACTIVITY_SERVICEPagerManager不仅可以获取上面APP所需的进程名(也是PackageName),判断此进程是否为系统进程,还可以获取到该进程所占用的内存大小应用名称以及应用图标代码如下。其中ProcessInfo为自定义的业务类,成员变量即为要获取的信息,加上set/get方法即可。

/** * For Info of Process
* Created by Calvin on 2016/4/24.
*/
public class ProcessInfoProviderUtil {
public static List<ProcessInfo> getProcessInfos(Context context){
//创造要返回的集合
List<ProcessInfo> list = new ArrayList<ProcessInfo>();
PackageManager pm = (PackageManager)context.getPackageManager();

//拿到手机里的所有进程信息
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();
for(ActivityManager.RunningAppProcessInfo processInfo : runningAppProcesses) {

//要添加的对象
ProcessInfo info = new ProcessInfo();
//包名即为进程名字
String packageName = processInfo.processName;
info.setPackageName(packageName);
//以进程号为参数,获得进程的信息(内存占用的大小)
//使用时通过Formatter.formatFileSize(this,SystemProcessUitl.getAvaMemory(this))转换为MB即可
Debug.MemoryInfo[] processMemoryInfo = am.getProcessMemoryInfo(new int[]{processInfo.pid});
long totalPrivateDirty = processMemoryInfo[0].getTotalPrivateDirty()*1024l;
info.setSize(totalPrivateDirty);
//应用名字和图标
ApplicationInfo applicationInfo = null;
try {
applicationInfo = pm.getApplicationInfo(packageName, 0);
String name = applicationInfo.loadLabel(pm).toString();
info.setName(name);
Drawable icon = applicationInfo.loadIcon(pm);
info.setIcon(icon);
if ( (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)== 0 ){
//用户进程
info.setUesrProcess(true);
}else {
//系统进程
info.setUesrProcess(false);
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if(info.getName()!=null) {
list.add(info);
}
}
return list;
}
}


2. 杀死指定的进程

杀死进程很简单。其实就是调用ActivityManager的killBackgroundProcesses方法,这里我做了一个优化,即监听锁屏广播,在服务里创建内部广播接收者,锁屏后即循环杀死所有的进程。实现代码如下。当然,系统进程是不会被杀死的。这样就做到了一点省电优化。当然,自己需要的,即便是锁屏也想保持运行的后台进程,可以自定义一个集合维护需要被保护的进程,杀死之前自行判断即可。

/** * Service used to kill all user process when lock the phone * Created by user on 2016/4/26. */public class AutoCleanService extends Service {    private  ScreenOffReceiver screenOffReceiver;    private ActivityManager am;    @Nullable    @Override    public IBinder onBind(Intent intent) {        return null;    }    @Override    public void onCreate() {        am =(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);        screenOffReceiver = new ScreenOffReceiver();        registerReceiver(screenOffReceiver,new IntentFilter(Intent.ACTION_SCREEN_OFF));        super.onCreate();    }    @Override    public void onDestroy() {        unregisterReceiver(screenOffReceiver);        screenOffReceiver = null;        super.onDestroy();    }    private  class ScreenOffReceiver extends BroadcastReceiver{        @Override        public void onReceive(Context context, Intent intent) {            List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();            for (ActivityManager.RunningAppProcessInfo info : runningAppProcesses){                //进程名字  即为包名                String processName = info.processName;                //杀掉可以杀的                am.killBackgroundProcesses(processName);            }        }    }}

Android开发——查询/杀死手机里正在运行的进程