android 구글 안드로이드 - 응용 프로그램을 쫓아 내고 있습니까?





15 Answers

나는이 스레드의 미래 독자를 위해 여기에 수정을 추가하고 싶습니다. 이 특별한 뉘앙스가 내 이해를 오랫동안 벗어 났으므로 여러분 중 누구도 똑같은 실수를하지 않도록하고 싶습니다.

스택에 둘 이상의 활동이있는 경우 System.exit() 이 응용 프로그램을 종료하지 않습니다. 실제로 일어나는 일은 프로세스가 강제 종료되고 스택에서 한 번 적은 활동으로 즉시 재시작 된다는 입니다. Force Close 대화 상자를 통해 앱이 종료되거나 DDMS에서 프로세스를 종료하려고 할 때도 마찬가지입니다. 이것은 내가 아는 바에 따라 완전히 서류 미비 된 사실입니다.

간단히 말해서, 애플리케이션을 종료하려면 스택의 모든 활동을 추적하고 finish() 할 때 모든 작업을 finish() 해야합니다 (아니요, 반복 할 방법이 없습니다). 액티비티 스택이므로 모든 것을 직접 관리해야합니다. 심지어 이것이 실제로 프로세스 또는 사용자가 가질 수있는 매달린 참조를 죽이지는 않습니다. 단순히 활동을 끝내기 만하면됩니다. 또한, Process.killProcess(Process.myPid()) 가 더 잘 작동하는지 확실하지 않습니다. 나는 그것을 시험하지 않았다.

반면에 스택에 액티비티를 남겨 두는 것이 좋다면, Activity.moveTaskToBack(true) 는 프로세스를 배경으로하고 홈 화면을 표시하기 만하면됩니다.

