如何模拟Android杀死我的进程

Dav*_*ser 164 android

如果进程在后台并且操作系统决定它需要资源(RAM,CPU等),Android将终止进程.我需要能够在测试期间模拟这种行为,以便我可以确保我的应用程序正常运行.我希望能够以自动方式执行此操作,以便我可以测试应用程序在发生这种情况时是否正常运行,这意味着我必须在每个活动中对此进行测试等.

我知道如何杀死我的进程.那不是问题.问题是,当我杀死我的过程(使用DDMS, ,adb shell kill,Process.killProcess()等)的Android不重新启动它以同样的方式,它将如果Android操作系统杀死了它本身.

如果Android操作系统终止进程(由于资源要求),当用户返回应用程序时,Android将重新创建该进程,然后在活动堆栈上重新创建顶级活动(调用onCreate()).

另一方面,如果终止进程,Android会假定活动堆栈顶部的活动表现不佳,因此它会自动重新创建进程,然后从活动堆栈中删除顶级活动并重新创建下面的活动顶级活动(调用onCreate()`).这不是我想要的行为.我想要与Android杀死进程时相同的行为.

只是用图解来解释,如果我的活动堆栈看起来像这样:

    ActivityA -> ActivityB -> ActivityC -> ActivityD
Run Code Online (Sandbox Code Playgroud)

如果Android终止进程并且用户返回应用程序,Android将重新创建该进程并创建ActivityD.

如果我终止该过程,Android将重新创建该过程并创建ActivityC.

Mar*_*ark 116

为我测试这个的最好方法是这样做:

  • 在您的应用程序中打开ActivityD
  • 按主页按钮
  • 在应用程序的DDMS中按停止(这将终止应用程序进程)
  • 使用Home长按或打开的应用程序返回应用程序(取决于设备)
  • 应用程序将在重新创建的ActivityD中启动(ActivityA,ActivityB,ActivityC已经死亡,当你回到它们时将重新创建)

在某些设备上,您还可以使用应用程序 - >您的启动器图标返回应用程序(ActivityD),但在其他设备上,它将启动ActivityA.

这就是Android文档所说的:

通常,当用户从主屏幕重新选择该任务时,系统会在某些情况下清除任务(从根活动上方的堆栈中删除所有活动).通常,如果用户未访问任务一段时间(例如30分钟),则完成此操作.

  • 这不是自动化的,但它完全符合我的目的.不要跳过**第2步**非常重要.您必须先将应用程序发送到后台,然后才能在DDMS中停止该过程,以使其正常工作.对于那些想知道文档引用来自哪里的人[这里](http://developer.android.com/guide/topics/manifest/activity-element.html#always).虽然我不确定它们是否与该主题有关,因为它与清单中的`<activity>`标签有关. (5认同)
  • 从 Electric Eel 开始,在 IDE 中不再可能(终止按钮移动并更改了功能以强制停止应用程序进程)。@HexAndBug 的解决方案但是有效 - /sf/answers/1882315011/ (4认同)
  • 或者,您可以转到"开发选项"并将背景限制设置为"无后台进程",然后每次按下主页时,进程将会死亡. (3认同)
  • 感谢您的回答,但这对我没有用,因为我需要一种自动化的方式来进行自动化测试。 (2认同)

Hex*_*ugs 50

这似乎对我有用:

adb shell am kill <package_name>
Run Code Online (Sandbox Code Playgroud)

adb shell kill与OP提到的不同.

请注意,该am kill命令的帮助说:

am kill: Kill all processes associated with <PACKAGE>.  Only kills.
  processes that are safe to kill -- that is, will not impact the user
  experience.
Run Code Online (Sandbox Code Playgroud)

因此,如果它在前台,它不会杀死进程.这似乎是OP想要的,如果我离开我的应用程序,然后运行adb shell am kill <package_name>它将杀死应用程序(我已经ps在设备上确认了这一点).然后,如果我回到应用程序,我回到我以前的活动中 - 也就是在OP的示例中,该过程被重新创建并创建ActivityD(而不是像大多数其他杀死方法似乎触发的ActivityC).

对不起,我的OP已经晚了几年,但希望其他人会觉得这很有用.

  • 谢谢!这就是我一直在寻找的!我想指定该命令的行为与“adb shell am force-stop”不同。最后一个还将删除与您的应用程序相关的任何悬而未决的Intent(如通知),而第一个则不会。 (2认同)

Mer*_*erk 17

另一种方法,可能是一种可编写脚本的方法,因为它不需要DDMS:

一次性设置:转到开发者选项,选择后台进程限制设置,将值从"标准限制"更改为"无后台进程".

需要重新启动过程时,请按主页按钮.该进程将被终止(您可以在工作室中的logcat/Android Monitor中进行验证 - 该进程将被标记为[DEAD]).然后使用任务切换器切换回应用程序.

  • 有趣。我认为这不会影响前台服务,对吗? (2认同)

fth*_*dgn 13

这个问题很老但是,这个问题有一个答案,不需要adb,Android Studio等.唯一的要求是API 23或更新版本.

要通过操作系统模拟应用程序重新启动,请在应用程序运行时进行应用程序设置,禁用(然后您可以启用)权限并从最近的应用程序返回应用程序.禁用权限后,操作系统会终止应用程序,但会保留已保存的实例状态.当用户返回应用程序时,将重新创建应用程序和最后一个活动(已保存状态).

"无后台进程"方法有时会导致相同的行为,但并非总是如此.例如,如果应用程序正在运行后台服务,则"无后台进程"不执行任何操作.但该应用程序可能被系统杀死,包括其服务.即使app有服务,权限方法也能正常工作.

例:

我们的应用有两项活动.ActivityA是从启动器启动的主要活动.ActivityB从ActivityA启动.我将仅显示onCreate,onStart,onStop,onDestroy方法.Android在调用onStop之前总是调用onSaveInstanceState,因为处于停止状态的活动可以被系统杀死.[ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]

许可方式:

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop (the order is like this, it is stopped after new one is started)
<go settings>
ActivityB onStop
<disable a permission>
//Application is killed, but onDestroy methods are not called.
//Android does not call onDestroy methods if app will be killed.
<return app by recent apps>
Application onCreate (this is the important part. All static variables are reset.)
ActivityB onCreate WITH savedInstance (user does not notice activity is recreated)
//Note that ActivityA is not created yet, do not try to access it.
ActivityB onStart
<return ActivityA by back>
ActivityA onCreate WITH savedInstance (user does not notice activity is recreated)
ActivityA onStart
ActivityB onStop
ActivityB onDestroy
<press back again, return launcher>
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
Run Code Online (Sandbox Code Playgroud)

我想比较其他答案中提到的其他方法.

不要保持活动:这不会杀死应用程序.

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop
ActivityA onDestroy (do not keep)
<return launcher by home button>
ActivityB onStop
ActivityB onDestroy (do not keep) 
<retun app from recent apps>
// NO Application onCreate
ActivityB onCreate WITH savedInstance (user does not notice activity recreated)
ActivityB onStart
<return ActivityA by back>
ActivityA onCreate WITH savedInstance (user does not notice activity recreated)
ActivityA onStart
ActivityB onStop
ActivityB onDestroy
<press back again, return launcher>
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
Run Code Online (Sandbox Code Playgroud)

强制停止方法:不存储已保存的实例状态

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop
<go settings>
ActivityB onStop
<force stop, return app from recent apps>
Application onCreate
ActivityA onCreate WITHOUT savedInstance 
//This is important part, app is destroyed by user.
//Root activity of the task is started, not the top activity.
//Also there is no savedInstance.
Run Code Online (Sandbox Code Playgroud)

  • @IgorGanapolsky文档很好,特别是如果它是完整和正确的(不幸的是它不是),但我通常更多地依赖于实际的个人观察.我已经看到前景"服务"被杀了很多次.即使系统内存不低.大多数设备制造商已经为Android操作系统编写了自己的"优化"和"改进",以节省电池电量.许多设备比标准Android具有更强大的"杀手". (3认同)

Epi*_*rce 13

使用主页按钮将应用程序置于后台

在Android Studio的“Logcat”模式下选择你的进程,然后点击左下角的Terminate Application

终止按钮

现在从 Android 设备上的启动器启动您的应用程序


编辑:根据互联网,以下也有效:

 adb shell am kill [my-package-name]
Run Code Online (Sandbox Code Playgroud)

来自未来的编辑:需要注意的是,Android Studio 4.0 中发生了变化,如果您Run从 AS使用,Terminate则会发出Force Stop.

但是,如果您之后从启动器启动,然后您尝试以这种方式模拟它,那么您将获得所需的结果(低内存行为)。


小智 7

我参加派对的时间已经很晚了,而且在我之前的几个人给出了同样正确的答案,但为了简化对我来说只需按下主页按钮并运行此命令:

adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill

该应用程序不会失去状态,根据我自己的经验,这种方式与操作系统在后台杀死应用程序的方式相同.这仅适用于调试构建的应用程序


dba*_*bar 6

这是您在Android Studio中执行此操作的方式.

  1. 让您的设备处于调试模式并连接到您的计算机.
  2. 打开设备上的应用程序,然后转到您要测试"从死里复位"的任何活动.
  3. 按设备上的主屏幕按钮.
  4. 在Android Studio中,转到Android监视器 - >监视器,然后按"终止应用程序"图标.
  5. 现在,您可以通过最近的应用程序或通过单击它的启动器图标返回到您的应用程序,我的测试中的行为也一样.

  • 这没有任何帮助。我需要在测试套件中以编程方式执行此操作。但是还是谢谢你。 (2认同)
  • @Dale Android 设备监视器已在 Android Studio 3.1 中弃用并从 Android Studio 3.2 中删除。 (2认同)

Spe*_*eed 0

在"设置"下的"开发人员"选项中,选择"不要保留活动",这将在您离开它们时立即销毁活动.

  • 这个几乎是好的,但它不会杀死这个过程,它只会破坏活动.这是什么意思?您的活动将使用savedInstanceState打开,但所有静态变量仍在进程中.在进程终止之后,所有静态变量也被清除. (9认同)