안드로이드 LifeCycle에 대한 밍기적

Posted by : at

Category : Android


 

네이버, 카카오 면접을 대비해 android 공부를 하며 작성하게 되었다.

Life Cycle에 관련된 내용으로 Activity가 실행될 때 어떤 메소드들이 호출되는지 함께 알아보자

먼저 전체 Life Cycle를 그림으로 살펴보자!

 

Life Cycle

 

우리가 앱을 실행시키고 화면에 보이기까지 무려 3가지 메소드가 호출된다.

onCreate -> onStart -> onResume

onCreate

  • 화면이 메모리에 만들어지고 여러 초기화 과정을 진행하게 된다.

onStart

  • 화면 기능을 실행할 준비를 한다.

onResume

  • activity가 화면 맨 앞에서(foreground) 동작 중인 상태로 사용자와 상호작용을 한다.

 

이후 Activity가 종료될 때 3가지 메소드가 호출된다.

onPause -> onStop -> onDestroy

onPause

  • 사용자가 activity를 벗어나게 되면 제일 먼저 호출되는 메소드이다.

부분적으로 activity가 가려진 상태로 메모리가 부족하면 강제 종료될 수도 있다.

onStop

  • 이번에는 activity가 완전히 가려진 상태이다. 메모리가 부족하면 우선적으로 강제종료된다.

onDestroy

  • Activity가 소멸되기 전에 호출된다

onStop 상태에서 다시 activity로 돌아갈 경우 onRestart라는 메소드를 호출하게 된다.

 

이렇게 간략하게 7가지 메소드를 살펴보았다. 그러나 살펴보는 것만으로는 머리에 남지 않는다.

그래서 준비했다.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.i("MainActivity","This is onCreate Method");
}

이런 식으로 7가지 메소드에 대해서 전부 Log를 남긴다.

참고로 Log에는 5가지 종류가 있다.(Log.e(), Log.w(), Log.i(), Log.d(), Log.v())

error, warning, info, debug, verbose

앱을 실행시키면 다음과 같이 나온다.

2020-10-21 15:35:15.479 17645-17645/com.example.lifecycle I/MainActivity: This is onCreate Method
2020-10-21 15:35:15.481 17645-17645/com.example.lifecycle I/MainActivity: This is onStart Method
2020-10-21 15:35:15.483 17645-17645/com.example.lifecycle I/MainActivity: This is onResume Method

이제 종료시켜보자.

2020-10-21 15:35:55.659 17645-17645/com.example.lifecycle I/MainActivity: This is onPause Method
2020-10-21 15:35:56.231 17645-17645/com.example.lifecycle I/MainActivity: This is onStop Method
2020-10-21 15:35:56.231 17645-17645/com.example.lifecycle I/MainActivity: This is onDestroy Method

우리가 배운 그대로이다. 그렇다면 Home버튼을 누르면 어떻게 될까?

2020-10-21 15:36:34.845 17899-17899/com.example.lifecycle I/MainActivity: This is onPause Method
2020-10-21 15:36:34.860 17899-17899/com.example.lifecycle I/MainActivity: This is onStop Method

다시 앱을 실행시켜보자.

2020-10-21 15:37:16.660 17899-17899/com.example.lifecycle I/MainActivity: This is onRestart Method
2020-10-21 15:37:16.661 17899-17899/com.example.lifecycle I/MainActivity: This is onStart Method
2020-10-21 15:37:16.663 17899-17899/com.example.lifecycle I/MainActivity: This is onResume Method

 

대충 어떤 느낌인지 감이 오는가? 그러나 여기서 만족하면 안 된다.

우리가 할 법한 행동은 다 해봐야한다. 만약 화면을 회전시키면 어떻게 될까?

한 번 예상해보고 답을 보자! 놀랍게도 다음과 같다.

2020-10-21 15:39:28.862 17899-17899/com.example.lifecycle I/MainActivity: This is onPause Method
2020-10-21 15:39:28.874 17899-17899/com.example.lifecycle I/MainActivity: This is onStop Method
2020-10-21 15:39:28.874 17899-17899/com.example.lifecycle I/MainActivity: This is onDestroy Method
2020-10-21 15:39:28.957 17899-17899/com.example.lifecycle I/MainActivity: This is onCreate Method
2020-10-21 15:39:28.961 17899-17899/com.example.lifecycle I/MainActivity: This is onStart Method
2020-10-21 15:39:28.965 17899-17899/com.example.lifecycle I/MainActivity: This is onResume Method

 

간단히 설명하자면 가로 화면에서 세로 화면으로 바뀌면 기존의 Activity를 다 지우고 새로 만들게 된다.

위의 3개의 메소드는 가로 화면을 지우기 위해 밑에 3개의 메소드는 세로 화면을 새롭게 만들기 위해 호출되었다.

그러면 여기서 문제! 다음과 같이 +버튼을 누르면 숫자가 올라가는 앱을 개발했다고 치자.

Life Cycle  Life Cycle

 

숫자를 열심히 올리고 화면을 회전시키면 어떻게 될까? 결과는 다음과 같다.

 

Life Cycle

 

화면을 돌리니 기존의 data가 다 날아가서 너무 슬프다…ㅠㅠ

이럴 때를 대비해서 똑똑한 선배들이 만들어둔 메소드들이 있다.

  • protected void onSaveInstanceState(@NonNull Bundle outState)

  • protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState)

onPause 메소드가 호출된 다음 onSaveInstanceState를 호출하여 data를 저장한다. 저장하는 방식은

Intent와 비슷하다. 그 후 onStart 메소드가 호출된 뒤 onRestoreInstanceState가 호출되면서 기존의 데이터를 유지할 수 있게 된다.

 

전체 코드를 보면서 한 번씩 따라해보면 면접 때까지는 기억에 남을 것이다.

package com.example.lifecycle;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Button bt_next;
    Button bt_plus;
    TextView tv_cnt;
    int cnt;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bt_next = (Button)findViewById(R.id.bt_next);
        bt_plus = (Button)findViewById(R.id.bt_plus);
        tv_cnt = (TextView)findViewById(R.id.tv_cnt);
        bt_next.setOnClickListener(onClickListener);
        bt_plus.setOnClickListener(onClickListener);

        Log.i("MainActivity","This is onCreate Method");
    }


    View.OnClickListener onClickListener = new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.bt_next:
                    Intent intent = new Intent(MainActivity.this, MainActivity2.class);
                    startActivity(intent);
                    break;
                case R.id.bt_plus:
                    cnt = Integer.parseInt(tv_cnt.getText().toString())+1;
                    tv_cnt.setText(String.valueOf(cnt));
                    break;
            }

        }
    };

    @Override
    protected void onStart() {
        super.onStart();
        Log.i("MainActivity","This is onStart Method");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("MainActivity","This is onRestart Method");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i("MainActivity","This is onStop Method");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("MainActivity","This is onDestroy Method");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i("MainActivity","This is onPause Method");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i("MainActivity","This is onResume Method");
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.i("MainActivity","This is onSaveInstanceState Method");
        outState.putInt("count",cnt);
    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.i("MainActivity","This is onRestoreInstanceState Method");
        cnt = savedInstanceState.getInt("count");
        tv_cnt.setText(String.valueOf(cnt));
    }
}

About GJ

안녕하세요 방문해주셔서 감사합니다. 혹시 보시면서 궁금하신것 있으시면 https://open.kakao.com/o/sivaz71c로 연락주세용~

Star
Useful Links