如何模拟Android杀死我的进程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11365301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to simulate Android killing my process
提问by David Wasser
Android will kill a process if it is in the background and the OS decides it needs the resources (RAM, CPU, etc.). I need to be able to simulate this behaviour during testing so that I can ensure that my application is behaving correctly. I want to be able to do this in an automated way so that I can test if the application behaves correctly whenever this happens, which means that I'll have to test this in every activity, etc.
如果一个进程在后台并且操作系统决定它需要资源(RAM、CPU 等),Android 将终止该进程。我需要能够在测试期间模拟这种行为,以便确保我的应用程序运行正常。我希望能够以自动化的方式执行此操作,以便我可以在发生这种情况时测试应用程序的行为是否正确,这意味着我必须在每个活动等中对此进行测试。
I know how to kill my process. That isn't the problem. The problem is that when I kill my process (using DDMS, adb shell kill
, Process.killProcess()
, etc.) Android does not restart it the same way that it would if the Android OS had killed it itself.
我知道如何杀死我的进程。那不是问题。问题是,当我杀死我的过程(使用DDMS, ,adb shell kill
,Process.killProcess()
等)的Android不重新启动它以同样的方式,它将如果Android操作系统杀死了它本身。
If the Android OS kills the process (due to resource requirements), when the user returns to the application Android will recreate the process and then recreate the top activity on the activity stack(calling onCreate()
).
如果 Android 操作系统终止进程(由于资源需求),当用户返回应用程序时,Android 将重新创建进程,然后重新创建活动堆栈上的顶部活动(调用onCreate()
)。
On the other hand, if Ikill the process, Android assumes that the activity on the top of the activity stack was badly behaved, so it automatically recreates the process and then removes the top activity from the activity stack and recreates the activity that was underneath the top activity(calling onCreate()`). This is not the behaviour I want. I want the same behaviour as when Android kills the process.
另一方面,如果我终止进程,Android 假定活动堆栈顶部的活动行为不良,因此它会自动重新创建进程,然后从活动堆栈中删除顶部活动并重新创建位于下方的活动顶部活动(调用 onCreate()`)。这不是我想要的行为。我想要与 Android 终止进程时相同的行为。
Just to explain pictorially, if my activity stack looks like this:
只是为了形象地解释,如果我的活动堆栈是这样的:
ActivityA -> ActivityB -> ActivityC -> ActivityD
If Android kills the process and the user returns to the application, Android recreates the process and creates ActivityD.
如果 Android 终止进程并且用户返回到应用程序,Android 将重新创建该进程并创建 ActivityD。
If I kill the process, Android recreates the process and creates ActivityC.
如果我终止该进程,Android 将重新创建该进程并创建 ActivityC。
回答by Mark
The best way to test this for me was doing this:
为我测试这个的最好方法是这样做:
- Open ActivityD in your application
- Press Home button
- Press
Terminate Application
in Logcat window in Android Studio (this will kill the app process, make sure you select your device and process in Logcat dropdowns at top) - Get back to the application with Home long press or opened apps (depends on the device)
- Application will start in recreated ActivityD (ActivityA, ActivityB, ActivityC are dead and will be recreated when you get back to them)
- 在您的应用程序中打开 ActivityD
- 按主页按钮
Terminate Application
在 Android Studio 的 Logcat 窗口中按下(这将终止应用进程,请确保在顶部的 Logcat 下拉列表中选择您的设备和进程)- 使用 Home 长按或打开的应用程序返回应用程序(取决于设备)
- 应用程序将在重新创建的 ActivityD 中启动(ActivityA、ActivityB、ActivityC 已死,当您返回它们时将重新创建)
On some devices you can also get back to application (ActivityD) with Applications -> Your launcher icon but on other devices it will start the ActivityA instead.
在某些设备上,您还可以通过 Applications -> Your launcher icon 返回应用程序 (ActivityD),但在其他设备上,它将启动 ActivityA。
This is what Android docs are saying about that:
这就是 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.
通常,当用户从主屏幕重新选择该任务时,系统会在某些情况下清除任务(从根活动上方的堆栈中删除所有活动)。通常,如果用户在一定时间内(例如 30 分钟)未访问任务,则会执行此操作。
回答by HexAndBugs
This seems to work for me:
这似乎对我有用:
adb shell am kill <package_name>
This is different to adb shell kill
mentioned by the OP.
这adb shell kill
与OP提到的不同。
Note that the help for the am kill
command says:
请注意,该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.
So, it won't kill the process if it is in the foreground. This seems to work as the OP wanted in that if I navigate away from my app, then run adb shell am kill <package_name>
it will kill the app (I've confirmed this using ps
on the device). Then if I return to the app I'm back in the activity I was in previously - i.e. in the OP's example the process gets recreated and creates ActivityD (rather than ActivityC like most other methods of killing seem to trigger).
因此,如果它在前台,它不会终止进程。这似乎像 OP 想要的那样工作,因为如果我离开我的应用程序,然后运行adb shell am kill <package_name>
它会杀死应用程序(我已经ps
在设备上确认了这一点)。然后,如果我返回到应用程序,我又回到了我之前所在的活动中 - 即在 OP 的示例中,该过程被重新创建并创建 ActivityD(而不是像大多数其他杀死方法似乎触发的 ActivityC)。
Sorry I'm a couple of years late for the OP, but hopefully others will find this useful.
抱歉,我为 OP 迟了几年,但希望其他人会发现这很有用。
回答by Merk
Another method, probably one that is scriptable since it doesn't require DDMS:
另一种方法,可能是可编写脚本的方法,因为它不需要 DDMS:
One time setup: go to Developer Options, select Background process limit setting, change value from 'Standard Limit' to 'No background processes'.
一次性设置:转到开发人员选项,选择后台进程限制设置,将值从“标准限制”更改为“无后台进程”。
When you need to restart the process, press the home button. The process will be killed (you can verify in logcat/Android Monitor in studio -- the process will be marked [DEAD]). Then switch back to the app using the task switcher.
当您需要重新启动该过程时,请按主页按钮。该进程将被终止(您可以在 Studio 中的 logcat/Android Monitor 中进行验证——该进程将被标记为 [DEAD])。然后使用任务切换器切换回应用程序。
回答by fthdgn
This question is old but, there is an answer for this question which does not require adb, Android Studio etc. The only requirement is API 23 or newer.
这个问题很老,但是,这个问题有一个答案,不需要 adb、Android Studio 等。唯一的要求是 API 23 或更新版本。
To simulate app restart by OS, go app settings while your app is running, disable (then you can enable) a permission and return the app from recent apps. When permission is disabled, the OS kills the app but keeps saved instance states. When user returns the app, the app and the last activity (with saved state) are recreated.
要模拟操作系统重新启动应用程序,请在应用程序运行时转到应用程序设置,禁用(然后您可以启用)权限并从最近的应用程序返回应用程序。当权限被禁用时,操作系统会终止应用程序但保留已保存的实例状态。当用户返回应用程序时,将重新创建应用程序和最后一个活动(具有保存的状态)。
'No background processes' method sometimes causes same behavior, but not always. For example, if the app is running a background service, "No background processes" does nothing. But the app can be killed by system including its services. Permission method works even if app has a service.
“无后台进程”方法有时会导致相同的行为,但并非总是如此。例如,如果应用程序正在运行后台服务,则“无后台进程”不执行任何操作。但是该应用程序可能会被系统(包括其服务)杀死。即使应用程序有服务,权限方法也有效。
Example:
例子:
Our app has two activities. ActivityA is main activity which is started from launcher. ActivityB is started from ActivityA. I will show only onCreate, onStart, onStop, onDestroy methods. Android calls onSaveInstanceState always before calling onStop, because an activity which is on stop state can be killed by system. [https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]
我们的应用程序有两个活动。ActivityA 是从启动器启动的主要活动。ActivityB 从 ActivityA 开始。我将只展示 onCreate、onStart、onStop、onDestroy 方法。Android 总是在调用 onStop 之前调用 onSaveInstanceState,因为处于停止状态的活动可以被系统杀死。[ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]
Permission method:
权限方法:
<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
I want to compare other methods which are mentioned on the other answers.
我想比较其他答案中提到的其他方法。
Do not keep activities: This does not kill application.
不要保持活动:这不会杀死应用程序。
<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
Force stop method: Does not store saved instance states
强制停止方法:不存储保存的实例状态
<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.
回答by Hirschen
I'm very late to the party and several before me gave the same correct answer but to simplify for whoever comes after me just press home button and run this command:
我参加聚会很晚,在我之前的几个人给出了相同的正确答案,但为了简化我之后的任何人,只需按主页按钮并运行以下命令:
adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill
adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill
The app won't lose state and from my own experience this works the same way as the OS killed the app in the background. This works only for debug built applications
该应用程序不会丢失状态,根据我自己的经验,这与操作系统在后台杀死该应用程序的方式相同。这仅适用于调试构建的应用程序
回答by dbar
This is how you do it in Android Studio.
这就是你在 Android Studio 中的做法。
- Have your device in Debug Mode connected to your computer.
- Open the app on your device and go to whichever activity you want to test the "Return to it from the dead".
- Press Home button on your device.
- In Android Studio go to Android Monitor -> Monitors and press the Terminate Application icon.
- Now you can either go back to your app through the recent apps or by clicking on it's launcher icon, behaviour has been the same in my tests.
- 将处于调试模式的设备连接到计算机。
- 在您的设备上打开应用程序,然后转到您想要测试“从死里归来”的任何活动。
- 按设备上的主页按钮。
- 在 Android Studio 中,转到 Android Monitor -> Monitors 并按 Terminate Application 图标。
- 现在您可以通过最近的应用程序或单击它的启动器图标返回到您的应用程序,在我的测试中行为是相同的。
回答by MSpeed
In the Developer options under Settings, select 'Do not keep activities', which will destroy activities as soon as you navigate away from them.
在“设置”下的“开发人员”选项中,选择“不保留活动”,这将在您离开活动时立即销毁活动。
回答by EpicPandaForce
Put the application in background with HOME button
使用主页按钮将应用程序置于后台
Select your process in "Logcat" mode in Android Studio, then click Terminate Application in the bottomleft corner
在Android Studio的“Logcat”模式下选择你的进程,然后点击左下角的Terminate Application
Now launch your app from launcher on Android device
现在从 Android 设备上的启动器启动您的应用程序
EDIT:According to the internet, the following also works:
编辑:根据互联网,以下也有效:
adb shell am kill [my-package-name]
回答by Igor Kostomin
You can do next steps to reproduce sought-for behaviour:
您可以执行后续步骤来重现所寻求的行为:
- Open your app, navigate to top activity
- Use notification panel to navigate to any another full-screen application (for example, to system settings - in right top corner)
- Kill your application process
- Press back button
- 打开您的应用,导航至热门活动
- 使用通知面板导航到任何其他全屏应用程序(例如,系统设置 - 在右上角)
- 杀死你的申请过程
- 按返回键
回答by Monstieur
Press the Home button and put the app in the background first. Then stop or kill the process from DDMS or ADB.
按主页按钮,然后先将应用程序置于后台。然后从 DDMS 或 ADB 停止或终止该进程。