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(); } } } 

 

    原文作者:brave-sailor
    原文地址: https://www.cnblogs.com/Free-Thinker/p/4580617.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