[관련글 링크]
1. Activity Jump #1 "홈 액티비티로 이동하기"
2. Activity Jump #2 "액티비티 스택에 없었던 메인액티비티로 이동하기"
[목표]
1번 글에서는 어느 액티비티에서든 홈 액티비티로 이동하는 방법에 대해 정리해봤다.
이번 글에서는 시작 액티비티가 기획자가 요구하는 UI흐름의 중간인 경우. 그래서 시작 액티비티에서 [이전] 키를 눌렀을 때, 안드로이드 홈스크린이 아닌 UI흐름 상의 액티비티를 보여줘야 하는 경우에 대해 알아본다.
그림으로 표현하면 다음과 같다.
안드로이드 홈스크린에서 "위젯" 또는 "실행 아이콘"을 눌렀을 때, 액티비티 B를 보여주는 것. 또한, [이전]의 의미가안드로이드 홈스크린이 아닌, 한 번도 띄운적 없는(액티비티 스택에 존재하지 않는) Activity A인 경우 어떻게 구현해야 할까?
[구현하기]
다음과 같이 액티비티 4개를 준비한다.
우선, AndroidManifest.xml을 수정하여, Activity B를 시작액티비티로 지정해 준다.
이렇게 하면 안드로이드홈에서 아이콘을 클릭하면 제일 먼서 Activity B가 보여진다.
당연히 액티비티 스택에는 Activity B 만 쌓여있는 상태가 된다.
<activity android:name=".ActivityJumpDemoActivity" android:label="@string/app_name"> </activity> <activity android:name="ActivityA" android:configChanges="orientation" android:screenOrientation="sensor"> </activity> <activity android:name="ActivityB" android:configChanges="orientation" android:screenOrientation="sensor"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="ActivityC" android:configChanges="orientation" android:screenOrientation="sensor"> </activity>
이제 Activity B에서 [이전]키를 눌렀을 때, Activity A를 보여주려면 Activity B에 onKeyUp(...)을 구현해준다.
나머지 액티비티들도 띄워줄 액티비티를 변경/적용해준다.
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { Intent intent = new Intent(getBaseContext(), ActivityA.class); startActivity(intent); finish(); return true; } return super.onKeyDown(keyCode, event); }
Line 4 : [이전]키가 눌렸을 때 보여줄 ActivityA.class를 지정한다.
Line 6 : 현재 창은 종료시켜 액티비티 스택에서 깔끔히 없앤다.
이렇게 구현된 상태에서 "안드로이드홈->B액티비티->[이전]키->A액티비티"의 흐름은 정상적으로 동작한다.
* 안드로이드홈->B액티비티->[이전]키->A액티비티 후 스택 확인
Running activities (most recent first):
TaskRecord{300bdd60 #5 A com.juno.activityjump.demo}
Run #1: HistoryRecord{3012fe80 com.juno.activityjump.demo/.ActivityJumpDemoActivity}
TaskRecord{2fe0c3e8 #2 A com.lge.launcher}
Run #0: HistoryRecord{300d62c0 com.lge.launcher/.Launcher}
그런데, 문제가 있다.
위와 같이 액티비티 마다 onKeyUp(...) 별도로 구현해 놓으면, [이전]키가 눌렸을 때 항상 새롭게 액티비티를 띄우게 된다.
만약 "메인->A->메인"를 반복하면, A액티비티는 finish()로 종료되지만, 스택에 있었던 녀석을 놔두고 새롭게 메인액티비티를 띄우게 된다. 즉, 메인액티비티가 여러 벌이 생기고 메모리에 계속 남게 된다.
* "메인->A->[이전]키->메인"를 두 번 반복했을 때의 스택 확인
Running activities (most recent first):
TaskRecord{301628a0 #6 A com.juno.activityjump.demo}
Run #3: HistoryRecord{30311070 com.juno.activityjump.demo/.ActivityJumpDemoActivity}
Run #2: HistoryRecord{301e5650 com.juno.activityjump.demo/.ActivityJumpDemoActivity}
Run #1: HistoryRecord{301c5ea8 com.juno.activityjump.demo/.ActivityJumpDemoActivity}
TaskRecord{2fe0c3e8 #2 A com.lge.launcher}
Run #0: HistoryRecord{300d62c0 com.lge.launcher/.Launcher}
이를 해결하는 방법은 "1. Activity Jump #1 "홈 액티비티로 이동하기" 글에서 소개한 인텐트 플래그를 동일하게 사용하면 해결된다.
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { Intent intent = new Intent(getBaseContext(), ActivityJumpDemoActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent); finish(); return true; } return super.onKeyDown(keyCode, event); }
Line 5 : FLAG_ACTIVITY_CLEAR_TOP 플래그. 혹시 모를 중간의 액티비티를 스택에서 없앤다.
Line 6 : FLAG_ACTIVITY_SINGLE_TOP 플래그. 최상위 스택에 보여줄 액티비티가 존재하는 경우, 이를 재사용한다.
위와 같이 적용한 후에는 액티비티 사이를 이리저리 왔다 갔다 한 후, 메인액티비티로 돌아온다고 해도 스택은 아래와 같이 깔끔해진다.
Running activities (most recent first):
TaskRecord{3027dff8 #7 A com.juno.activityjump.demo}
Run #1: HistoryRecord{301e89e8 com.juno.activityjump.demo/.ActivityJumpDemoActivity}
TaskRecord{2fe0c3e8 #2 A com.lge.launcher}
Run #0: HistoryRecord{300d62c0 com.lge.launcher/.Launcher}
[다운로드]
전체소스
'Android' 카테고리의 다른 글
[번역글] 프레그먼트 #1 - 프레그먼트(Fragments)란? (0) | 2014.01.08 |
---|---|
[번역글] Supporting Different Screen Sizes #1 - 최소너비 식별자(Smallest-width Qualifier) 사용하기 (0) | 2014.01.08 |
[Android] Activity Jump #1 "홈 액티비티로 이동하기" (0) | 2012.01.30 |
[Android] Animated "ListView" Demo (0) | 2012.01.19 |
[Android] BroadcastReceiver 동적으로 등록하기 (2) | 2012.01.17 |