Android基础【1】杀死进程(强行停止)应用程序的方法

写在前面:
进入手机ODM已经很久,经历过几个项目项目下来,对高通、展讯、Marvell平台都进行了接触,对于我个人来说,参与手机系统项目的开发与维护,最明显的好处是可以深入的了解某一功能的具体实现过程,以及Android的设计框架,能够以框架的思维去修改代码添加功能。入行这么久,越来越觉得有必要将自己在实际工作过程中看到的,领悟到的一些东西能够记忆下来,并分享出来。
        从这篇开始我将会筛选出一些常用功能在Google源码中的标准方法与大家一起分享,对于我个人来讲,比较喜欢按照源码中已经存在了的标准方法去coding。

首先共享的是 杀死进程的方法, 一般手机管家类应用最基本的就是清理进程的功能。其实这个功能在源码里面来看是很简单的,主要有两步骤:1.获取正在运行的进程列表;2.根据packageName选择怎样去杀掉。

2015.05.06 更新一种方法,利用反射机制调用ActivityManagerService::forceStopPackage来杀掉进程(适用于usr组,但仍然不一定成功)。

这部分的功能主要参考了
    1. 设置--应用--正在运行--停止所有进程
    2. 任意界面--长按Home--清理最近进程

设置中获取所用应用程序的做法:
主要使用PackageManager::getInstalledApplications(int flags){} 方法
[java] view plaincopy
final int mRetrieveFlags;  

List<ApplicationInfo> mApplications = new ArrayList<ApplicationInfo>();  

        // Only the owner can see all apps.
        if (UserHandle.myUserId() == 0) {
            mRetrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES |
                    PackageManager.GET_DISABLED_COMPONENTS |
                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
        } else {
            mRetrieveFlags = PackageManager.GET_DISABLED_COMPONENTS |
                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
        }
        // 获取系统中的所有包
        <strong>mApplications = mPm.getInstalledApplications(mRetrieveFlags);</strong>
        if (mApplications == null) {
            mApplications = new ArrayList<ApplicationInfo>();
        }  

        for (int i=0; i<mApplications.size(); i++) {
            final ApplicationInfo info = mApplications.get(i);
            // Need to trim out any applications that are disabled by
            // something different than the user.
            if (!info.enabled) { //此处很有必要,获取未被禁止的且允许被操作的包
                if (info.enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
                    mApplications.remove(i);
                    i--;
                    continue;
                }
                mHaveDisabledApps = true;
            }
        }  

标准方法获取正在运行的进程:
主要使用ActivityManagerService::getRunningAppProcesses(){} 方法
[java] view plaincopy
// Temporary structure used when updating above information.
final SparseArray<AppProcessInfo> mTmpAppProcesses = new SparseArray<AppProcessInfo>();  

    // Retrieve list of running processes, organizing them into a sparse
    // array for easy retrieval.
    List<ActivityManager.RunningAppProcessInfo> processes
            = am.getRunningAppProcesses(); // 获取正在运行的进程
    final int NP = processes != null ? processes.size() : 0;
    mTmpAppProcesses.clear();
    for (int i=0; i<NP; i++) {
        ActivityManager.RunningAppProcessInfo pi = processes.get(i);
        mTmpAppProcesses.put(pi.pid, new AppProcessInfo(pi));
    }  

杀死正在运行进程的方法:

适合api LEVEL <= 7
权限 android.permission.RESTART_PACKAGE
[java] view plaincopy
private void killPackage(String pkgName) {
    ActivityManager am = (ActivityManager)getActivity().getSystemService(
            Context.ACTIVITY_SERVICE);
    am.restartPackage(pkgName);  

}  

适合api LEVEL >=8
权限 android.permission.KILL_BACKGORUND_PROCESSES
[java] view plaincopy
private void killPackage(String pkgName) {
    ActivityManager am = (ActivityManager)getActivity().getSystemService(
            Context.ACTIVITY_SERVICE);
    am.killBackgroundProcesses(pkgName);  

}  

设置--应用--详细--强制停止:
对于非System组进程,无法调用ActivityManager::forceStopPackage(String){}方法,只能尝试使用ActivityManagerService::forceStopPackage(final String packageName, int userId) 并且不一定能成功,设置中的逻辑大致如下:

[java] view plaincopy
private DevicePolicyManager mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);  

private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        updateForceStopButton(getResultCode() != Activity.RESULT_CANCELED);
    }
};  

private void updateForceStopButton(boolean enabled) {
    mForceStopButton.setEnabled(enabled);
    mForceStopButton.setOnClickListener(InstalledAppDetails.this);
}  

private void checkForceStop() {
    if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
        // User can‘t force stop device admin.
        updateForceStopButton(false);
    } else if ((mAppEntry.info.flags&ApplicationInfo.FLAG_STOPPED) == 0) {
        // If the app isn‘t explicitly stopped, then always show the
        // force stop button.
        updateForceStopButton(true);
    } else {
        Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
                Uri.fromParts("package", mAppEntry.info.packageName, null));
        intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppEntry.info.packageName });
        intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid);
        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mAppEntry.info.uid));
        getActivity().sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
                mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null);
    }
}
[java] view plaincopy
private void forceStopPackage(String pkgName) {
    ActivityManager am = (ActivityManager)getActivity().getSystemService(
            Context.ACTIVITY_SERVICE);
    am.forceStopPackage(pkgName); // 不一定成功
    mState.invalidatePackage(pkgName); // 强制停止后重新获取一下包信息
    ApplicationsState.AppEntry newEnt = mState.getEntry(pkgName);
    if (newEnt != null) {
        mAppEntry = newEnt;
    }
    checkForceStop(); // 最后检验是否强停成功(体现在“强行停止”按钮是否置灰)
}  

