Activity.finish () 메소드는 정확히 무엇을합니까?


156

한동안 안드로이드 응용 프로그램을 개발 중이며 활동 수명주기 및 응용 프로그램 수명주기에 대한 많은 게시물을 따랐습니다.

나는 Activity.finish()메소드 호출을 어딘가에 호출 Activity.onDestroy()하고 스택에서 액티비티를 제거한다는 것을 알고 있으며, 어떻게 든 운영 체제와 가비지 콜렉터가 "트릭을 수행하고"좋은 시간이되면 메모리를 확보 할 수 있다고 생각합니다. 그래서....

이 게시물에 왔습니다- 응용 프로그램을 종료하는 것은 눈살을 찌푸리고 있습니까? Mark Murphy의 답변을 읽으십시오.

정확히 finish()방법이 실제로 하는 일에 대해 약간 혼란 스러웠습니다 .

내가 전화 할게 기회가 있습니까 finish()onDestroy()호출되지 않습니다는?


답변:


171

finish()활동을 호출 하면 메소드 onDestroy()가 실행됩니다. 이 방법은 다음과 같은 작업을 수행 할 수 있습니다.

  1. 활동이 관리하고있는 대화를 닫습니다.
  2. 활동이 관리하고있는 커서를 닫으십시오.
  3. 열려있는 검색 대화 상자를 모두 닫습니다.

또한 onDestroy()소멸자가 아닙니다. 실제로 객체를 파괴하지는 않습니다. 특정 상태에 따라 호출되는 메소드 일뿐입니다. 따라서 슈퍼 클래스가 onDestroy()실행되고 돌아온 후에도 인스턴스는 여전히 살아 있고 매우 잘 * 사용 됩니다. 프로세스가 수행하지 않고 메모리를 회수해야하는 경우 프로세스가 종료됩니다.


5
그래서 finish () 메소드 만 onDestroy () 호출을 트리거하고 그게 전부입니까?
탈 카넬

9
예, Activity로 돌아 오면 onCreate ()가 호출됩니다.
Luis Pena

9
finish ()도 onPause () 및 onStop ()을 호출합니까?
sr09

36
다시 테스트 한 결과 finish ()를 호출 한 후 onPause (), onStop () 및 onDestroy ()가 모두 순서대로 호출됩니다.
Sam003

5
@Laurent onPause () 및 onStop ()이 항상 호출되는 것은 아닙니다. 아래 답변에서 내 관찰을 참조하십시오
Prakash

77

@K_Anas에서 내 2 센트가 대답합니다. finish () 메소드에서 간단한 테스트를 수행했습니다. 활동 수명주기에서 중요한 콜백 메소드 나열

  1. onCreate ()에서 finish () 호출 : onCreate ()-> onDestroy ()
  2. onStart ()에서 finish () 호출 : onCreate ()-> onStart ()-> onStop ()-> onDestroy ()
  3. onResume ()에서 finish () 호출 : onCreate ()-> onStart ()-> onResume ()-> onPause ()-> onStop ()-> onDestroy ()

내가 말하고자하는 것은 finish ()가 실행될 때 사이에있는 메소드와 함께 메소드의 대응 부분이 호출된다는 것입니다.

예 :

 onCreate() counter part is onDestroy()
 onStart() counter part is onStop()
 onPause() counter part is onResume()

onPause 내부에서 finish를 호출하면 어떻게됩니까? onStop> onDestroy?를 호출합니다.
rmpt

이 테이블은 정말 유용하고 설명 적입니다. (좀 아래로 스크롤해야합니다) developer.android.com/reference/android/app/…
winklerrr

본인은이 답변이 올바른지 확인했습니다.
Sreekanth Karumanaghat '12

33

의도 후 finish ()를 호출하면 "뒤로"버튼으로 이전 활동으로 돌아갈 수 없습니다.

startActivity(intent);
finish();

이것은 내가 구글 드라이브에만 연결하는 활동이 있기 때문에 필요한 정보입니다. 그런 다음 점검을 수행하고 기본 활동 (또는 오류가있는 경우 설정 활동)으로 이동하므로 사용자는 돌아갈 수 없습니다.
Francesco Marchetti-Stasi

1
@Francesco Marchetti-Stasi 귀하의 경우 다시 돌아 가지 않아야하는 경우 onBackPressed ()를 재정의하고 super.onBackPressed ()를 호출하지 않는 것이 좋습니다.
Paul

13

