안드로이드가 프로세스를 죽이는 것을 시뮬레이션하는 방법


174

안드로이드는 프로세스가 백그라운드에 있고 프로세스가 리소스 (RAM, CPU 등)가 필요하다고 결정하면 프로세스를 종료합니다. 응용 프로그램이 올바르게 작동하는지 테스트 할 수 있도록 테스트 중에이 동작을 시뮬레이션 할 수 있어야합니다. 자동화 된 방식 으로이 작업을 수행 할 수 있기를 원할 때마다 응용 프로그램이 올바르게 작동하는지 테스트 할 수 있기를 원합니다. 즉, 모든 활동에서 이것을 테스트해야합니다.

프로세스를 종료하는 방법을 알고 있습니다. 그것은 문제가 아닙니다. 문제는 내가 내 프로세스를 종료 할 때 (DDMS를 사용하는 것입니다 adb shell kill, Process.killProcess()안드로이드는 그것을는 안드로이드 OS가 자체를 죽인한다면 것과 같은 방식으로 다시 시작되지 않는 등).

Android OS가 프로세스를 종료하면 (자원 요구 사항으로 인해) 사용자가 애플리케이션으로 돌아올 때 Android는 프로세스를 다시 생성 한 다음 활동 스택 에서 최상위 활동 을 다시 작성합니다 (호출 onCreate()).

다른 한편, 만약 내가 프로세스를 종료, 안드로이드는 활동 스택의 상단에 활동이 심하게 행동 것으로 가정 자동 과정을 재현하므로, 다음 활동 스택의 상단 활동을 제거하고 아래에 있던 활동을 재현 최고 활동 (onCreate ()를 호출). 이것은 내가 원하는 행동이 아닙니다. Android가 프로세스를 종료 할 때와 동일한 동작을 원합니다.

내 활동 스택이 다음과 같은 경우 그림으로 설명하십시오.

    ActivityA -> ActivityB -> ActivityC -> ActivityD

Android가 프로세스를 종료하고 사용자가 애플리케이션으로 돌아 가면 Android는 프로세스를 다시 작성하고 ActivityD를 작성합니다.

프로세스를 종료하면 Android가 프로세스를 다시 만들고 ActivityC를 만듭니다.


4
백그라운드에서 프로세스를 종료하는 데 필요한 프로세스 양만 만들 수 있습니까?
— Alex W


2
@ 팡 당신이 요점을 놓치고 있다고 생각합니다. Android가 프로세스를 종료했음을 감지하는 방법을 알고 있습니다. 이러한 조건을 처리하는 코드가 있습니다. 내가하고 싶은 것은 이 코드 를 올바르게 (자동으로) 테스트하는 것입니다 . 그러기 위해서는 일반적으로 리소스 압력 하에서와 동일한 방식으로 프로세스를 강제 종료하도록 Android를 자극 할 수있는 방법이 필요합니다. 링크 된 질문은 흥미롭지 만 여기에는 아무런 가치가 없습니다.
— David Wasser


@IgorGanapolsky 링크는 감사하지만 실제로는 해당 링크 중 어느 것도 문제에 대한 해결책을 가지고 있지 않습니다.
— David Wasser

답변:


127

나를 위해 이것을 테스트하는 가장 좋은 방법은 이것을하는 것입니다.

  • 응용 프로그램에서 ActivityD 열기
  • 홈 버튼을 누릅니다
  • Terminate ApplicationAndroid Studio에서 Logcat 창을 누릅니다 (앱 프로세스가 종료되고 장치를 선택하고 Logcat 드롭 다운에서 맨 위 프로세스를 확인하십시오)
  • 홈 길게 누르기 또는 열린 앱을 사용하여 애플리케이션으로 돌아 가기 (기기에 따라 다름)
  • 응용 프로그램이 다시 작성된 ActivityD에서 시작됩니다 (ActivityA, ActivityB, ActivityC가 종료되었으며 다시 돌아 오면 다시 작성 됨)

