写在前面:
进入手机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();
}
}
}

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

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

    killall killall可以根据名字来杀死进程,它会给指定名字的所有进程发送信息.如果没有指定信号名,则发送SIGTERM.信号可以通过名称(例如-HUP或-SIGHUP)或数字(例如-1)或选 ...

  2. Linux基础命令---杀死进程pkill

    pkill pkill可以给指定的进程发送信息,它可以结束某个执行的进程或者目录登录的用户. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedo ...

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

    [NodeJs] 1.安装 http://nodejs.cn/download/ 2.安装过程省略(因为已经安装过了) 和平时安装软件没区别 3.配置环境 计算机--->属性-->高级系统 ...

  4. MAC OSX在视图port哪个程序占用,杀死进程的方法

    sudo lsof -i :9000 COMMAND   PID    USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME java    6 ...

  5. android基础---->IntentService的使用

    这一篇博客,我们开始前台服务与IntentServie源码分析的学习,关于service的生命周期及其简单使用,请参见我的博客:(android基础---->service的生命周期) 目录导航 ...

  6. linux / OS 杀死进程

    1,查询端口 sudo netstat -apn | grep 端口号 2,杀死进程kill -9 应用程序进程id

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

     场景:实现安装一个apk应用程序的过程.界面如下: 编写如下应用,应用结构如下: <RelativeLayout   编写activity_main.xml布局: <Relative ...

  8. Android杀死进程方法

    1. android.os.Process.killProcess(pid) 只能终止本程序的进程,无法终止其它的 具体代码如下: ?12 Process.killProcess(Process.my ...

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

    0. 前言 以前有同学好像做过一个叫"自习君"的App,开启后自动检测用户这一天的自习时间,在学校里宣传广告还打了不少.其实实现原理非常简单,在SQlite数据库(也可以通过文件) ...

随机推荐

  1. HDU 1848 Fibonacci again and again

    题解:尼姆博弈,对于1至1000计算SG函数,每次取最小的前继值,SG值异或为0则为P-position. #include <cstdio> #include <cstring&g ...

  2. c++复习(未完待续)

    1.使函数不能在定义该函数的文件之外访问的方法: (1)声明函数为static(2)将函数放到无名名字空间中 namespace { void g() { ......... } }

  3. C# Webservice

    c#webservice的简单示例   webservice传递的数据只能是序列化的数据,典型的就是xml数据. 下面以一个简单例子为例: (一)新建——-项目---Visual C#---web-- ...

  4. leetcode208 happynumber

    19 is a happy number 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1 class Solution {public ...

  5. BZOJ 3907: 网格( 组合数 + 高精度 )

    (0,0)->(n,m)方案数为C(n,n+m), 然后减去不合法的方案. 作(n,m)关于y=x+1的对称点(m-1,n+1), 则(0,0)->(m-1,n+1)的任意一条路径都对应( ...

  6. C# Programming Study #2

    readonly (C# Reference) readonly  关键字是可以在字段上使用的修饰符.  当字段声明包括 readonly 修饰符时,该声明引入的字段赋值只能作为声明的一部分出现,或者 ...

  7. Apache的Mod_rewrite学习(RewriteRule重写规则的语法)

    URL:http://www.tenwe.com/tech/web/server/200705/content_1548.shtml 今天学习重写规则的语法.RewriteRuleSyntax: Re ...

  8. sun.proxy.$Proxy0 cannot be cast to dao.impl.MyAdviceImpl

    ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");       ...

  9. 转: requirejs中文api (详细)

    RequireJS的目标是鼓励代码的模块化,它使用了不同于传统<script>标签的脚本加载步骤.可以用它来加速.优化代码,但其主要目的还是为了代码的模块化.它鼓励在使用脚本时以modul ...

  10. Code 16K 码

    Code 16K 码是一种多层.连续型.可变长度的条码符号,可以表示全ASCII字符集的128个字符及扩展ASCII字符.它采用UPC及Code128字符.一个16层的Code 16K符号,可以表示7 ...