onDestroy()최종 정리를위한 것입니다. 자신이 직접 할 수있는 리소스를 확보하고 열린 연결, 리더, 작성자 등을 닫습니다. 재정의하지 않으면 시스템이 필요한 작업을 수행합니다.

반면에, finish()프로그래머에게 전류 Activity가 완료 되기를 원한다는 것을 시스템에 알리십시오 . 따라서 onDestroy()그 후에 호출됩니다 .

주목할 사항 :

그것은 그 필요는 없습니다 의 호출 finish()트리거 호출에 onDestroy(). 아시다시피, 안드로이드 시스템은 Activity해제 해야하는 전류에 필요한 리소스가 있다고 생각되면 활동 을 자유롭게 종료 할 수 있습니다.


1
finish ()는 시스템에 활동 완료가 필요하다는 것을 알려주었습니다. "do x = 시스템에게 x를하도록 지시하십시오"라고 말하는 것과 같습니다. 초 것 : 귀하의 답변에서 finish ()를 호출하는 방법이있는 것처럼 들리며 시스템은 onDestroy ()를 호출하지 않기로 결정합니까? 가능합니까?
탈 카넬

첫 번째 부분이 맞았습니다. 호출 finish()하면 시스템에을 (를) 완료하라는 메시지가 표시됩니다 Activity. do 문의 "x"부분은 "완료 (파기) Activity"입니다. 두 번째 부분이 잘못되었습니다. 사실, 나는 거기에서 한 마디도 놓쳤다. 답변을 편집했습니다. onDestroy()에 의해 트리거되는 것이 아니라 finish()시스템이 자체적으로 호출 할 수도 있습니다.
Kazekage Gaara 2016 년

1
답변에 추가 한 내용을 읽었습니다. 지금까지 나는 당신의 설명이 흥미로운 것을 발견 한 답을 찾았습니다. 그러나 "응답 된"것으로 표시하기 전에 다른 사람들이 그것에 대해 말할 다른 것이 있는지 알고 싶습니다. 주셔서 감사합니다 :)
Tal Kanel

따라서 finish () 후에이 활동의 ​​모든 변수가 파괴됩니다. 이 활동으로 다시 돌아 오면 다시 선언되거나 초기화됩니다.
Sibbs Gambling

3
참고 : 시스템이 프로세스를 종료하면 onDestroy가 호출되지 않을 수 있습니다. developer.android.com/reference/android/app/…
Kevin Lee

9

Finish () 메소드는 현재 활동을 파괴합니다. 사용자가 뒤로 버튼을 누를 때이 활동을 다시로드하지 않으려는 경우이 방법을 사용할 수 있습니다. 기본적으로 현재 스택에서 활동을 지 웁니다.


8

위의 @rommex 답변 외에도 finish()활동 파괴가 대기하고 활동 우선 순위에 달려 있음을 알았 습니다.

finish()이후 onPause()에 전화하면이 표시 onStop()되고 onDestroy()즉시 전화했습니다.

finish()이후 onStop()에 전화하면 onDestroy()5 분 후에 는 표시되지 않습니다 .

내 관찰에 따르면, 마무리가 대기중인 것처럼 보이고 그것을 보았을 때로 adb shell dumpsys activity activities설정 finishing=true되었지만 더 이상 포 그라운드에 없기 때문에 파괴 우선 순위가 지정되지 않았습니다.

요약하면 onDestroy()호출이 보장되지는 않지만 호출 된 경우에도 지연 될 수 있습니다.


5

