10-1 태스크 관리 이해하기
앱을 실행하면 그 앱은 하나의 프로세스 위에서 동작한다. 예전 글에서 앱에서 시스템으로 인텐트를 보내는 방법으로 전화 앱을 띄워보았다. 이렇게 하면 두 앱은 별도의 프로세스로 동작하게 된다. 그런데 프로세스는 독립적인 상자와 같아서 프로세스 간의 정보 공유는 어렵다. 그래서 앱에는 태스크(Task)라는 것이 만들어지고, 태스크가 전화 앱에서 [BACK] 키를 누르면 다시 원래의 앱 화면으로 돌아올 수 있게 해준다.
10-1-1 프로세스와 태스크
시스템은 알아서 태스크를 관리하지만 직접 제어해야 하는 경우도 생긴다. 매니페스트 파일(AndroidManifest.xml)에 액티비티를 등록할 때 태스크도 함께 설정할 수 있다.
▼ 액티비티의 launchMode 속성을 추가하고 값을 singleTop으로 설정
// 중략
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
// 중략
<activity> 태그 안에 launchMode 속성을 추가하고 값을 singleTop으로 설정하면 태스크의 가장 위쪽에 있는 액티비티는 더 이상 새로 만들지 않게 된다. 저번 글에서 소개했던 인텐트의 플래그를 FLAG_ACTIVITY_SINGLE_TOP로 설정하는 것과 같은 효과이다.
10-2 액티비티의 수명주기와 SharedPreferences 이해하기
액티비티는 처음 실행될 때 메모리에 만들어지는 과정부터 시작해서 실행과 중지, 그리고 메모리에서 해제되는 여러 과정의 상태 정보를 갖고 있으며, 이런 상태 정보는 시스템이 관리하면서 각각의 상태에 해당하는 메서드를 자동으로 호출하게 된다. 예를 들어, onCreate() 메서드는 액티비티가 만들어질 때 시스템이 자동으로 호출하는 메서드이다.

이렇게 액티비티의 상태 정보가 변화하는 것을 액티비티의 수명주기(Life Cycle) 또는 생명주기라 하며 액티비티가 처음 만들어진 후 없어질 때까지 상태가 변화하면서 각각에 해당하는 메서드가 자동으로 호출된다.
상태 메서드 | 설명 |
onCreate | 액티비티가 처음 만들어졌을 때 호출됨 화면에 보이는 뷰들의 일반적인 상태를 설정하는 부분 이전 상태가 저장되어 있는 경우에는 번들 객체를 참조하여 이전 상태 복원 가능 이 메서드 다음에는 항상 onStart 메서드가 호출됨 |
onStart | 액티비티가 화면에 보이기 바로 전에 호출됨 액티비티가 화면 상에 보이면 이 메서드 다음에 onResume 메서드가 호출됨 액티비티가 화면에서 가려지게 되면 이 메서드 다음에 onStop 메서드가 호출됨 |
onResume | 액티비티가 사용자와 상호작용하기 바로 전에 호출됨 |
onRestart | 액티비티가 중지된 이후에 호출되는 메서드로 다시 시작되기 바로 전에 호출됨 이 메서드 다음에는 항상 onStart 메서드가 호출됨 |
onPause | 또 다른 액티비티를 시작하려고 할 때 호출됨 저장되지 않은 데이터를 저장소에 저장하거나 애니메이션 작업을 중지하는 등의 기능을 수행하는 메서드임 이 메서드가 리턴하기 전에는 다음 액티비티가 시작될 수 없으므로 이 작업은 매우 빨리 수행된 후 리턴되어야 함 액티비티가 이 상태에 들어가면 시스템은 액티비티를 강제 종료할 수 있음 |
onStop | 액티비티가 사용자에게 더 이상 보이지 않을 때 호출됨 액티비티가 소멸되거나 또 다른 액티비티가 화면을 가릴 때 호출됨 액티비티가 이 상태에 들어가면 시스템은 액티비티를 강제 종료할 수 있음 |
onDestroy | 액티비티가 소멸되어 없어지기 전에 호출됨 이 메서드는 액티비티가 받는 마지막 호출이 됨 액티비티가 앱에 의해 종료되거나(finish 메서드 호출) 시스템이 강제로 종료시키는 경우에 호출될 수 있음 |
▼ 수명주기 상태 변화 확인하기, 데이더 저장하고 복원하기
public class MainActivity extends AppCompatActivity {
EditText nameInput;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
println("onCreate 호출됨");
nameInput = findViewById(R.id.nameInput);
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();
println("onStart 호출됨");
}
@Override
protected void onStop() {
super.onStop();
println("onStop 호출됨");
}
@Override
protected void onDestroy() {
super.onDestroy();
println("onDestroy 호출됨");
}
@Override
protected void onPause() {
super.onPause();
println("onPause 호출됨");
saveState(); // 현재 입력상자에 입력된 데이터를 저장
}
@Override
protected void onResume() {
super.onResume();
println("onResume 호출됨");
restoreState(); // 설정 정보에 저장된 데이터를 복원
}
public void println(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();
}
}
-println() 메서드: 토스트 메시지는 여러 번 실행될 경우 이전 메시지가 보이지 않을 수도 있다. 따라서 디버깅 목적으로 사용할 때는 Logcat 창에 메시지를 출력하는 것이 좋다.