일부 장치에서는 응용 프로그램-> 런처 아이콘을 사용하여 응용 프로그램 (ActivityD)으로 돌아갈 수 있지만 다른 장치에서는 대신 ActivityA를 시작합니다.

이것은 안드로이드 문서가 그것에 대해 말하는 것입니다 :

일반적으로 시스템은 사용자가 홈 화면에서 해당 작업을 다시 선택할 때 특정 상황에서 작업을 삭제합니다 (루트 활동 위의 스택에서 모든 활동 제거). 일반적으로 사용자가 30 분과 같은 일정 시간 동안 작업을 방문하지 않은 경우에 수행됩니다.


2
귀하의 답변에 감사하지만 자동 테스트를 위해 자동으로 수행 해야하는 방법이 필요하기 때문에 유용하지 않습니다.
— David Wasser

1
이것은 정말 도움이되었습니다.
— John Roberts

6
이것은 자동화되지 않았지만 내 목적을 위해 완벽하게 작동했습니다. 2 단계 를 건너 뛰지 않는 것이 매우 중요 합니다. 이 작업을 수행하려면 DDMS에서 프로세스를 중지하기 전에 앱을 백그라운드로 보내야합니다. 문서 인용문이 어디에서 왔는지 궁금한 사람들은 여기에 있습니다 . 비록 그것이 <activity>매니페스트 의 태그에 관한 것이기 때문에 실제로 주제와 관련이 있는지는 확실하지 않습니다 .
— Tony Chan

1
정확히 내가 필요한 것. 감사합니다. 모르는 사람들을 위해 DDMS는 Eclipse에 있으며 Window-> Open Perspective로 이동하면 찾을 수 있습니다.
— Richard

4
또는 "개발 옵션"으로 이동하여 백그라운드 제한을 "백그라운드 프로세스 없음"으로 설정 한 다음 집을 누를 때마다 프로세스가 종료됩니다.
— Joao Gavazzi 2016 년

56

이것은 나를 위해 작동하는 것 같습니다 :

adb shell am kill <package_name>

이것은 adb shell killOP 에서 언급 한 것과 다릅니다 .

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 년 늦었지만 다른 사람들이이 기능을 유용하게 사용할 수 있기를 바랍니다.


감사! 이것이 내가 찾던 것입니다! 이 명령이과 다르게 동작하도록 지정하고 싶습니다 adb shell am force-stop. 마지막으로 앱과 관련된 모든 pendingIntent (예 : 알림)는 제거하지만 첫 번째 알림은 제거하지 않습니다.
— bonnyz

메모리를 확보하기 위해 프로세스를 종료 할 때 어떤 코드가 실행되는지 확인하기 위해 OS 소스 코드를 조사하는 사람을 지적합니다. 내 생각은와 동일한 코드 am kill입니다.
— androidguy

Android 7.1 Samsung J5에서는 작동하지 않습니다. ps내 앱을 보여줍니다
— Valgaal

17

또 다른 방법, 아마도 DDMS가 필요하지 않기 때문에 스크립팅 가능한 방법 일 것입니다

한 번 설정 : 개발자 옵션으로 이동하여 백그라운드 프로세스 한계 설정을 선택하고 값을 '표준 한계'에서 '배경 프로세스 없음'으로 변경하십시오.

프로세스를 다시 시작해야 할 경우 홈 버튼을 누릅니다. 프로세스가 종료됩니다 (스튜디오의 logcat / Android 모니터에서 확인할 수 있음-프로세스가 [DEAD]로 표시됨). 그런 다음 작업 전환기를 사용하여 앱으로 다시 전환하십시오.


2
흥미 롭군 나는 그것이 전경 서비스에 영향을 미치지 않는다고 생각합니다.
— IgorGanapolsky

2.3.3 이전의 Android를 실행하는 실제 기기 에서이 작업을 수행해야하므로 도움이되지 않습니다.
— David Wasser

13

이 질문은 오래되었지만 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

다른 답변에 언급 된 다른 방법을 비교하고 싶습니다.