다양한 답변과 메모에 따르면 finish ()는 onPause () 및 onStop ()을 건너 뛰고 onDestroy ()를 직접 실행할 수 있다고 주장합니다. 공평하게 말하면, 이것에 대한 Android 문서 ( http://developer.android.com/reference/android/app/Activity.html )는 "활동이 시스템에 의해 마무리되거나 파괴되고 있습니다"라고 지적하지만 상당히 모호하지만 finish ()는 onDestroy ()로 이동할 수 있습니다.

finish ()의 JavaDoc은 비슷하게 실망스럽고 ( http://developer.android.com/reference/android/app/Activity.html#finish () ) 실제로 종료에 대한 응답으로 어떤 메소드가 호출되는지 기록하지 않습니다. ().

그래서이 미니 응용 프로그램을 아래에 작성하여 진입시 각 상태를 기록합니다. finish ()를 호출하는 버튼이 포함되어있어 어떤 메소드의 로그가 실행되는지 확인할 수 있습니다. 이 실험은 finish () 가 실제로 onPause () 및 onStop ()을 호출 한다고 제안했습니다 . 내가 얻는 결과는 다음과 같습니다.

2170-2170/? D/LIFECYCLE_DEMO INSIDE: onCreate
2170-2170/? D/LIFECYCLE_DEMO INSIDE: onStart
2170-2170/? D/LIFECYCLE_DEMO INSIDE: onResume
2170-2170/? D/LIFECYCLE_DEMO User just clicked button to initiate finish() 
2170-2170/? D/LIFECYCLE_DEMO INSIDE: onPause
2170-2170/? D/LIFECYCLE_DEMO INSIDE: onStop 
2170-2170/? D/LIFECYCLE_DEMO INSIDE: onDestroy

package com.mvvg.apps.lifecycle;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

public class AndroidLifecycle extends Activity {

    private static final String TAG = "LIFECYCLE_DEMO";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "INSIDE: onCreate");
        setContentView(R.layout.activity_main);
        LinearLayout layout = (LinearLayout) findViewById(R.id.myId);
        Button button = new Button(this);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View view) {
                Toast.makeText(AndroidLifecycle.this, "Initiating finish()",
                        Toast.LENGTH_SHORT).show();
                Log.d(TAG, "User just clicked button to initiate finish()");
                finish();
            }

        });

        layout.addView(button);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "INSIDE: onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "INSIDE: onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "INSIDE: onDestroy");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "INSIDE: onPause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "INSIDE: onResume");
    }

}

3

@ user3282164 활동 라이프 사이클에 따라 호출시 onPause()-> onStop()-> onDestroy()를 거쳐야합니다 finish().

다이어그램은 onDestroy()시스템으로 인한 [활동 실행]에서 [ ] 까지의 직선 경로를 보여주지 않습니다 .

onStop () doc는 " onPause () 메소드가 호출 된 후 활동 프로세스를 실행할 메모리가 부족한 메모리가 부족한 상황에서는 이 메소드를 호출 할 수 없습니다 . "



2

내 연구에 따르면이 finish()방법은 실제로 일부 파괴 작업을 대기열에 배치하지만 활동이 즉시 파괴되지는 않습니다. 그러나 파기는 예정되어 있습니다.

당신이 배치 예를 들어, finish()onActivityResult()동안, 콜백 onResume()실행하는 데 아직, 먼저 onResume()만 그 후, 실행됩니다 onStop()onDestroy()이라고합니다.

참고 : 설명서에onDestroy() 명시된대로 호출되지 않을 수 있습니다 .


2

onCreate ()에서 finish를 호출하면 @prakash가 말한 것처럼 onDestroy ()를 직접 호출하지 않습니다. finish()당신은 안드로이드에 제어를 리턴 할 때까지 작업도 시작되지 않습니다.

onCreate ()에서 finish () 호출 : onCreate ()-> onStart ()-> onResume () . 사용자가 종료하면 앱이 -> onPause ()-> onStop ()-> onDestroy ()를 호출합니다.

onStart ()에서 finish () 호출 : onCreate ()-> onStart ()-> onStop ()-> onDestroy ()

onResume ()에서 finish () 호출 : onCreate ()-> onStart ()-> onResume ()-> onPause ()-> onStop ()-> onDestroy ()

자세한 참조 확인을 위해 마무리 후 연속finish ()


0

지금까지 romnex는 "onDestroy ()가 전혀 호출되지 않을 수도 있습니다"라는 정답을 제시 한 것 같습니다. 실제로는 거의 모든 경우에 그럴 것이라고 보장 할 수는 없습니다. finish ()에 대한 문서 는 활동 결과가 호출자에게 다시 전파된다고 약속하지만 더 이상은 아닙니다. 또한 수명주기 설명서에 따르면 onStop ()이 완료 되 자마자 (또는 구형 장치에서는 더 이른 경우) OS에서 활동을 종료 할 수 있다는 사실이 명시되어 있습니다. onDestroy ()가 실행되는 동안 또는 실행되기 전에 종료 될 수 있습니다.

따라서 finish ()를 호출 할 때 일부 작업이 완료되도록하려면 onDestroy ()에 넣을 수 없지만 실제로 호출하기 직전에 finish ()를 호출하는 동일한 위치에서 수행해야합니다.


-4

finish ()는 안드로이드에서 이전 활동으로 다시 보내거나 응용 프로그램에서 한 단계 뒤로 가고 있다고 말할 수 있습니다.

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