티스토리 뷰

액티비티는 처음 실행될 때 메모리에 만들어지는 과정부터 시작해서 실행과 중지, 그리고 메모리에서 해제되는 여러 과정의 상태 정보로 갖고 있으며, 이런 상태 정보는 시스템이 관리하면서 각각의 상태에 해당되는 메서드를 자동으로 호출한다. 

 

액티비티 위에 새로운 액티비티가 생성된다면 이전에 있는 액티비티는 액티비티 스택에 보관하다가 새로 생성된 액티비티가 사라지면 다시 이전 액티비티가 동작하는 과정을 거친다.

 

액티비티의 대표적인 상태 정보는 다음과 같다.

상태 설명
Running 화면 상에 액티비티가 보이면서 실행되고 있는 상태, 액티비티 스택의 최상위에 있으며 포커스를 가지고 있다.
Paused 사용자에게 보이지만 다른 액티비티가 위에 있어 포커스를 받지 못하는 상태, 대화 상자가 위에 있어 일부가 가려진 경우에 해당함
Stopped 다른 액티비티에 의해 완전히 가려져 보이지 않는 상태

 

아래는 액티비티에 생명주기에 따라 호출되는 메서드들을 정리한 것이이다.

 

액티비의 상태 메서드에 대한 상세한 설명은 다음과 같다.

 

onPause()와 onResume()의 경우는 앱이 멈추거나 없어절 때, 그리고 앱이 다시 보이거나 새로 실행될 때 사용되므로, 이 두가지 메서드가 실행될 때는 앱의 현재 상태를 저장하거나 이전 상태를 복원하여야 한다.

 

또한 onSaveInstanceState() 메서드를 사용하여 데이터를 임시로 저장할 수 있다. onSaveInstanceStete()메서드의 파라미터로 전달되는 번들 객체를 이용해 데이터를 저장하면 onCreate() 메서드나 onRestoreInstanceState() 메서드로 저장했던 데이터가 전달된다. 

 

이 방식을 사용하면 앱이 강제 종료되거나 비정상 종료된 이후에 앱이 재실행되었을 때도 그 상태 그대로 보일 수 있도록 만들어준다.

 

이제, 간단한 예제로 액티비티의 생명 주기를 한 번 확인해보자.


activity_main.xml 에 menu 액티비티를 띄울 수 있는 버튼 1개와 값을 입력할 수 있는 입력 창 하나를 생성한 뒤, 입력 창에 값을 입력하고 menu 액티비티를 띄우거나 어플을 닫았다가 다시 열었을 때 임시 저장한 값을 입력 창에 다시 넣어주는 예제이다.

 

◎MainActivity.java

package com.example.simplelifecycle;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    EditText nameInput;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        print("onDestroy 호출됨");
        nameInput = findViewById(R.id.editText);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), MenuActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        print("onStart 호출됨");
    }

    @Override
    protected void onStop() {
        super.onStop();
        print("onStop 호출됨");
    }

    @Override
    protected void onPause() {
        super.onPause();
        print("onPause 호출됨");
        saveState();
    }

    @Override
    protected void onResume() {
        super.onResume();
        print("onResume 호출됨");
        restoreState();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        print("onDestroy 호출됨");
    }

    public void print(String data) {
        Toast.makeText(this, data, Toast.LENGTH_LONG).show();
        Log.d("Main", data);
    }

    protected void restoreState() {
        SharedPreferences pref = getSharedPreferences("pref", Activity.MODE_PRIVATE);
        if((pref != null) && (pref.contains("name"))) {
            String name = pref.getString("name", "");
            nameInput.setText(name);
        }
    }

    protected void saveState() {
        SharedPreferences pref = getSharedPreferences("pref", Activity.MODE_PRIVATE);
        SharedPreferences.Editor editor = pref.edit();

        editor.putString("name", nameInput.getText().toString());
        editor.commit();
    }

    protected void clearState() {
        SharedPreferences pref = getSharedPreferences("pref", Activity.MODE_PRIVATE);
        SharedPreferences.Editor editor = pref.edit();

        editor.clear();
        editor.commit();
    }
}

위 코드에서 입력 값을 임시로 저장하기 위해 SharedPreferences 객체를 불러와 사용했는데, getSharedPreferences메서드는 첫번째 인자로 값이 저장될 SharedPreference의 이름을 설정하고, 두번째 인자로 모드를 받는다. 

Activity.MODE_PRIVATE 는 기본 값으로, 현재 어플에서만 해당 객체를 사용하겠다는 의미이다.

 

이후 edit() 메서드로 Editor 객체를 생성하고, Editor 객체에 데이터를 저장한다.


Comments