1.当前设备进程分类

进程优先级从高到低可分为四种:前台进程可视进程服务进程缓存进程

前台进程(foreground process)用户当前正在进行可操作的,一般满足以下条件:

(1).屏幕顶层运行Activity(处于onResume()状态),用户正与之交互。

(2).有BroadcastReceiver正在执行代码。

(3).有Service在其回调方法(onCreate()、onStart()、onDestroy())中正在执行代码。

可视进程(visible process):做用户当前意识到的工作。一般满足以下条件:

(1).屏幕上显示Activity,但不可操作(处于onPause()状态)。

(2).有service通过调用Service.startForeground(),作为一个前台服务运行。

(3).含有用户意识到的特定的服务,如动态壁纸、输入法等 

服务进程(service process):含有以startService()方法启动的service。虽然该进程用户不直接可见,

但是它们一般做一些用户关注的事情(如数据的上传与下载)。这些进程一般不会杀死,除非系统内存不足以

保持前台进程和可视进程的运行。 对于长时间运行的service(如30分钟以上),系统会考虑将之降级为缓存进程,

避免长时间运行导致内存泄漏或其他问题,占用过多RAM以至于系统无法分配充足资源给缓存进程。

缓存/后台进程(cached/background process):一般来说包含以下条件:

(1). 包含多个Activity实例,但是都不可见(处于onStop()且已返回)。 
系统如有内存需要,可随意杀死。

2.android SDK版本20以下获取当前进程

在android5.0即sdk20以下,获取当前进程需要在注册权限,权限为:

android.Manifest.permission.GET_TASKS
获取之前先判断权限是否已注册:

/** * 检查当前应用是否有指定的权限 *  * @param context * @param permName *            --权限 * @return true--有, false--没有 */public static boolean checkPermission(Context context, String permName) {PackageManager pm = context.getPackageManager();if (PackageManager.PERMISSION_GRANTED == pm.checkPermission(permName, context.getPackageName())) {return true;}return false;}
最后获取当前进程包名:

/** * 获取当用户在试用的应用包名,适用于5.0以下 *  * @param context * @return */public static String getRunningTask(Context context) {ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);List taskInfos = am.getRunningTasks(1);if (taskInfos != null && taskInfos.size() > 0) {ComponentName cn = taskInfos.get(0).topActivity;return cn.getPackageName();}return "";}

在android5.0即sdk20以上(包含20),要获取当前设备进程,用常规方式只能获取自身应用,若自身应用不是前台进程,者获取不到其他进程包名。以下方式是通过读取系统进程底层文件来获取当前进程包名。