활동을 유지하지 마십시오. 응용 프로그램이 종료되지 않습니다.

<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.

~ " 서비스를 포함한 시스템에 의해 앱이 종료 될 수 있습니다 ." 전경 서비스가 아닙니다 ...
— IgorGanapolsky

@DavidWasser 사양을 읽어보세요! developer.android.com/guide/components/services.html#Foreground 포 그라운드 서비스는 사용자가 적극적으로 인식하고 있으며 메모리가 부족할 때 시스템이 종료 될 수있는 서비스가 아닙니다.
— IgorGanapolsky

3
@IgorGanapolsky 설명서는 특히 완전하고 정확하면 (아쉽게도 그렇지 않은 경우) 유용하지만 일반적으로 실제 개인 관찰에 더 의존합니다. 나는 전경 Service이 여러 번 죽임을 보았다 . 시스템의 메모리가 부족하지 않은 경우에도 마찬가지입니다. 대부분의 기기 제조업체는 배터리 전원을 절약하기 위해 자체 "최적화"및 "개선"을 Android OS에 작성했습니다. 많은 기기가 표준 Android보다 훨씬 공격적인 "킬러"를 가지고 있습니다.
— David Wasser

@DavidWasser 공정한 관찰. 그래서 몇 년 후, 당신은 해결책을 생각해 냈습니까?
— IgorGanapolsky

@ IgorGanapolsky 아니요.이 문제에 대한 해결책을 찾지 못했습니다. 그래서 질문이 아직 열려 있습니다.
— David Wasser

7

나는 파티에 매우 늦었고 여러 사람이 똑같은 대답을하기 전에 나에게 오는 사람을 단순화하기 위해 홈 버튼을 누르고이 명령을 실행하십시오.

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

앱은 상태를 잃지 않으며 내 경험으로 인해 백그라운드에서 OS가 앱을 종료 한 것과 같은 방식으로 작동합니다. 이것은 디버그 빌드 응용 프로그램에서만 작동합니다


나는 얻는다'grep' is not recognized as an internal or external command, operable program or batch file.
— Dale

그러나 나는 껍질에있는 동안 그것을 run-as <package name> kill 7379했지만 홈 버튼을 눌렀을 때의 활동이 아니라 이전 활동에 나를 두었습니다.
— Dale

6

이것이 Android Studio에서 수행하는 방법입니다.

  1. 디버그 모드의 장치를 컴퓨터에 연결하십시오.
  2. 기기에서 앱을 열고 "죽음에서 돌아 오기"를 테스트하려는 활동으로 이동하십시오.
  3. 기기에서 홈 버튼을 누릅니다.
  4. Android Studio에서 Android 모니터-> 모니터로 이동하여 애플리케이션 종료 아이콘을 누르십시오.
  5. 이제 최신 앱을 통해 앱으로 돌아가거나 실행기 아이콘을 클릭하면 내 테스트에서 동작이 동일합니다.

2
이것은 도움이되지 않습니다. 테스트 스위트 내에서 프로그래밍 방식 으로이 작업을 수행해야합니다. 어쨌든 고마워
— David Wasser

또한이 답변은 Mark의 답변과 거의 동일합니다.
— David Wasser

UIAutomator 또는 Espresso를 통해이 작업을 수행하는 방법을 알고 있습니까?
— IgorGanapolsky

찾을 수 없습니다 Android Monitor - Monitors. 그들이 제거해야합니다. 나는 v 3.2.1에 있습니다
— Dale

1
@Dale Android 기기 모니터는 Android Studio 3.1에서 더 이상 사용되지 않으며 Android Studio 3.2에서 제거되었습니다.
— Valgaal 2019

5

HOME 버튼으로 백그라운드에서 응용 프로그램을 넣습니다.

Android Studio의 "로그 캣"모드에서 프로세스를 선택한 다음 왼쪽 하단에서 애플리케이션 종료를 클릭하십시오.

종료 버튼

이제 Android 기기의 런처에서 앱을 시작하십시오.