긴 대답은이 행동 뒤에있는 철학에 대한 설명을 포함합니다. 이 철학은 여러 가지 가정에서 태어났다.

  1. 우선, 앱이 포 그라운드에있는 경우에만 발생합니다. 백그라운드에 있다면 프로세스가 정상적으로 종료됩니다. 그러나 포 그라운드에있는 경우 운영 체제는 사용자가 수행중인 작업을 계속 수행하려고한다고 가정합니다. (DDMS에서 프로세스를 종료하려는 경우 먼저 홈 단추를 누르고 죽여야합니다.)
  2. 또한 각 활동이 다른 모든 활동과 독립적이라고 가정합니다. 예를 들어 앱이 브라우저 활동을 시작한 경우 (예 : 완전히 분리되어 나와 작성되지 않은 경우)는 종종 사실입니다. 브라우저 활동은 매니페스트 특성에 따라 동일한 작업에서 생성되거나 생성되지 않을 수 있습니다.
  3. 귀하의 활동이 완전히 자립적이며 잠시 통고로 살해 / 복구 될 수 있다고 가정합니다. (오히려 onSaveInstanceState 동안 효율적으로 직렬화하기에는 너무 많은 캐시 된 데이터에 의존하는 많은 활동이 내 앱에 있기 때문에이 특정 가정을 싫어합니다.하지만 대부분 잘 작성된 Android 앱의 경우 사실이어야합니다. 왜냐하면 당신의 앱이 백그라운드에서 언제 죽게 될지 결코 알 수 없기 때문이다.
  4. 마지막 요소는 많은 가정이 아니라 오히려 OS의 한계입니다 . 앱을 명시 적으로 종료하는 것은 앱이 손상되는 것과 동일하며, Android가 메모리를 회수하기 위해 앱을 종료하는 것과 동일합니다. 앱이 종료되거나 추락했는지 여부를 안드로이드가 알 수 없기 때문에 사용자가 중단 한 부분을 반환하기를 원한다고 가정하기 때문에 ActivityManager가 프로세스를 다시 시작합니다.

생각할 때 이것은 플랫폼에 적합합니다. 첫째, 이것은 백그라운드에서 프로세스가 종료되고 사용자가 다시 돌아 왔을 때 발생하는 상황입니다. 따라서 중단 된 위치에서 다시 시작해야합니다. 둘째, 앱이 충돌하고 두려운 강제 닫기 대화 상자를 표시 할 때 발생합니다.

내 사용자가 사진을 찍어 업로드 할 수 있기를 바랍니다. 내 활동에서 Camera Activity를 실행하고 이미지를 반환하도록 요청합니다. 카메라가 현재 작업의 상단에 푸시됩니다 (자체 작업에서 생성되는 것이 아니라). 카메라에 오류가 발생하여 충돌이 발생하면 전체 응용 프로그램이 손상 될 수 있습니까? 사용자 입장에서는 카메라 만 실패하고 이전 활동으로 되돌려 야합니다. 따라서 스택에서 카메라를 제외한 모든 동일한 활동으로 프로세스를 다시 시작하기 만하면됩니다. 귀하의 활동 모자 한 방울에서 살해되고 복원 될 수 있도록 설계 되어야 하므로 문제가되지 않아야합니다. 불행히도, 모든 앱이 그런 식으로 디자인 될 수있는 것은 아니므로, Romain Guy 또는 다른 누구에게도 알려지지 않아도 많은 사람들이 문제가됩니다. 따라서 우리는 대안을 사용해야합니다.

그래서, 나의 마지막 조언 :

  • 그 과정을 죽이려고하지 마십시오. 모든 액티비티에 대해 finish() 를 호출하거나 moveTaskToBack(true) 호출 moveTaskToBack(true) .
  • 프로세스가 충돌하거나 죽게되면, 나처럼 현재 메모리에 있던 데이터가 필요하면 루트 작업으로 돌아 가야합니다. 이렇게하려면 Intent.FLAG_ACTIVITY_CLEAR_TOP 플래그가 포함 된 Intent와 함께 startActivity() 를 호출해야합니다.
  • Eclipse DDMS 관점에서 앱을 종료하려면 포 그라운드에 있지 않는 것이 좋으며, 그렇지 않으면 스스로 다시 시작됩니다. 먼저 홈 단추를 누른 다음 프로세스를 종료해야합니다.
download wiki pie

안드로이드를 배우려고 시도하면서 계속 전진 해 다음과 같이 읽었습니다 .

질문 : 메뉴 옵션을 죽이지 않으면 사용자가 응용 프로그램을 종료 할 수 있습니까? 그러한 옵션이없는 경우 사용자가 응용 프로그램을 어떻게 종료합니까?

답 : (Romain Guy) : 사용자가 자동으로 처리하지 않습니다. 이것이 활동 라이프 사이클 (특히 onPause / onStop / onDestroy)의 목적입니다. 당신이 무엇을 하든지, "quit"또는 "exit"application button을 넣지 마십시오. Android의 애플리케이션 모델에서는 쓸모가 없습니다. 이는 또한 핵심 응용 프로그램의 작동 방식과 상반됩니다.

Hehe, 내가 안드로이드 세계에 걸릴 모든 단계마다 나는 어떤 종류의 문제에 빠진다 = (

분명히 Android에서 애플리케이션을 종료 할 수는 없습니다 (하지만 안드로이드 시스템은 느낄 때마다 앱을 완전히 파괴 할 수 있습니다). 그게 뭐야? 나는 "정상적인 앱"으로 기능하는 앱을 작성하는 것이 불가능하다고 생각하기 시작했습니다. 사용자가 앱을 종료 할 때 그 앱을 종료 할 수 있다는 것입니다. 그것은 OS에 의존해야하는 것이 아닙니다.

내가 만들려고하는 응용 프로그램은 Android 마켓 용 응용 프로그램이 아닙니다. 그것은 일반 대중이 "폭넓게"사용할 수있는 응용 프로그램이 아니며 매우 좁은 비즈니스 분야에서 사용되는 비즈니스 응용 프로그램입니다.

Windows Mobile 및 .NET에 존재하는 많은 문제를 해결하기 때문에 Android 플랫폼을 실제로 개발할 것을 고대하고있었습니다. 그러나 지난 주에 나에게 다소 방해가되었습니다 ... 안드로이드를 버릴 필요는 없지만 지금은별로 좋아 보이지 않습니다. = (

신청서를 정말로 종료 할 수있는 방법이 있습니까?




응용 프로그램을 모 놀리 식 응용 프로그램으로 생각하지 마십시오. 그것은 사용자가 귀하의 "응용 프로그램"과 상호 작용할 수있는 UI 화면 세트이며 안드로이드 서비스를 통해 제공되는 "기능"입니다.

신비한 앱이하는 일이 무엇인지 알지 못하는 것은 정말로 중요하지 않습니다. 사용자가 "응용 프로그램을 종료 할 때까지 일부 모니터링 또는 상호 작용을 수행하고 로그인 된 상태로 유지되는 일부 보안이 안전한 회사 인트라넷에 있다고 가정 해 봅시다. IT 부서에서 명령을 내리기 때문에 사용자는 인트라넷에서 언제 또는 언제 인하는지 매우 숙지해야합니다. 따라서 사용자가 "종료"하는 것이 중요합니다.

이것은 간단합니다. 알림 표시 줄에 "나는 인트라넷에 있거나 실행 중입니다."라는 알림을 보내는 서비스를 만듭니다. 해당 서비스에서 응용 프로그램에 필요한 모든 기능을 수행하도록하십시오. 사용자가 "응용 프로그램"과 상호 작용할 수있는 UI 비트에 액세스 할 수 있도록 해당 서비스에 바인딩하는 활동을하십시오. Android 메뉴를 종료하려면 -> 서비스 종료를 알리는 종료 (또는 로그 아웃 또는 기타) 버튼을 클릭 한 다음 활동 자체를 닫습니다.

이것은 모든 의도와 목적에 맞게 정확히 말하고 싶은 것입니다. Android 방식으로 완료되었습니다. Google 토크 나 Google지도 내비게이션을 보면이 "이탈"의 예가 가능한 사고 방식입니다. 유일한 차이점은 사용자가 응용 프로그램을 다시 작동시키려는 경우에 대비하여 활동에서 단추를 뒤로 밀면 UNIX 프로세스가 대기 상태에 빠질 수 있습니다. 이것은 실제로 메모리에 최근에 액세스 한 파일을 캐시하는 현대적인 운영 체제와 다르지 않습니다. Windows 프로그램을 종료 한 후 필요한 리소스는 여전히 메모리에 남아 있으므로 더 이상 필요없는 다른 리소스로 대체되기를 기다리고 있습니다. Android도 마찬가지입니다.

나는 정말로 당신의 문제를 보지 못합니다.




뒤로 단추를 누르거나 Activity 에서 finish() 를 호출하여 종료 있습니다 . 명시 적으로 제거하려는 경우 MenuItem 에서 finish() 를 호출하기 만하면됩니다.

Romain은 그것을 끝낼 수 없다는 말은 아니며 단지 무의미한 것입니다. 사용자는 응용 프로그램 수명주기 작동 방식에 따라 자동 저장 및 저장하는 스마트 소프트웨어를 작성하도록 권장하므로 업무를 중단하거나 저장하는 데 신경을 쓸 필요가 없습니다. 무슨 일이 있어도 상태를 복원합니다.




테드, 당신이 성취하고자하는 것은 지금 당장 생각하고있는 방법이 아니라 아마도 끝낼 수 있습니다.

나는 당신이 활동과 서비스에 대해 읽어 보길 권한다. "앱"이라는 용어 사용을 중단하고 구성 요소 (예 : 활동, 서비스)를 시작하십시오. Android 플랫폼에 대해 더 많이 배워야한다고 생각합니다. 그것은 표준 PC 응용 프로그램에서 사고 방식의 변화입니다. 귀하의 게시물 중 아무도 "활동"이라는 단어가 없다는 사실 (사실, 귀하의 단어가 아닌)은 귀하가 좀 더 읽을 필요가 있음을 알려줍니다.




나는 당신이 버그가있는 소프트웨어를 가지고 있지 않다면 애플 리케이션을 종료 할 필요가 없다는 것이 중요하다고 생각한다. 사용자가 앱을 사용하지 않고 기기에 더 많은 메모리가 필요한 경우 Android가 앱을 종료합니다. 백그라운드에서 서비스를 실행해야하는 앱이있는 경우 서비스를 사용 중지 할 수 있습니다.

예를 들어 Google Listen은 앱이 표시되지 않을 때 계속 팟 캐스트를 재생합니다. 그러나 사용자가 Podcast를 끝내면 Podcast를 끄는 일시 중지 버튼이 항상 있습니다. 필자가 올바르게 기억하면 '듣기 (Listen)'는 알림 표시 줄에 바로 가기를 추가하여 항상 일시 중지 버튼을 빠르게 얻을 수 있습니다. 또 다른 예는 끊임없이 인터넷에서 서비스를 조사하는 트위터 앱과 같은 앱입니다. 이러한 유형의 앱은 실제로 사용자가 서버를 폴링하는 빈도를 선택하거나 백그라운드 스레드에서 폴링할지 여부를 선택할 수 있어야합니다.

끝낼 때 실행되는 코드가 필요할 경우 onPause (), onStop () 또는 onDestroy ()를 적절하게 재정의 할 수 있습니다. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle




Addison-Wesley가 발행 한 "Android 무선 애플리케이션 개발"을 읽는 것을 고려할 것 입니다. 나는 그것을 끝내고 있고 그것은 아주 철저하다.

Android 플랫폼에 대한 근본적인 오해가있는 것으로 보입니다. 저도 처음 엔 Android 앱의 애플리케이션 라이프 사이클에 조금 좌절감을 나타 냈습니다. 그러나 더 큰 이해를 얻은 후에 저는이 접근법을 정말로 즐기기 위해 왔습니다. 이 책은 모든 질문에 대한 답변을 제공합니다. 그것은 정말로 내가 새로운 안드로이드 개발자를 위해 찾은 최고의 리소스입니다.

또한 기존 앱의 line-for-line 포트를 놓아 줘야한다고 생각합니다. 애플리케이션을 Android 플랫폼에 이식하려면 일부 애플리케이션 디자인이 변경 될 것입니다. 모바일 장치는 데스크톱 시스템에 비해 리소스가 매우 제한적이므로 Android 장치가 순서 있고 리소스를 인식하는 방식으로 여러 응용 프로그램을 실행할 수 있으므로 사용되는 응용 프로그램 수명주기가 필요합니다. 플랫폼에 대한 깊이있는 연구를 좀 더 해보십시오. 당신이하고 싶은 것이 전적으로 실현 가능하다는 것을 깨닫게 될 것입니다. 행운을 빕니다.

덧붙여서, 나는 Addison-Wesley 또는이 책과 관련된 사람이나 단체와 아무런 관계가 없습니다. 내 게시물을 다시 읽은 후 나는 조금 fanboyish 떨어져 왔다고 느낀다. 나는 정말로, 정말로 그것을 즐겼고, 그것이 매우 도움이되는 것을 알았다. :)




시간의 거의 99 %가 안드로이드 애플리케이션이 자체 라이프 사이클을 인수 할 필요가 없습니다. 대부분의 경우 응용 프로그램의보다 나은 계획 또는 더 똑똑한 디자인이 필요합니다. 예를 들어 다운로드 등을 처리하거나 사용자 워크 플로와 관련된 작업 및 작업을 디자인하기 위해 내부 서비스 (내보내기되지 않음)를 작성하십시오.

그러나 그것이 유언장이있는 곳에서는 방법이있다. 안드로이드는 - android.os.Process 클래스를 통해 자바보다 훨씬 나은 API를 제공하여 기본 프로세스를 제어합니다. 자바와 달리 개발자는 단순한 java.lang.System.exit () 호출 뒤에 모든 것을 숨겨서 바보처럼 취급하지 않는다.

그렇다면 Android에서 자살을 신청하는 방법은 무엇입니까? 자, 트릭은 간단합니다.

표준 android.app.Application 클래스를 상속 받아 자신 만의 Android 애플리케이션 클래스를 작성하십시오 (AndroidManifest.xml 파일에서 선언해야 함).

onCreate () 메서드를 재정의하고 응용 프로그램을 시작한 프로세스 ID를 저장합니다.

this.pid = android.os.Process.myPid(); // Save for later use.

이제 응용 프로그램을 종료하려면 kill () 메소드를 제공하십시오.

android.os.Process.sendSignal(pid, android.os.Process.SIGNAL_KILL);

이제 자살을 위해 앱이 필요할 때마다 애플리케이션 컨텍스트를 입력하고 kill 메소드를 호출하십시오!

((MySuicidalApp) context.getApplicationContext()).kill()

Android의 프로세스 관리 정책, 특히 서비스와 관련된 서비스 때문에 Android는 서비스를 다시 시작하기 만 할 수도 있습니다 ( Android에서 작업 킬러를 사용하면 안됨을 참조하십시오 ).




음 ...

나는 당신이 안드로이드 애플 리케이션을 올바른 방법으로 보지 못한다고 생각한다. 원하는 것을 쉽게 할 수 있습니다.

  • 개발자의 라이브 사이클 문서에서 권장하는 것처럼 앱 활동이 상태를 저장 / 복원합니까?

  • 복원 단계에서 일부 로그인이 필요한 경우 (사용 가능한 로그인 / 세션 정보가 없음) 그런 다음 수행하십시오.

  • 결국 버튼 / 메뉴 / 타임 아웃을 추가 finish()하면 로그인 및 기타 세션 정보를 저장하지 않고 암시 적으로 앱 세션이 종료됩니다. 따라서 앱이 시작 / 다시 시작되면 새로운 세션이 시작됩니다.

그렇게하면 앱이 실제로 메모리에서 제거되는지 아닌지 신경 쓰지 않아도됩니다.

당신이 정말로 메모리에서 제거하려면 (이 어떤 목적을 위해 BTW 낙담하고있다?) 당신의 말에 조건을 죽일 수 onDestroy()java.lang.System.exit(0)(혹은 restartPackage(..)?). 물론 앱이 실제로 onDestroy()정상적으로 종료되기를 원하는 경우에만 수행하십시오. 앱 의 정상적인 라이프 사이클의 일부이며 앱의 종료가 아니기 때문 입니다.




리눅스 커널은 Out-of-memory killer 라고 불리는 기능을 가지고있다. (위에서 언급했듯이, 정책은 사용자 공간 수준에서 구성 할 수있을뿐 아니라 커널은 최적의 것이 아니라 불필요한 것이 아니다.)

그리고 그것은 안드로이드에서 많이 사용됩니다 :

일부 사용자 공간 앱은 다음과 같이 이러한 킬 (kill) 앱을 지원할 수 있습니다.




나는 Ted와 동의한다. 애플리케이션을 종료하는 것이 'Android 방식'이 아니라는 것을 이해합니다. 그러나 배제해야하는 것처럼 보이지는 않습니다. 액티비티뿐만 아니라 애플리케이션으로의 실제 이탈을 원하는 세 가지 이유는 다음과 같습니다.

  1. 사용자는 메모리가 부족한 경우 앱이 종료되는 것을 제어 할 수 있습니다. 중요한 응용 프로그램 A가 백그라운드에서 실행중인 경우, 응용 프로그램 A가 운영 체제에 의해 종료되지 않도록 응용 프로그램 B를 끝내고 나면 응용 프로그램 B를 종료 할 수 있습니다.

  2. 응용 프로그램에 중요한 데이터가 메모리에 캐시되어있는 경우 바이러스 / 웜 / 악성 앱이 침입 할 수 없도록 응용 프로그램을 종료 할 수 있습니다. 나는 보안 모델이 그것을 방지하기로되어 있다는 것을 알고 있지만 다만 ...

  3. 응용 프로그램이 전화에 나쁜 영향을 미칠 수있는 자원 (예 : 네트워크, CPU, 센서 등)을 사용하는 경우 해당 자원을 확보하는 한 가지 방법은 응용 프로그램을 종료하는 것입니다. 잘 작동하는 앱은 필요하지 않을 때 리소스를 확보해야한다는 것을 알고 있습니다. 그러나 다시 한 번, 응용 프로그램을 종료하면이를 보장하는 합리적인 방법처럼 보입니다.




시간이 지남에 따라 상황이 바뀌기를 바랍니다. 앱 프로세스가 OS에 의해 올바르게 샌드 박싱되면 사용자는 앱이나 프로세스를 종료 할 수 있어야합니다. 앱을 완벽하게 작성해야한다는 생각이 들거나 사용자가 모든 SDK 권장 사항을 따르는 앱만 사용하게됩니다. 나는 그것이 큰 명령이라고 생각한다.




응용 프로그램 개발자가 자체 응용 프로그램을 종료 할 수있는 종료 기능이 없으면 이는 매우 나쁜 설계입니다.

내 응용 프로그램은 사용자가 동적으로 데이터를 동적으로 변경하도록 허용해야하며 변경 효과를 적용하려면 사용자가 응용 프로그램을 다시 시작해야하지만 Android는 응용 프로그램을 다시 시작할 수 없습니다. Android OS의 디자인 응용 프로그램 수명주기가 매우 나쁩니다.




어떤 시점에서 앱을 종료하려면 FLAG_ACTIVITY_CLEAR_TOPIntent에서 플래그를 사용 하고 그 다음에system.exit();

또는 비슷한 방법이 있지만 system.exit()이 메서드를 종료 할 때 제외 할 :

public void exit() {
    startActivity(new Intent(this, HomeActivity.class).
    setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK).putExtra(EXIT_FLAG, true));
}

HomeActivity.onCreate()다음 코드를 추가 하십시오.

protected void onCreate(Bundle savedInstanceState) {
    if (getIntent().getBooleanExtra(EXIT_FLAG, false)) {
        if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
            finish();
        }
    }
......................

이것은 Android 라이프 사이클을 깨지 않고 작동합니다.




Android 애플리케이션 라이프 사이클은 컴퓨터 사용자가 아닌 휴대 전화 사용자를 위해 설계되었습니다.

앱 수명주기는 Linux 서버를 소비자 어플라이언스로 바꾸는 데 필요한 잔인하게 단순한 패러다임입니다.

안드로이드는 실제 플랫폼 간 서버 OS 인 Linux over Java입니다. 그것이 그렇게 빨리 퍼지는 방법입니다. 앱 라이프 사이클은 OS의 기본 현실을 캡슐화합니다.

모바일 사용자에게는 앱이 설치되었거나 설치되지 않았습니다. 실행 또는 종료의 개념은 없습니다. 사실, app 프로세스는 운영체제가 보유한 리소스를 위해 OS를 릴리스 할 때까지 실행됩니다.

스택 오버플로이므로이 내용을 읽는 사람은 컴퓨터 사용자이므로 모바일 앱 수명주기를 이해하려면 지식의 90 %를 꺼야합니다.




10,20 .. 여러 활동이 실행 중이고 모두 끝내고 시스템에서 나가기를 원한다면

application class또는에 정적 배열 만들기constants class.

상수

public class Constants {

public static ArrayList<Activity> activities = new ArrayList<Activity>();

}

MainActivity 이 배열에 현재 활동 참조 추가

activity = MainActivity.this; Constants.activities.add(activity);

public class MainActivity extends Activity {

    private ImageView imageButton;
    private Activity activity;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        activity = MainActivity.this;
        Constants.activities.add(activity);

        imageButton = (ImageView) findViewById(R.id.camera);
        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // existing app.
                if (Constants.activities != null) {
                    for (int i = 0; i < Constants.activities.size(); i++) {
                        Activity s = Constants.activities.get(i);
                        s.finish();
                    }
                }
                //super.finish();
                finish();
                android.os.Process.killProcess(android.os.Process.myPid());
                System.exit(1);
            }
        });
    }
}



Related


Tags

android