/** * 获取当用户在试用的应用包名,适用于5.0以上 *  * @return */public static String getForegroundApp(Context context) {File[] files = new File("/proc").listFiles();int lowestOomScore = Integer.MAX_VALUE;String foregroundProcess = null;for (File file : files) {if (!file.isDirectory()) {continue;}int pid;try {pid = Integer.parseInt(file.getName());} catch (NumberFormatException e) {continue;}try {String cgroup = read(String.format("/proc/%d/cgroup", pid));String[] lines = cgroup.split("\n");String cpuSubsystem;String cpuaccctSubsystem;if (lines.length == 2) {// 有的手机里cgroup包含2行或者3行,我们取cpu和cpuacct两行数据cpuSubsystem = lines[0];cpuaccctSubsystem = lines[1];} else if (lines.length == 3) {cpuSubsystem = lines[0];cpuaccctSubsystem = lines[2];} else if (lines.length == 5) {cpuSubsystem = lines[2];cpuaccctSubsystem = lines[4];} else {continue;}if (!cpuaccctSubsystem.endsWith(Integer.toString(pid))) {continue;}if (cpuSubsystem.endsWith("bg_non_interactive")) {continue;}String cmdline = read(String.format("/proc/%d/cmdline", pid));if (isContainsFilter(cmdline)) {continue;}int uid = Integer.parseInt(cpuaccctSubsystem.split(":")[2].split("/")[1].replace("uid_", ""));if (uid >= 1000 && uid <= 1038) {continue;}int appId = uid - AID_APP;while (appId > AID_USER) {appId -= AID_USER;}if (appId < 0) {continue;}File oomScoreAdj = new File(String.format("/proc/%d/oom_score_adj", pid));if (oomScoreAdj.canRead()) {int oomAdj = Integer.parseInt(read(oomScoreAdj.getAbsolutePath()));if (oomAdj != 0) {continue;}}int oomscore = Integer.parseInt(read(String.format("/proc/%d/oom_score", pid)));if (oomscore < lowestOomScore) {lowestOomScore = oomscore;foregroundProcess = cmdline;}if (foregroundProcess == null) {return null;}int indexOf = foregroundProcess.indexOf(":");if (indexOf != -1) {foregroundProcess = foregroundProcess.substring(0, indexOf);}} catch (NumberFormatException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}return foregroundProcess;}private static String read(String path) throws IOException {StringBuilder output = new StringBuilder();BufferedReader reader = new BufferedReader(new FileReader(path));output.append(reader.readLine());for (String line = reader.readLine(); line != null; line = reader.readLine()) {output.append('\n').append(line);}reader.close();return output.toString().trim();// 不调用trim(),包名后会带有乱码}
有一些应用是常驻应用包名,添加过滤方法:

/** * filter包名过滤 *  * @param cmdline * @return */public static boolean isContainsFilter(String cmdline) {boolean flag = false;if (filterMap == null || filterMap.isEmpty() || filterMap.size() == 0) {initFliter();}if (filterMap != null) {for (String key : filterMap.keySet()) {if (cmdline.contains(key)) {flag = true;break;}}}return flag;}
下面方法是判断是否为第三方应用,并且有界面的应用:

/** * 判断是否为第三方应用,并且有界面的应用 *  * @param context * @param packageName * @return true:第三方应用,并且有界面 */public static boolean isUserApp(Context context, String packageName) {List names = new ArrayList();PackageManager packageManager = context.getPackageManager();Intent intent = new Intent(Intent.ACTION_MAIN);intent.addCategory(Intent.CATEGORY_HOME);List list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);//for (ResolveInfo resolveInfo : list) {names.add(resolveInfo.activityInfo.packageName);}if (!names.contains(packageName)) {if (packageManager.getLaunchIntentForPackage(packageName) != null) {return true;}}return false;}
下面方法是判断是否为桌面应用:

/** * 是否为桌面应用 *  * @param context * @param packageName * @return */public static boolean isLauncherApp(Context context, String packageName) {List names = new ArrayList();PackageManager packageManager = context.getPackageManager();Intent intent = new Intent(Intent.ACTION_MAIN);intent.addCategory(Intent.CATEGORY_HOME);List list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);//for (ResolveInfo resolveInfo : list) {names.add(resolveInfo.activityInfo.packageName);}if (names.contains(packageName)) {return true;}return false;}
有一些第三方常驻顶层应用,可以在初始化的时候添加进去,比如:
/** * 初始化filter */public static void initFliter() {if (filterMap == null) {filterMap = new HashMap();}if (filterMap.isEmpty() || filterMap.size() == 0) {filterMap.put("com.android.systemui", 0);filterMap.put("com.aliyun.ams.assistantservice", 0);filterMap.put("com.meizu.cloud", 0);filterMap.put("com.android.incallui", 0);filterMap.put("com.amap.android.location", 0);filterMap.put("com.android.providers.contacts", 0);filterMap.put("com.samsung.android.providers.context", 0);filterMap.put("com.android.dialer", 0);filterMap.put("com.waves.maxxservice", 0);filterMap.put("com.lge.camera", 0);filterMap.put("se.dirac.acs", 0);filterMap.put("/", 0);}}
转载请说明出处: http://blog.csdn.net/u012438830/article/details/78526152
下面是本人的具体代码事例代码,需要的到请下载
点击打开链接







更多相关文章

  1. Android(三):远程Service基本操作
  2. Android(安卓)8.0 系统启动流程之init进程--第二阶段(五)
  3. android多进程深入分析
  4. Android学习系列(7)--App消息通知机制
  5. Activity的启动流程分析
  6. 《Android开发艺术探索》读书笔记 (2) 第2章 IPC机制
  7. Android(安卓)9.0及以上版本中,关于多进程问题对于WebView的影响
  8. android学习和广告平台赚钱
  9. Android(安卓)8.1 开机流程分析(1)

随机推荐

  1. Android(安卓)7.0调用系统相机返回路径问
  2. Android监听Dialog点击外部区域
  3. Android输入框中提示自动输入内容
  4. 禁止状态栏下拉
  5. android 背光控制 HAL层分析
  6. Android(安卓)intent 传递数组对象序列化
  7. Android(安卓)文件打开方式
  8. android 首页fragment切换
  9. 更换工程的sdk或者google apis
  10. Android(安卓)Activity设置全屏