편집 : 인터넷에 따르면 다음도 작동합니다.

 adb shell am kill [my-package-name]

미래에서 편집 : 노트에 뭔가가, 당신이 사용하는 경우, 안드로이드 스튜디오 4.0의 변경이있는 RunAS에서, 다음 Terminate를 발행합니다 Force Stop.

그러나 나중에 런처에서 시작한 다음이 방법으로 시뮬레이션하려고하면 원하는 결과를 얻을 수 있습니다 (메모리 동작이 낮음).


이것은 정답입니다
— Onik

@Onik 다른 모든 것들에는 ddms와 같은 불필요한 보풀이 있습니다. 기술적으로는 맞지만 stackoverflow.com/a/41975750/2413303도 같은 내용을 말합니다. 사진을 추가해야 할 수도 있습니다.
— EpicPandaForce

도움이되지 않습니다. 테스트 하네스가 있으며 테스트 하네스에서 이러한 작업을 실행할 수 없습니다. 또한 동작이 Android에서 프로세스를 종료 할 때 발생하는 동작과 동일하지 않습니다.
— David Wasser

the behaviour is not the same as what happens when Android kills the process그렇습니다
— EpicPandaForce

이 프로세스는 홈 버튼을 눌렀을 때의 활동이 아니라 이전 활동을 보여줍니다.
— Dale

2

추구하는 행동을 재현하기 위해 다음 단계를 수행 할 수 있습니다.

  1. 앱을 열고 주요 활동으로 이동
  2. 알림 패널을 사용하여 다른 전체 화면 응용 프로그램 (예 : 시스템 설정-오른쪽 상단 모서리)으로 이동하십시오.
  3. 신청 절차 종료
  4. 뒤로 가기 버튼

1
귀하의 답변에 감사하지만 자동 테스트를 위해 자동으로 수행 해야하는 방법이 필요하기 때문에 유용하지 않습니다.
— David Wasser

따라서이 방법은 실제로 안드로이드 메모리 지우기 및 앱 종료를 시뮬레이션하는 유일한 방법입니다 (API 레벨은 19이므로 send-trim-memory 명령을 사용할 수 없습니다). adb shell am force-stop com.my.app.package 또는 kill과 같은 다른 명령은 위의 절차를 따르는 것과 동일한 정확한 프로세스를 재현하지 않습니다!
— Mark Garcia

2

설정 아래의 개발자 옵션에서 '활동 유지 안 함'을 선택하면 활동에서 벗어나면 즉시 활동이 삭제됩니다.

참고 : 아래의 유용한 설명에 따라 정적 값이 지워지지 않는 경우에만 사용하십시오.


이것은 1 년 전에 이미 게시 및 거부 된 솔루션과 사실상 동일합니다. 유일한 차이점은 에뮬레이터에서 응용 프로그램을 설정하는 데 사용되는 응용 프로그램과 응용 프로그램을 지원하는 최신 전화입니다.
— Chris Stratton

1
Chris Stratton이 말했듯이 이것은 다른 답변과 거의 동일한 제안입니다. 이것은 안드로이드 마무리 활동에 관한 것이 아닙니다. 이것은 안드로이드가 전체 프로세스를 죽이는 것에 관한 것입니다 (특히 Android 4.x를 실행하는 HTC 장치에서 매우 규칙적이고 효과적입니다).
— David Wasser

6
이것은 거의 좋지만 프로세스를 종료하지는 않으며 활동을 파괴합니다. 무슨 뜻인가요? savedInstanceState를 사용하여 활동이 열리지 만 모든 정적 변수는 아직 처리 중입니다. 프로세스 종료 후 모든 정적 변수도 지워집니다.
— Mark

1

홈 버튼을 누르고 앱을 배경에 먼저 놓습니다. 그런 다음 DDMS 또는 ADB에서 프로세스를 중지하거나 종료하십시오.


귀하의 답변에 감사하지만 자동 테스트를 위해 자동으로 수행 해야하는 방법이 필요하기 때문에 유용하지 않습니다.
— David Wasser

