Android 의 Activity 시작 관련 Intent 플래그값에 대하여 1.
안드로이드의 Task 내부에는 여러 액티비티들을 갖고 있으며 이 것들은 동일한Affinity 값을 갖고 있고 하나의 스택위에 유지되고 있다. 우선 첫 번째로 동일한 Task 내에서 액티비티를 시작할 때, 자주 쓰이는 플래그값에 대하여 알아보겠다.
아래 설명되는 옵션들은 아래와 같이 사용할 수 있다.
Intent intent = new Intent(this, activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
참고로 startActivity 는 Context 의 메소드이다.
실제로 어떻게 동작하는지 궁금하여 아래 스샷과 같이 실험 앱을 만들어보고 정리해 보았다. (코드를 너무 날림으로 만들어서 공개는 민망하지만, 희망하는 분들께는 드리겠습니다.ㅠㅠ)
FLAG_ACTIVITY_SINGLE_TOP
예제)
1. 이미 A-B-C 순으로 액티비티가 생성되어 있다. 이 상태에서 FLAG_ACTIVITY_SINGLE_TOP 플래그 값을 줘서 액티비티 D 를 생성해 보겠다. 아래 그림에서 알파벳은 액티비티(클래스)이름이며, 괄호 안의 숫자는 생성된 순서 또는 실제 객체를 구분하기 위한 값이라고 생각하면 되겠다. 빨간색은 최상위 액티비티를 나타낸다.
+-----+--------+------+
|A(1)| B(2)| C(3) |
+-----+-------+------+
2. 이제 Task 의 스택에 액티비티 D 가 추가되었다. 이 상태에서 마찬가지로 FLAG_ACTIVITY_SINGLE_TOP 플래그 값으로 액티비티 D를 생성해 보겠다.
+------+-------+-------+------+
|A(1) | B(2) | C(3) | D(4) |
+-----+------+------+------+
3. 다시 한 번 FLAG_ACTIVITY_SINGLE_TOP 를 이용하여 액티비티 D를 생성하려고 했지만 이미 D 가 스택 최상위에 있으므로 아무것도 일어나지 않는다.
+------+--------+-------+------+
|A(1) | B(2) | C(3) | D(4) |
+------+------+------+------+
FLAG_ACTIVITY_CLEAR_TOP
생성하려는 액티비티와 동일한 종류의의 액티비티가 스택 내부에 있을 경우, 기존 동일한 액티비티 위의 모든 액티비티를 종료 시키고 기존 액티비티를 새로 생성된 액티비티로 교체한다. 이해가 안 된다면 아래 예제를 살펴보도록 하자.
예제)
1. 스택 위에 A-B-C-D 순으로 액티비티가 생성되어 있다. 이 상태에서 FLAG_ACTIVITY_CLEAR_TOP 플래그 값을 이용하여 액티비티 B 를 생성해 보겠다.
+------+------+-----+-------+
|A(1) | B(2) | C(3) | D(4) |
+-----+-----+----+------+
2. 생성하려는 액티비티 B가 이미 스택상에 있으므로 그 위의 액티비티 C와 D를 모두 종료시켜 준다. 그리고 기존에 생성된 액티비티 B(2) 를 종료 시켜주고 새롭게 생성된 액티비티 B(5)가 그 자리를 대신하게 된다. 이 상태에서 다시 같은 플래그 값을 이용하여 액티비티 B를 생성해 보겠다.
+-----+-----+
|A(1)| B(5) |
+-----+-----+
3. 예상한대로 B(5) 액티비티는 제거되고 새로 생성된 액티비티 B(6) 가 그 자리를 차지하게 된다.
+-----+-----+
|A(1)| B(6) |
+-----+-----+
FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP
1. 스택 위에 A-B-C-D 순으로 액티비티가 생성되어 있다. 이 상태에서 FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP 혼합 플래그 값을 이용하여 액티비티 D 를 생성해 보겠다.
+------+------+------+-------+
|A(1) | B(2) | C(3) | D(4) |
+-----+-----+-----+------+
2. 이때는 FLAG_ACTIVITY_SINGLE_TOP 옵션을 따라서 스택 최상단에 생성하려는 액티비티 D가 이미 있으므로 아무 일도 일어나지 않는다. 이 상태에서 액티비티 B를 새로 추가해 보겠다.
+------+-------+-------+------+
|A(1) | B(2) | C(3) | D(4) |
+-----+------+------+------+
+-----+-----+
|A(1)| B(2) |
+-----+-----+
FLAG_ACTIVITY_REORDER_TO_FRONT
Task의 스택 위에 새롭게 생성하려는 액티비티와 같은 종류의 액티비티가 존재한다면, 그 것을 최상단으로 가져온다. 만약 FLAG_ACTIVITY_CLEAR_TOP 와 같이 쓰여진다면 결국 이 REORDER_TO_FRONT 플래그 값은 무시된다. 만약 생성 하려는 액티비티와 같은 종류의 액티비티가 스택 최상단에 존재하고 있다면 FLAG_ACTIVITY_SINGLE_TOP 과 동일하게 아무일도(?) 일어나지 않을 것이다.
1. 스택 위에 A-B-C-D 순으로 액티비티가 생성되어 있다. 이 상태에서 FLAG_ACTIVITY_REORDER_TO_FRONT 옵션을 이용하여 액티비티 A 를 불러와 보겠다.
+------+-------+------+-------+
|A(1) | B(2) | C(3) | D(4) |
+-----+------+------+------+
2. 아래와 같이 기존에 생성되었던 액티비티 A가 스택 최상단으로 이동하였다. A는 액티비티 생명주기상 onResume 이 호출된다. 이 상황에서 액티비티 B가 베이스 액티비티가 된다.
+-------+-------+--------+-------+
| B(2) |C(3) | D(4) | A(1) |
+------+------+-------+-------+
FLAG_ACTIVITY_NO_HISTORY
이 옵션을 사용하여 스택위에 추가된 액티비티 위에 새 액티비티가 추가될 경우 기존의 액티비티가 종료된다. 즉, 최상위 액티비티가 아닐 경우 스택에 쌓이지 않는 액티비티를 만든다.
1. 스택 위에 A-B-C-D 순으로 액티비티가 생성되어 있다. D 는 FLAG_ACTIVITY_NO_HISTORY 를 통하여 생성되었다. 이 상태에서 액티비티 B 를 새로 추가해 보겠다.
+-------+--------+------+------+
|A(1) | B(2) | C(3) | D(4) |
+------+------+------+------+
2. 액티비티 D 는 스택에 남지 않고 종료 된다. 하지만, 실험을 했을 때 종종 액티비티 D는 바로Destory 되지 않고 B가 추가된 상태에서 finish 를 호출하였을 때, 스택에서 같이 제거되었다. 즉, FLAG_ACTIVITY_NO_HISTORY 를 통하여 생성한 액티비티는 그 위에 새 액티비티를 위에 추가한 뒤에 스택위에 남더라도 최상위 액티비티를 제거(pop) 한 시점에서 같이 사라진다. 결과적으로 다시 launch 되지 않는다는 것이다.
+-----+-----+------+------+--------+|A(1)| B(2) | C(3) | D(4) | B(5) |
+-----+-----+------+------+------+
B(5) finish 호출. D(4) 도 함께 종료된다.
+-----+-----+------+
|A(1)| B(2) | C(3) |
+-----+-----+------+
좀 더 자세한 정보는 http://developer.android.com/reference/android/content/Intent.html 에서 찾아볼 수 있다.
다음 시간에는 Task 동작에 관여하는 플래그 값에 대하여 알아보겠다.