如何模拟Android杀死我的过程
Android会杀死一个进程,如果它在后台,操作系统决定它需要资源(RAM,CPU等)。 我需要能够在testing过程中模拟这种行为,以便确保我的应用程序正常运行。 我希望能够以一种自动化的方式做到这一点,这样我就可以testing应用程序是否正确行为,这意味着我将不得不在每个活动中testing这些。
我知道如何杀死我的过程。 这不是问题。 问题是,当我杀死我的进程(使用DDMS, adb shell kill
, Process.killProcess()
等))Android不会重新启动它的方式,如果Android操作系统已经杀死它本身。
如果Android操作系统杀死进程(由于资源需求),当用户返回到应用程序时,Android将重新创build进程,然后在活动堆栈上重新创build顶级活动 (调用onCreate()
)。
另一方面,如果我终止进程, Android会认为活动堆栈顶部的活动performance不佳 ,因此会自动重新创build进程,然后从活动堆栈中移除顶部活动,并重新创build活动下面的活动顶级活动 (调用onCreate()`)。 这不是我想要的行为。 我需要和Android杀死进程时一样的行为。
只是为了解释,如果我的活动堆栈看起来像这样:
ActivityA -> ActivityB -> ActivityC -> ActivityD
如果Android杀死进程并且用户返回到应用程序,则Android重新创build进程并创buildActivityD。
如果我杀了进程,Android重新创build过程并创buildActivityC。
为我testing这个最好的方法是这样做的:
- 在您的应用程序中打开ActivityD
- 按主页button
- 在您的应用程序中按DDMS停止(这将杀死应用程序进程)
- 回到主页长按或打开的应用程序(取决于设备)
- 应用程序将在重新创build的ActivityD中开始(ActivityA,ActivityB,ActivityC已经死了,当你回到它们时将被重新创build)
在某些设备上,您还可以使用应用程序 – >您的启动器图标返回到应用程序(ActivityD),但在其他设备上,它将启动ActivityA。
这就是Android文档所说的:
通常,在用户从主屏幕重新select该任务的某些情况下,系统清除任务(从根目录活动之上的堆栈中移除所有活动)。 通常,如果用户在一定的时间内(例如30分钟)未访问任务,则完成此操作。
这似乎为我工作:
adb shell am kill <package_name>
这与OP提到的adb shell kill
不同。
请注意, 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.
所以,如果它在前台,它不会杀死进程。 这似乎工作,因为OP想要的,如果我离开我的应用程序的导航,然后运行adb shell am kill <package_name>
它将杀死应用程序(我已经证实这在设备上使用ps
)。 然后,如果我返回到应用程序,我回到了之前的活动 – 即在OP的例子中,过程得到重新创build,并创buildActivityD(而不是ActivityC,像大多数其他杀戮方法似乎触发)。
对不起,我已经晚了几年的OP,但希望别人会发现这有用。
另一种方法,可能是一个脚本,因为它不需要DDMS:
一次设置:转到开发人员选项,select后台进程限制设置,将值从“标准限制”更改为“无后台进程”。
当您需要重新启动进程时,请按主页button。 该进程将被杀死(你可以在工作室的logcat / Android监视器中进行validation – 该进程将被标记为[DEAD])。 然后使用任务切换器切换回应用程序。
在“设置”下的“开发者”选项中,select“不要保留活动”,一旦离开活动,活动将立即销毁活动。
这是你在Android Studio中的做法。
- 将您的设备debugging模式连接到您的计算机。
- 打开您的设备上的应用程序,并去任何你想testing的活动“从死里复活”。
- 按设备上的主页button。
- 在Android Studio中,进入Android监视器 – >监视器,然后按终止应用程序图标。
- 现在,您可以通过最近的应用程序或点击启动器图标返回到您的应用程序,在我的testing中行为也一样。
这个问题是旧的,但是,这个问题有一个答案,不需要亚行,Android Studio等。唯一的要求是API 23或更新。
要模拟应用程序通过操作系统重启,在应用程序运行时转到应用程序设置,禁用(然后您可以启用)权限,并从最近的应用程序返回应用程序。 当权限被禁用时,操作系统杀死应用程序,但保持已保存的实例状态。 当用户返回应用程序时,应用程序和最后一个活动(保存状态)被重新创build。
“没有后台进程”方法有时会导致相同的行为,但并不总是如此。 例如,如果应用程序正在运行后台服务,则“无后台进程”将不会执行任何操作。 但该应用程序可以通过包括其服务在内的系统来杀死。 即使应用程序有服务,权限方法也可以工作。
例:
我们的应用有两个活动。 ActivityA是从启动器启动的主要活动。 ActivityB从ActivityA开始。 我只会显示onCreate,onStart,onStop,onDestroy方法。 Android在调用onStop之前总是调用onSaveInstanceState,因为处于停止状态的活动可以被系统终止。 [ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle%5D
权限方法:
<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
我想比较其他答案中提到的其他方法。
不要保持活动:这不会杀死应用程序。
<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
强制停止方法:不存储保存的实例状态
<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.
我对晚会已经很迟了,之前的几个人给出了同样正确的答案,但是为了简化后面的任何人,只要按下home键并运行这个命令即可:
adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill
该应用程序不会松动的状态,从我自己的经验来看,这与OS在后台中杀死应用程序的方式相同。 这仅适用于debugging构build的应用程序
看来你想testingonSaveInstanceState
和onRestoreInstanceState
。
在真实设备上testing:看看SetAlwaysFinish应用程序。
在模拟器中进行testing: checkout在Android模拟器的Dev Tools App中立即销毁活动选项。
对于所有人,我只是想让你知道我发现的这个文件:
http://developer.android.com/tools/testing/activity_testing.html
我不能100%肯定地说在这里有一个与Android完全一样的杀人方法,但是,这是一个开始。 您可以在这里模拟活动生命周期的许多部分,所以您应该能够模拟进程的查杀。
另外这里是一个教程: http : //developer.android.com/tools/testing/activity_test.html#StateManagementTests
希望这可以帮助。 干杯
您可以执行后续步骤来重现所寻找的行为:
- 打开你的应用程序,导航到最高的活动
- 使用通知面板导航到任何其他全屏应用程序(例如,到系统设置 – 在右上angular)
- 杀死你的申请程序
- 按下后退button
你的问题的根源似乎是当你杀死进程时你的Activity
在前台。
你可以通过在DDMS中按下stop来观察这一点,当Activity
是可见的(正好发生你所描述的),并将其与家庭之后的按压停止比较,然后返回到应用程序。
只要确保在testing中以某种方式移动moveTaskToBack(true)
。
按主页button,然后把应用程序放在后台。 然后停止或杀死从DDMS或ADB进程。
我不确定这是你正在寻找的答案,更像是一个逻辑思考。
我不认为你真的可以做一个完全自动化的testing,唯一的方法来模拟它,它会重新创build它,AKA有这么多的活动,Android会杀死你的应用程序。
所以我的想法或者build议是制作另一个小程序,不断popup新的活动,直到Android耗尽内存并开始将其处理为背景。
线之间的东西:
开始活动我 – >检查正在运行的进程,如果应用程序在列表中,递增我并重新启动循环而不closures当前活动,否则 – >减less我并closures当前活动,返回到上一个并重新检查…
你也可以用adb shell
从terminal连接到你的设备/仿真器,然后用ps | grep <your_package_name
获得你的进程的PID ps | grep <your_package_name
并执行kill -9 <pid>
。 然后从最近的应用程序select器中打开最小化的应用程序,它将重新启动上次的活动