활동이 현재 포 그라운드에있는 경우 Android는 프로세스를 종료하지 않습니다. 절대 발생하지 않는 조건을 테스트하려고합니다. 활동이 백그라운드에 있으면 상태가 이미 저장되었으며 수동으로 종료하는 것과 메모리가 부족한 상태에서 Android를 종료하는 것 사이에는 차이가 없습니다. 즉, 프로세스가 종료 된 것입니다. 낮은 메모리 킬에 대해서는 특별한 것이 없습니다. 메모리를 다시 사용할 수있게되면 고정 서비스가 다시 시작되고 (4.4 제외) 아이콘 또는 최근 작업을 누르면 스택 및 활동 상태가 복원됩니다.
— Monstieur

3
귀하의 예에서, 활동 D가 화면에 표시되어있는 동안 (메모리가 부족하더라도 절대 발생하지 않음) 프로세스가 종료되고 활동 C의 상태가 배경에 있기 때문에 활동 C의 상태가 저장되었으므로 활동 C로 돌아갑니다. 프로세스가 포 그라운드에 있지 않은 경우에만 프로세스가 종료됩니다. 즉, 활동 D의 상태가 백그라운드로 갈 때 저장되어 프로세스가 종료 된 경우에도 복원됩니다. 각 활동에 대한 테스트를 수행하려면 앱을 종료하기 전에 먼저 백그라운드로 앱을 보내야합니다.
— Monstieur 2012

~ "이 무슨 뜻 입니까? 먼저 백그라운드에서 앱을 넣었 습니까?"
— IgorGanapolsky

1

로 터미널에서 장치 / 에뮬레이터에 연결 adb shell한 다음 프로세스의 PID를 가져 와서 ps | grep <your_package_name실행할 수도 kill -9 <pid>있습니다. 그런 다음 최근 앱 선택기에서 최소화 된 앱을 열면 마지막 활동이 다시 시작됩니다.


메모리가 부족한 조건에서 Android가 프로세스를 종료시키는 것과 동일합니까? OP가 구체적으로 원했던 것 같습니다 ...
— IgorGanapolsky

1
@IgorGanapolsky는 이론적으로는 뿌리가 없다면 실제 장치에서는 그렇게 할 수 없었습니다.
— Fran Marzoa

0

문제의 근원은 Activity프로세스를 죽일 때 전경 에있는 것 같습니다 .

DDMS에서 중지 Activity가 표시되면 (정확하게 설명 된대로) 멈춤을 누른 다음 집에서 중지 한 후 중지하고 나중에 앱으로 돌아 오는 것을 비교하여이를 확인할 수 있습니다.

moveTaskToBack(true)어떻게 든 테스트에서 확인하십시오 .


0

이것이 당신이 찾고있는 대답인지 확실하지 않습니다. 논리적 사고와 같습니다.

나는 당신이 실제로 완전히 자동화 된 테스트를 할 수 있다고 생각하지 않습니다. 시뮬레이트하는 유일한 방법은 그것을 재현하는 것입니다. AKA는 너무 많은 활동을 통해 Android가 응용 프로그램을 종료시킬 것입니다.

그래서 내 아이디어 나 제안은 안드로이드가 메모리가 부족하고 백그라운드에서 프로세스를 종료하기 시작할 때까지 새로운 활동을 계속 보여주는 또 다른 작은 앱을 만드는 것입니다.

라인 중 무언가 :

활동 시작 i-> 앱이 목록에 있으면 실행중인 프로세스 확인, i를 증가시키고 현재 활동을 닫지 않고 루프를 다시 시작하십시오. 그렇지 않으면-> i를 줄이고 현재 활동을 닫고 이전으로 돌아가 다시 확인하십시오 ...


0

애플리케이션 프로세스가 종료되면 Android는 활동 레코드 (항목이 내역 스택의 활동을 나타냄)를 통해 결정합니다. 역사에서 유지하고 그것에서 어떤 사람을 제거 할 것.

