안드로이드가 프로세스를 죽이는 것을 시뮬레이션하는 방법
안드로이드는 프로세스가 백그라운드에 있고 프로세스가 리소스 (RAM, CPU 등)가 필요하다고 결정하면 프로세스를 종료합니다. 응용 프로그램이 올바르게 작동하는지 테스트 할 수 있도록 테스트 중에이 동작을 시뮬레이션 할 수 있어야합니다. 자동화 된 방식 으로이 작업을 수행 할 수 있기를 원할 때마다 응용 프로그램이 올바르게 작동하는지 테스트 할 수 있기를 원합니다. 즉, 모든 활동에서 이것을 테스트해야합니다.
프로세스를 종료하는 방법을 알고 있습니다. 그것은 문제가 아닙니다. 문제는 내가 내 프로세스를 종료 할 때 (DDMS를 사용하는 것입니다 adb shell kill
, Process.killProcess()
안드로이드는 그것을는 안드로이드 OS가 자체를 죽인한다면 것과 같은 방식으로 다시 시작되지 않는 등).
Android OS가 프로세스를 종료하면 (자원 요구 사항으로 인해) 사용자가 애플리케이션으로 돌아올 때 Android는 프로세스를 다시 생성 한 다음 활동 스택 에서 최상위 활동 을 다시 작성합니다 (호출 onCreate()
).
다른 한편, 만약 내가 프로세스를 종료, 안드로이드는 활동 스택의 상단에 활동이 심하게 행동 것으로 가정 자동 과정을 재현하므로, 다음 활동 스택의 상단 활동을 제거하고 아래에 있던 활동을 재현 최고 활동 (onCreate ()를 호출). 이것은 내가 원하는 행동이 아닙니다. Android가 프로세스를 종료 할 때와 동일한 동작을 원합니다.
내 활동 스택이 다음과 같은 경우 그림으로 설명하십시오.
ActivityA -> ActivityB -> ActivityC -> ActivityD
Android가 프로세스를 종료하고 사용자가 애플리케이션으로 돌아 가면 Android는 프로세스를 다시 작성하고 ActivityD를 작성합니다.
프로세스를 종료하면 Android가 프로세스를 다시 만들고 ActivityC를 만듭니다.
나를 위해 이것을 테스트하는 가장 좋은 방법은 이것을하는 것입니다.
- 응용 프로그램에서 ActivityD 열기
- 홈 버튼을 누릅니다
Terminate Application
Android Studio에서 Logcat 창을 누릅니다 (앱 프로세스가 종료되고 장치를 선택하고 Logcat 드롭 다운에서 맨 위 프로세스를 확인하십시오)- 홈 길게 누르기 또는 열린 앱을 사용하여 애플리케이션으로 돌아 가기 (기기에 따라 다름)
- 응용 프로그램이 다시 작성된 ActivityD에서 시작됩니다 (ActivityA, ActivityB, ActivityC가 종료되었으며 다시 돌아 오면 다시 작성 됨)
일부 장치에서는 응용 프로그램-> 런처 아이콘을 사용하여 응용 프로그램 (ActivityD)으로 돌아갈 수 있지만 다른 장치에서는 대신 ActivityA를 시작합니다.
이것은 안드로이드 문서가 그것에 대해 말하는 것입니다 :
일반적으로 시스템은 사용자가 홈 화면에서 해당 작업을 다시 선택할 때 특정 상황에서 작업을 삭제합니다 (루트 활동 위의 스택에서 모든 활동 제거). 일반적으로 사용자가 30 분과 같은 일정 시간 동안 작업을 방문하지 않은 경우에 수행됩니다.
이것은 나를 위해 작동하는 것 같습니다 :
adb shell am kill <package_name>
이것은 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.
따라서 프로세스가 포 그라운드에 있으면 프로세스를 종료하지 않습니다. 이것은 OP가 원하는 것처럼 작동하는 것 같습니다. 내 앱에서 다른 곳으로 이동하면 실행 adb shell am kill <package_name>
하면 앱이 종료됩니다 ( ps
기기에서 사용하여 확인했습니다 ). 그런 다음 앱으로 돌아 가면 이전에했던 활동으로 돌아갑니다. 즉, OP의 예에서는 프로세스가 다시 만들어지고 ActivityD가 아닌 ActivityC 대신 다른 C를 죽이는 것처럼 보입니다.
죄송합니다. OP에 대해 2 년 늦었지만 다른 사람들이이 기능을 유용하게 사용할 수 있기를 바랍니다.
또 다른 방법, 아마도 DDMS가 필요하지 않기 때문에 스크립팅 가능한 방법 일 것입니다.
한 번 설정 : 개발자 옵션으로 이동하여 백그라운드 프로세스 한계 설정을 선택하고 값을 '표준 한계'에서 '배경 프로세스 없음'으로 변경하십시오.
프로세스를 다시 시작해야 할 경우 홈 버튼을 누릅니다. 프로세스가 종료됩니다 (스튜디오의 logcat / Android 모니터에서 확인할 수 있음-프로세스가 [DEAD]로 표시됨). 그런 다음 작업 전환기를 사용하여 앱으로 다시 전환하십시오.
이 질문은 오래되었지만 adb, Android Studio 등을 필요로하지 않는이 질문에 대한 답변이 있습니다. 유일한 요구 사항은 API 23 이상입니다.
OS 별 앱 다시 시작을 시뮬레이션하려면 앱이 실행되는 동안 앱 설정으로 이동하여 권한을 비활성화 (활성화 한 후 활성화) 한 다음 최근 앱에서 앱을 반환하십시오. 권한이 비활성화되면 OS가 앱을 종료하지만 저장된 인스턴스 상태는 유지합니다. 사용자가 앱을 반환하면 앱과 마지막 활동 (저장된 상태)이 다시 생성됩니다.
'백그라운드 프로세스 없음'방법으로 동일한 동작이 발생하지만 항상 그런 것은 아닙니다. 예를 들어 앱에서 백그라운드 서비스를 실행중인 경우 "배경 프로세스 없음"은 아무 작업도 수행하지 않습니다. 그러나 응용 프로그램은 서비스를 포함하여 시스템에 의해 종료 될 수 있습니다. 앱에 서비스가 있어도 권한 방법이 작동합니다.
예:
우리 앱에는 두 가지 활동이 있습니다. 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
다른 답변에 언급 된 다른 방법을 비교하고 싶습니다.
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.
This is how you do it in 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.
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
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
In the Developer options under Settings, select 'Do not keep activities', which will destroy activities as soon as you navigate away from them.
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
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
Now launch your app from launcher on Android device
EDIT: According to the internet, the following also works:
adb shell am kill [my-package-name]
Press the Home button and put the app in the background first. Then stop or kill the process from DDMS or ADB.
The root of your problem seems to be that your Activity
is in foreground when you kill the process.
You can observe this by pressing stop in DDMS when Activity
is visible (happens exactly what you describe) and comparing that to pressing stop after home and later returning to the app.
Just make sure to moveTaskToBack(true)
somehow in your tests.
I'm not sure this is the answer you are looking for, it's more like a logic think.
I don't think that you can really make a fully automated test, the only way to simulate it, it will be to recreate it, AKA have so many activities that Android will kill your application.
So my idea or suggestion is to make another small app, which keeps popping up new activities, till Android runs out of memory and start killing process it the background.
Something among the line:
Start activity i -> Check running process if the app is in the list, increment i and restart the loop without closing current activity, else -> decrease i and close current activity, go back to previous and recheck...
You can also connect to your device/emulator from terminal with adb shell
, then get PID of your process with ps | grep <your_package_name
and execute kill -9 <pid>
. Then open your minimized app from recent apps picker and it will restart last activity
참고URL : https://stackoverflow.com/questions/11365301/how-to-simulate-android-killing-my-process
'IT' 카테고리의 다른 글
언제 WeakHashMap 또는 WeakReference를 사용 하시겠습니까? (0) | 2020.06.02 |
---|---|
전체 객체 또는 컨테이너에 객체에 대한 포인터를 저장해야합니까? (0) | 2020.06.02 |
변수에 표준 오류를 저장하는 방법 (0) | 2020.06.02 |
C # 또는 VB.NET에서 할 수없는 MSIL에서 무엇을 할 수 있습니까? (0) | 2020.06.02 |
PHP 5 : const 대 정적 (0) | 2020.06.02 |