在调试过程中,强行停止某一进程的方法是:
adb shell  am force-stop <package>
比如: am force-stop com.android.launcher

另外 am kill <package> 安全模式下杀死进程,不影响体验

附:
am force-stop: force stop everything associated with <PACKAGE>.

    --user <USER_ID> | all | current: Specify user to force stop;

        all users if not specified.

am kill: Kill all processes associated with <PACKAGE>.  Only kills.

  processes that are safe to kill -- that is, will not impact the user

  experience.

    --user <USER_ID> | all | current: Specify user whose processes to kill;

        all users if not specified.

am kill-all: Kill all background processes.

第三种方法:
        通过反射机制,杀死进程

[java] view plaincopy
package com.example.androidtest;  

import android.app.ActivityManager;
import android.content.Context;  

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;  

/**
 * 通过Java的反射机制强制杀死进程
 * @author hanhao
 *
 */
public class ForceKillProgress {  

    public static void forceStopProgress(Context context, String pkgName) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);  

        try {
            Method forceStopPackage = am.getClass().getDeclaredMethod("forceStopPackage", String.class);
            forceStopPackage.setAccessible(true);
            forceStopPackage.invoke(am, pkgName);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
} 
时间: 2024-10-10 04:45:58

Android基础【1】杀死进程(强行停止)应用程序的方法的相关文章

Linux基础命令---杀死进程killall

killall killall可以根据名字来杀死进程,它会给指定名字的所有进程发送信息.如果没有指定信号名,则发送SIGTERM.信号可以通过名称(例如-HUP或-SIGHUP)或数字(例如-1)或选项-s来指定.如果命令名不是正则表达式(选项-r),并且包含斜杠(/),则将选择执行该特定文件的进程,与其名称无关.如果每个列出的命令至少有一个进程被杀死,或者没有列出命令,并且至少有一个进程符合-u和-Z搜索条件,则KILLALL返回一个零返回代码.否则KILLALL返回非零.KILLALL进程永

Sublime Text3配置及控制台乱码[cmd杀死进程乱码/编译文件乱码]解决方法

[NodeJs] 1.安装 http://nodejs.cn/download/ 2.安装过程省略(因为已经安装过了) 和平时安装软件没区别 3.配置环境 计算机--->属性-->高级系统设置-->环境变量-->path-->编辑 每一个变量值和前一个变量值用;隔开将D:\Program Files\nodejs\node.exe;写入 4.打开cmd 输入node -v  和 npm -v 看是否安装成功 [Sublime Nodejs] 1.安装nodejs插件 http

[Android Pro] android 杀死进程的方法

1: 杀死自己进程的方法 android.os.Process.killProcess(Process.myPid()); 2:杀死别人进程的方法(不能杀死自己) -------a: activityManager.killBackgroundProcesses ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); activityManager.killBa

20_Android中apk安装器,通过WebView来load进一个页面,Android通知,程序退出自动杀死进程,通过输入包名的方式杀死进程

?? 场景:实现安装一个apk应用程序的过程.界面如下: 编写如下应用,应用结构如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_heigh

android中杀死进程的方法

第一种方法:这个方法只能自杀,不能杀死其他进程~ /**************************************************** *            杀死进程的第一种方法                   * *                                                   * ****************************************************/ int myPid = android

Android基础——Messenger在跨进程通信中的使用

Messenger在跨进程通信中的使用 事先说明: 本人也是个初学者,所以本文是从初学者的角度入手,如果有不妥的地方请留言教导我,谢谢. 本篇文章主要针对讲解Messenger的使用和Messenger在应用层上的原理解析和Messenger在服务端的回复. 什么是Messenger? Messenger可以翻译为信使,Messenger是一种轻量级的IPC方案,通过它可以在不同进程中传递Message对象,在Message中放入我们需要传递的数据,就可以实现数据的进程间传递了. 步骤一:Mes

Android使用Messenger实现进程间双向通信

在了解本文即将学到的技能外,有些知识还是有必要提前知道的,这样才会更容易理解本文即将讲到的知识点.需要提前预热的知识点: 1.Android四大组件之一Service,要知道怎样去写一个Service,Service有哪两种启动方式: 2.Android Service启动方式之Bound Service: 3.Android基础知识之Messenger: 掌握了这三个知识点,就可以快速入手使用Messenger进行进程间通信了. 一.知识点回顾之Service 我们来看看官方文档关于对Serv

Android 面试题总结之Android 基础(四)

Android 面试题总结之Android 基础Service(四) 在上一章节Android 面试题总结之Android 基础Broadcast Receiver(三) 我们讲了Broadcast Receiver基础知识.本节主要讲解Service相关基础知识,Service也是我们开发过程中经常使用到. 在阅读过程中有任何问题,请及时联系.如需转载请注明 fuchenxuan de Blog 本章系<Android 之美 从0到1 – 高手之路>Android基础Service 总结了A

Android基础入门教程——4.2.2 Service进阶

Android基础入门教程--4.2.2 Service进阶 标签(空格分隔): Android基础入门教程 本节引言 上节我们学习了Service的生命周期,以及两种启动Service的两种方法, 本节继续来深入了解Service中的IntentService,Service的使用实例: 前台服务与轮询的实现! 1.IntentService的使用 在上一节后我们已经知道了如何去定义和启动Service,但是如果我们直接把 耗时线程放到Service中的onStart()方法中,虽然可以这样做