2012-03-21 49 views

回答

25

我再次回答的时间太晚了,但由于我今天在相同的情况下运行,我想分享我的发现以帮助某人。

首先你需要了解你可以什么不是。从Android的角度来看,应用程序不像其他操作系统。一个Android应用程序由包装在一个包中的许多组件(活动,广播接收器,服务,最重要的任务等)组成。一个程序包可以有多个运行的进程,具体取决于其运行的组件。

现在最有趣的部分是一个Android软件包没有(由Android)杀死停止如果过程中的任何或全部杀死,其实包仍可甚至没有任何进程在运行考虑一直运行。你可以看到这个效果,如果你开始的仿真器,启动程序(IE浏览器),然后通过DDMS杀死它的进程,之后去到应用程序的包设置(Settings --> Applications --> Manage Applications --> All --> Browser),你可以看到启用强制停止按钮,这意味着应用程序仍在运行(从Android的角度来看)。这里发生的事情是,应用程序有一个或多个任务冷冻。也就是说,Android已经保存了应用程序活动(任务或任务)的状态,所以如果用户返回,那么程序包仍然运行或更好,他将着陆他正在做的最后一件事。现在,如果你点击强制停止按钮,Android将放弃所有的这些冷冻任务,当用户返回到应用程序,他会看到的第一个活动。 A 任务只有用户(从强制停止按钮)不能杀死(从froyo),系统或与系统的相同密钥签名的第三方应用程序可以做到这一点(也可能是根有能力的应用程序,但我没有证实这一点)。在另一方面一个过程是你可以杀死,并收回其占用的内存,只要你遵循一些限制:

  1. 你有android.permission.KILL_BACKGROUND_PROCESSES权限。
  2. 进程不是系统或根进程。
  3. 该进程不属于持久性组件。
  4. 该过程对于系统以任何其他方式操作都不是关键。

除了第一条规则,您不必对它们做些什么,Android会照顾到这一点。

ActivityManager有一个方便的功能,你可以用它来杀死一个包一次完成的所有进程。当你调用它时,Android会杀死任何可以被杀死的进程,从而释放一些内存。然而,这个包的任务状态将被保存,当用户返回到应用程序时,他会看到他所做的最后一件事情,除非系统本身已经杀死了他们。这可能是因为它需要资源或状态很久以前被保存(大约30分钟)。副作用是因为用户认为所有的应用程序都像桌面操作系统,他们不相信应用程序真的关闭了,但这是android的生活。

现在编码:

对于我的项目,我准备了三个功能来实现这个功能。

第一个查找包中可能包含的第一个进程pid,如果没有,则返回-1。

private Context cx; 
private ActivityManager am = (ActivityManager) cx.getSystemService(Context.ACTIVITY_SERVICE); 

public int findPIDbyPackageName(String packagename) { 
    int result = -1; 

    if (am != null) { 
     for (RunningAppProcessInfo pi : am.getRunningAppProcesses()){ 
      if (pi.processName.equalsIgnoreCase(packagename)) { 
       result = pi.pid; 
      } 
      if (result != -1) break; 
     } 
    } else { 
     result = -1; 
    } 

    return result; 
} 

第二个做一些愚蠢的事,但我需要它为我的项目。

public boolean isPackageRunning(String packagename) { 
    return findPIDbyPackageName(packagename) != -1; 
} 

第三个工作。

public boolean killPackageProcesses(String packagename) { 
    boolean result = false; 

    if (am != null) { 
     am.killBackgroundProcesses(packagename); 
     result = !isPackageRunning(packagename); 
    } else { 
     result = false; 
    } 

    return result; 
} 

他们证实API 15与仿真器API 8,9和实际设备(银河S2)上工作,他们尽杀任何应用程序的进程(不仅仅是你自己的),只要他们不需要。

现在谈谈android.os.Process.killProcess文档其中指出:

...通常,这意味着只有进程中运行呼叫者的包/应用程序,通过该应用程序创建的任何额外的过程; ...

我相信“运行呼叫者的包/应用程序的进程”意味着家庭启动应用程序而不是在你自己的应用程序。您的应用程序是调用者,并且运行调用者程序包/应用程序的进程是家庭启动器或任何其他应用程序启动您的应用程序。这是我解释killBackgroundProcesses函数和android.os.Process.killProcess函数确实可用于第三方应用程序的唯一方法。

+0

谢谢你的完整答案! – 2012-05-07 07:24:36

+0

绝妙的解释.. – 2014-12-19 19:57:38

1

站在DOC:

杀死与所述给定PID的过程。请注意,虽然此API允许我们根据其PID来请求终止任何进程,但内核仍会对您确实能够杀死的PID施加标准限制。通常这意味着只有运行调用者的程序包/应用程序以及由该应用程序创建的任何其他进程的进程;共享一个通用UID的软件包也能够杀死对方的进程。

,所以你可以杀死自己的进程..

看到Process文档。我试图运行adb shell kill pid,但它需要超级用户权限

+0

我知道我可以杀死我自己的进程,我的问题是如何杀死外部进程。 – 2012-03-21 13:22:43

+1

据我所知,你不能,如果你没有权利杀死那个过程 – Blackbelt 2012-03-21 13:25:14

+0

是<如何杀死外国进程?<< – Criss 2015-03-30 09:16:56