여기에 핵심 포인트 중 하나는이다 ActivityRecord라는 필드 haveState안드로이드 프레임 워크 엔지니어, 설명 으로 "우리가 입수했습니다 마지막 활동 상태를?".

기본적으로 Android 는 활동에 상태가 있다고 간주 합니다. 활동 은애플리케이션 이 활동이 재개되었음을 활동 태스크 관리자 서비스에 보고 하면 상태 비 저장 상태 이는 애플리케이션 이 활동이 중지됨 상태에 있음을 프레임 워크에 알릴 때까지 유효합니다 . 간단하게 말하면, 값은 활동 사이 라고하며 혹은 , 호출 따라 적용 대상 버전.haveStatefalseonResume()onStop()onSaveInstanceState()

프로세스를 종료하면 Android가 프로세스를 다시 만들고 ActivityC를 만듭니다.

이 경우 ActivityD에는 android:stateNotNeeded="true"응용 프로그램 매니페스트에 속성 이 없으며 현재 포 그라운드에서 실행 중이므로 시스템이 마지막 상태가 아니기 때문에 Android는 기록에서 속성을 제거합니다.

안드로이드가 프로세스를 죽이는 것을 시뮬레이션하는 방법

여러 번 언급했듯이 단순히 응용 프로그램을 백그라운드로 이동하면 액티비티 백 스택의 최상위 활동이 상태를 저장 한 후 Android Debug Bridge, Android Studio 또는 응용 프로그램 프로세스를 사용하여 응용 프로그램 프로세스를 종료 할 수 있습니다 개발자 옵션의 백그라운드 프로세스 제한 특성 그 후 최근 활동이 성공적으로 재생성됩니다.

그럼에도 불구하고 응용 프로그램 프로세스 종료 시나리오를 테스트하는 또 다른 간단한 방법이 있습니다. 위에서 설명한 모든 사실과 현재 실행중인 ActivityD에서 새 ActivityE를 시작 onStop()하면 ActivityE onResume()메소드 후에 만 ActivityD 콜백이 호출 된다는 사실을 알고 다음 트릭을 수행 할 수 있습니다.

class TerminatorActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val isPrePie = applicationInfo.targetSdkVersion < Build.VERSION_CODES.P
        val callbacks = TerminatorLifecycleCallbacks(isPrePie)
        (applicationContext as Application).registerActivityLifecycleCallbacks(callbacks)
    }

    private class TerminatorLifecycleCallbacks(
        // Before P onSaveInstanceState() was called before onStop(), starting with P it's
        // called after
        // Used to schedule the death as app reports server that activity has stopped
        // after the latest of these was invoked
        private val isPrePie: Boolean
    ) : ActivityLifecycleCallbacksDefault {

        private val handler = Handler(Looper.getMainLooper())

        override fun onActivityPostStopped(activity: Activity) {
            if (isPrePie) {
                terminate()
            }
        }

        override fun onActivityPostSaveInstanceState(activity: Activity, outState: Bundle) {
            if (!isPrePie) {
                terminate()
            }
        }

        fun terminate() {
            handler.postDelayed(
                {
                    Process.killProcess(Process.myPid()) // This is the end... 
                },
                LAST_MILLIS
            )
        }

        companion object {
            // Let's wait for a while, so app can report and server can handle the update
            const val LAST_MILLIS = 100L
        }

    }

    private interface ActivityLifecycleCallbacksDefault : Application.ActivityLifecycleCallbacks {
        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
        override fun onActivityStarted(activity: Activity) {}
        override fun onActivityResumed(activity: Activity) {}
        override fun onActivityPaused(activity: Activity) {}
        override fun onActivityStopped(activity: Activity) {}
        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
        override fun onActivityDestroyed(activity: Activity) {}
    }
}

그런 다음 TerminatorActivity응용 프로그램을 종료하려고 할 때 시작 하십시오.

결국에는 응용 프로그램 프로세스 사망 테스트를 단순화하는 간단한 도구가 있습니다. Venom 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.