-화면이 보일 때는 onCreate, onStart, onResume 순서로 호출되고, 화면을 없앨 때는 onPause, onStop, onDestroy 순서로 호출된다. 이렇게 시스템에서 자동으로 호출하는 메서드를 콜백 메서드(Callback Method)라고 한다.
-화면이 보일 때와 화면이 보이지 않을 때 항상 호출되는 메서드는 onResume과 onPause 메서드이다. 앱이 갑자기 중지되거나 또는 다시 화면에 나타날 때 앱 데이터의 저장과 복원이 필요하기 때문에 이 두 개의 메서드는 아주 중요하다. 예를 들어, 게임을 할 때 사용자의 점수가 갑자기 사라지지 않도록 하려면 onPause 메서드 안에서 데이터를 저장하고 onResume 메서드 안에서 복원해야 한다.
-앱 안에서 간단한 데이터를 저장하거나 복원할 때는 SharedPreferences를 사용할 수 있다. 이것은 앱 내부에 파일을 하나 만드는데 이 파일 안에서 데이터를 저장하거나 읽어올 수 있게 한다. 개발자는 실제로 파일을 만들 필요 없이 SharedPreferences의 저장, 복원 메서드를 호출하면 된다.
-SharedPreferences 객체를 사용하려면 getSharedPreferences 메서드로 참조한다. pref 문자열은 저장소의 이름으로 사용한다. SharedPreferences.Editor 객체는 데이터를 저장할 수 있도록 edit 메서드를 제공하는데 edit 메서드를 호출한 후 put___ 메서드로 저장하려는 데이터를 설정할 수 있다. 데이터를 저장한 후에는 commit 메서드를 호출해야 실제로 저장된다.
*책에는 빠져있는 onCreate() 메서드 안에 nameInput 뷰 객체를 참조하는 코드를 추가했다.
'Android' 카테고리의 다른 글
[Do it! 안드로이드 앱 프로그래밍 #12] 프래그먼트로 화면 만들기 (0) | 2021.12.03 |
---|---|
[Do it! 안드로이드 앱 프로그래밍 #11] 프래그먼트란? (0) | 2021.11.28 |
[Do it! 안드로이드 앱 프로그래밍 #9] 인텐트, 플래그 그리고 부가 데이터 사용하기 (0) | 2021.11.21 |
[Do it! 안드로이드 앱 프로그래밍 #8] 여러 화면 만들고 화면 간 전환하기 (0) | 2021.11.19 |
[Do it! 안드로이드 앱 프로그래밍 #7] 레이아웃 인플레이션 이해하기 (0) | 2021.11.18 |