如何模拟Android杀死我的进程

How to simulate Android killing my process

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

我知道如何杀死我的进程。那不是问题。问题是,当我杀死我的进程(使用DDMS,adb shell killProcess.killProcess()等)时,Android不会像Android OS自身杀死它那样重启它。

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

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

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

1
    ActivityA -> ActivityB -> ActivityC -> ActivityD

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

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


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

  • 在您的应用程序中打开ActivityD
  • 按主页按钮
  • 在Android Studio的Logcat窗口中按Terminate Application(这将终止应用程序进程,确保在Logcat下拉列表中选择您的设备和进程)
  • 使用Home长按或打开的应用程序返回应用程序(取决于设备)
  • 应用程序将在重新创建的ActivityD中启动(ActivityA,ActivityB,ActivityC已经死亡,当你回到它们时将重新创建)

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

这就是Android文档所说的:

Normally, the system clears a task (removes all activities from the stack above the root activity) in certain situations when the user re-selects that task from the home screen. Typically, this is done if the user hasn't visited the task for a certain amount of time, such as 30 minutes.


这似乎对我有用:

1
adb shell am kill <package_name>

这与OP提到的adb shell kill不同。

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

1
2
3
am kill: Kill all processes associated with <PACKAGE>.  Only kills.
  processes that are safe to kill -- that is, will not impact the user
  experience.

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

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


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

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

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


这个问题很老但是,这个问题有一个答案,不需要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]

许可方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<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
[cc]
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<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
[cc]
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<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.


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

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

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

    adb shell ps | grep | awk '{print $2}' | xargs adb shell run-as kill

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


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


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

    在Android Studio中以"Logcat"模式选择您的过程,然后单击左下角的Terminate Application

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

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

    1
     adb shell am kill [my-package-name]


    您可以执行后续步骤来重现所寻求的行为:

  • 打开您的应用,导航至热门活动
  • 使用通知面板导航到任何其他全屏应用程序(例如,到系统设置 - 在右上角)
  • 杀死你的申请流程
  • 按后退按钮

  • 按Home键,然后将应用程序放在后台。然后从DDMS或ADB停止或终止该进程。


    您也可以使用adb shell从终端连接到您的设备/仿真器,然后使用ps | grep 获取进程的PID并执行kill -9 。然后从最近的应用选择器中打开最小化的应用,它将重新启动上一个活动


    我不确定这是你正在寻找的答案,它更像是一种逻辑思考。

    我不认为你真的可以进行全自动测试,模拟它的唯一方法,就是重新创建它,AKA有很多活动,Android会杀死你的应用程序。

    所以我的想法或建议是创建另一个小应用程序,它不断弹出新的活动,直到Android内存不足并开始杀死进程后台。

    行中的东西:

    启动活动i - >检查运行过程,如果应用程序在列表中,增加i并重新启动循环而不关闭当前活动,否则 - >减少i并关闭当前活动,返回上一步并重新检查...


    您的问题的根源似乎是当您终止进程时Activity处于前台。

    您可以通过在Activity可见时按下DDMS(完全按照您描述的方式)按下停止并将其与在主页后按停止并稍后返回应用程序进行比较来观察此情况。

    只需确保在测试中以某种方式moveTaskToBack(true)