| page.title=작업 및 백 스택 |
| parent.title=액티비티 |
| parent.link=activities.html |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| |
| <h2>이 문서의 내용</h2> |
| <ol> |
| <li><a href="#ActivityState">액티비티 상태 저장하기</a></li></li> |
| <li><a href="#ManagingTasks">작업 관리하기</a> |
| <ol> |
| <li><a href="#TaskLaunchModes">시작 모드 정의하기</a></li> |
| <li><a href="#Affinities">유사성 처리하기</a></li> |
| <li><a href="#Clearing">백 스택 지우기</a></li> |
| <li><a href="#Starting">작업 시작하기</a></li> |
| </ol> |
| </li> |
| </ol> |
| |
| <h2>글</h2> |
| <ol> |
| <li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html"> |
| Android식 멀티태스킹</a></li> |
| </ol> |
| |
| <h2>참고 항목</h2> |
| <ol> |
| <li><a href="{@docRoot}design/patterns/navigation.html">Android 디자인: |
| 탐색</a></li> |
| <li><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>} 매니페스트 |
| 요소</a></li> |
| <li><a href="{@docRoot}guide/components/recents.html">개요 화면</a></li> |
| </ol> |
| </div> |
| </div> |
| |
| |
| <p>하나의 애플리케이션에는 보통 여러 개의 <a href="{@docRoot}guide/components/activities.html">액티비티</a>가 들어있습니다. 각 액티비티는 |
| 사용자가 수행할 수 있는 특정한 종류의 작업을 중심으로 디자인되어야 하며 다른 액티비티를 |
| 시작할 수 있는 기능이 있습니다. 예를 들어 이메일 애플리케이션에는 새 메시지 목록을 표시하는 하나의 액티비티가 있을 수 있습니다. |
| 사용자가 메시지를 하나 선택하면, 새 액티비티가 열려 해당 메시지를 볼 수 있게 합니다.</p> |
| |
| <p>액티비티는 기기에서 다른 애플리케이션에 존재하는 액티비티를 시작할 수도 있습니다. 예를 들어 |
| 애플리케이션이 이메일 메시지를 보내고자 하는 경우, "전송" 작업을 수행할 인텐트를 |
| 정의하여 이메일 주소와 메시지 등의 몇 가지 데이터를 포함시키면 됩니다. 그러면 다른 애플리케이션에서 가져온 액티비티 중 |
| 이러한 종류의 인텐트를 처리한다고 스스로 선언한 것이 열립니다. 이 경우, 이 인텐트는 |
| 이메일을 전송하기 위한 것이므로 이메일 애플리케이션의 "작성" 액티비티가 시작됩니다(같은 인텐트를 |
| 지원하는 액티비티가 여러 개 있는 경우, 시스템은 사용자에게 어느 것을 사용할지 선택하도록 합니다). 이메일이 전송되면 |
| 액티비티가 재개되고 해당 이메일 액티비티가 애플리케이션의 일부였던 것처럼 보입니다. 액티비티는 |
| 서로 다른 애플리케이션에서 온 것일 수 있지만, Android는 두 액티비티를 |
| 모두 같은 <em>작업</em> 안에 유지하여 이처럼 막힘 없는 사용자 환경을 유지합니다.</p> |
| |
| <p>작업이란 액티비티 컬렉션을 일컫는 말로, 사용자가 특정 작업을 수행할 때 이것과 |
| 상호 작용합니다. 액티비티는 스택 안에 정렬되며(<em>백 스택</em>), 이때 |
| 순서는 각 액티비티가 열린 순서와 같습니다.</p> |
| |
| <!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED |
| <div class="sidebox-wrapper"> |
| <div class="sidebox"> |
| <h3>Adding fragments to a task's back stack</h3> |
| |
| <p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example, |
| suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the |
| other being a layout to display an item from the list (fragment B). When the user selects an item |
| from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be |
| desireable for the user to navigate back to reveal fragment B, using the <em>Back</em> button.</p> |
| <p>In order to add fragment B to the back stack so that this is possible, you must call {@link |
| android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link |
| android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment |
| C.</p> |
| <p>For more information about using fragments and adding them to the back stack, see the {@link |
| android.app.Fragment} class documentation.</p> |
| |
| </div> |
| </div> |
| --> |
| |
| <p>기기 메인 스크린이 대다수 작업의 시작 지점입니다. 사용자가 |
| 애플리케이션 |
| 시작 관리자에 있는 아이콘(또는 메인 스크린의 바로 가기)을 터치하면 해당 애플리케이션의 작업이 전경으로 나옵니다. 해당 애플리케이션에 대한 |
| 작업이 존재하지 않으면(이 애플리케이션을 최근에 사용한 적이 없는 경우), 새 작업이 생성되고 |
| 해당 애플리케이션의 "기본" 액티비티가 스택에 있는 루트 액티비티로 열립니다.</p> |
| |
| <p>현재 액티비티가 또 다른 액티비티를 시작하는 경우, 새 액티비티가 스택의 맨 위로 밀어올려지고 |
| 사용자의 초점이 이에 맞춰집니다. 이전 액티비티는 스택에 유지되지만, 중단됩니다. 액티비티가 중단되면 |
| 시스템은 이 액티비티의 사용자 인터페이스의 현재 상태를 보존합니다. 사용자가 |
| <em>뒤로</em> |
| 버튼을 누르면, 현재 액티비티가 스택의 맨 위에서 튀어나오고(해당 액티비티는 소멸됩니다) |
| 이전 액티비티가 재개됩니다(이것의 UI 이전 상태가 복원됩니다). 스택에 있는 액티비티는 |
| 결코 다시 정렬되지 않습니다. 다만 스택에서 밀어올려지거나 튀어나올 뿐입니다. 즉, 현재 액티비티에 의해 |
| 시작되면 스택 위로 밀어올려지고, 사용자가 <em>뒤로</em> 버튼을 사용하여 액티비티를 떠나면 튀어나와 사라지는 것입니다. 따라서, |
| 백 스택은 |
| 일종의 "후입선출" 객체 구조로서 작동한다고 할 수 있습니다. 그림 1은 |
| 이 행동을 시간 표시 막대와 함께 표시하여 여러 액티비티 사이의 진행률을 보여주며, |
| 각 시점에서 현재 백 스택의 모습을 나타낸 것입니다.</p> |
| |
| <img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" /> |
| <p class="img-caption"><strong>그림 1.</strong> 작업에 있는 각각의 새 액티비티가 백 스택에 항목을 추가하는 |
| 방법을 나타낸 것입니다. 사용자가 <em>뒤로</em> 버튼을 누르면 현재 |
| 액티비티가 |
| 소멸되고 이전 액티비티가 재개됩니다.</p> |
| |
| |
| <p>사용자가 계속해서 <em>뒤로</em> 버튼을 누르면, 스택에 있는 각 액티비티가 하나씩 튀어나가 |
| 이전 것을 |
| 드러내고, 마침내는 사용자가 메인 스크린으로 되돌아가게 됩니다(아니면 작업이 시작되었을 때 |
| 실행 중이던 액티비티가 무엇이든 그것으로 되돌아갑니다). 스택에서 모든 액티비티가 제거되면 이 작업은 더 이상 존재하지 않게 됩니다.</p> |
| |
| <div class="figure" style="width:287px"> |
| <img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p |
| class="img-caption"><strong>그림 2.</strong> 두 개의 작업: 작업 B가 전경에서 사용자 상호 작용을 수신하는 한편, |
| 작업 A는 배경에서 재개되기를 기다립니다.</p> |
| </div> |
| <div class="figure" style="width:215px"> |
| <img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p |
| class="img-caption"><strong>그림 3.</strong> 하나의 액티비티가 여러 번 인스턴트화됩니다.</p> |
| </div> |
| |
| <p>작업이란 하나의 잘 짜여진 단위로 사용자가 새 작업을 시작할 때 "배경"으로 이동할 수도 있고 |
| <em>홈</em> 버튼을 통해 메인 스크린으로 이동할 수도 있습니다. 작업의 모든 액티비티는 배경에 있는 동안은 |
| 중단되지만 |
| , 해당 작업에 대한 백 스택은 그대로 변함 없이 유지됩니다. 이 작업은 또 다른 작업이 발생하는 동안 |
| 초점을 잃을 뿐입니다(그림 2 참조). 그런 다음 작업이 "전경"으로 되돌아와 사용자가 |
| 이전에 하던 일을 계속할 수 있습니다. 예를 들어 현재 작업(작업 A)의 스택에 세 개의 액티비티가 있다고 |
| 가정하면 그 중 둘은 현재 액티비티 아래에 있습니다. 사용자가 <em>홈</em> |
| 버튼을 누른 다음 |
| 애플리케이션 시작 관리자로부터 새 애플리케이션을 시작합니다. 메인 스크린이 나타나면 작업 A는 |
| 배경으로 이동합니다. 새 애플리케이션이 시작되면 시스템은 해당 애플리케이션에 대한 작업을 시작하며 |
| (작업 B) 여기에는 나름의 액티비티 스택이 딸려 있습니다. 해당 애플리케이션과 |
| 상호 작용한 후, 사용자는 다시 홈으로 돌아와 원래 작업 A를 시작한 |
| 애플리케이션을 선택합니다. 이제 작업 A가 전경으로 옵니다. |
| 이 스택에 있는 액티비티 세 개는 모두 멀쩡하고, 스택 맨 위에 있는 액티비티가 |
| 재개됩니다. 이 시점에서 |
| 사용자는 작업 B로 도로 전환할 수도 있습니다. 홈으로 이동하여 해당 작업을 |
| 시작한 애플리케이션 아이콘을 선택하면 됩니다(아니면 |
| <a href="{@docRoot}guide/components/recents.html">개요 화면</a>에서 해당 앱의 작업을 선택해도 됩니다). |
| 이것이 Android에서 멀티태스킹을 하는 작업의 예시입니다.</p> |
| |
| <p class="note"><strong>참고:</strong> 여러 개의 작업을 배경에 한꺼번에 대기시킬 수 있습니다. |
| 하지만, 사용자가 수많은 배경 작업을 동시에 실행하면 시스템이 메모리를 복원하기 위해 |
| 배경 액티비티를 소멸시키기 시작할 수 있고, 그러면 액티비티 상태가 손실됩니다. |
| 다음의 <a href="#ActivityState">액티비티 상태</a>에 관한 섹션을 참조하십시오.</p> |
| |
| <p>백 스택에 있는 액티비티는 결코 다시 정렬되지 않으므로, 애플리케이션에서 |
| 사용자에게 하나 이상의 액티비티로부터 특정 액티비티를 시작하도록 허용하는 경우, 해당 액티비티의 새 인스턴스가 |
| 생성되어 스택 위로 밀려옵니다(해당 액티비티의 기존 인스턴스를 |
| 맨 위로 가져오는 대신). 따라서, 애플리케이션 안의 한 액티비티가 여러 번 |
| 인스턴트화될 수 있으며(서로 다른 작업으로부터도 가능), 이를 나타낸 것이 그림 3입니다. 이 때문에 사용자가 |
| <em>뒤로</em> 버튼을 사용하여 뒤로 이동하는 경우, 액티비티의 각 인스턴스가 열린 순서대로 드러납니다 |
| (각자 나름의 |
| UI 상태를 가지고). 다만, 액티비티가 한 번 이상 인스턴트화되는 것을 원치 않으면 이 행동은 수정할 수 |
| 있습니다. 그 방법에 대해서는 <a href="#ManagingTasks">작업 관리하기</a>에 관한 이후 섹션에서 이야기합니다.</p> |
| |
| |
| <p>액티비티 및 작업에 대한 기본 행동을 요약하려면 다음과 같이 합니다.</p> |
| |
| <ul> |
| <li>액티비티 A가 액티비티 B를 시작하면 액티비티 A는 중단되지만, 시스템이 그 상태를 |
| (예: 스크롤 위치 및 양식에 입력된 텍스트 등) 보존합니다. |
| 사용자가 액티비티 B에 있는 동안 <em>뒤로</em> 버튼을 누르면 액티비티 A가 재개되며 상태도 |
| 복원됩니다.</li> |
| <li>사용자가 <em>홈</em> 버튼을 눌러 작업을 떠나면 현재 액티비티가 |
| 중단되고 |
| 그 소속 작업이 배경으로 들어갑니다. 시스템은 작업에 속한 모든 액티비티의 상태를 보존합니다. 사용자가 |
| 나중에 작업을 시작한 시작 관리자 아이콘을 선택하여 해당 작업을 재개하면, 그 작업이 |
| 전경으로 나오고 스택 맨 위에서 액티비티를 재개합니다.</li> |
| <li>사용자가 <em>뒤로</em> 버튼을 누르면, 현재 액티비티가 스택에서 튀어나오고 |
| 소멸됩니다. |
| 스택에 있던 이전 액티비티가 재개됩니다. 액티비티가 소멸되면, 시스템은 그 액티비티의 상태를 |
| 보존하지 <em>않습니다.</em></li> |
| <li>액티비티는 여러 번 인스턴트화할 수 있으며, 다른 작업에서도 이를 수행할 수 있습니다.</li> |
| </ul> |
| |
| |
| <div class="note design"> |
| <p><strong>탐색 디자인</strong></p> |
| <p>Android에서 앱 탐색의 작동 원리를 자세히 알아보려면, Android 디자인의 <a href="{@docRoot}design/patterns/navigation.html">탐색</a> 가이드를 읽어보십시오.</p> |
| </div> |
| |
| |
| <h2 id="ActivityState">액티비티 상태 저장하기</h2> |
| |
| <p>위에서 논한 바와 같이, 시스템의 기본 행동은 액티비티가 중단되면 그 상태를 보존해두는 |
| 것입니다. 이렇게 하면, 사용자가 이전 액티비티로 도로 이동했을 때 그에 속한 사용자 인터페이스가 이전 상태 |
| 그대로 표시됩니다. 그러나 액티비티의 상태를 미리 보존할 수도 있으며 사전에 이렇게 <strong>해야 합니다.</strong> |
| 이때에는, 액티비티가 소멸되고 다시 만들어야 하는 경우를 대비해 |
| 콜백 메서드를 사용합니다.</p> |
| |
| <p>시스템이 액티비티 중 하나를 중단시키는 경우(예를 들어 새 액티비티가 시작되었을 때 또는 작업이 |
| 배경으로 이동하는 경우), 시스템은 시스템 메모리를 회복해야 하는 경우 액티비티를 |
| 완전히 소멸시켜버릴 수도 있습니다. 이런 상황이 벌어지면, 액티비티 상태에 대한 정보는 손실됩니다. 이런 일이 벌어지더라도, |
| 시스템은 여전히 |
| 백 스택에 해당 액티비티의 자리가 있다는 것을 알고 있습니다. 다만 액티비티가 스택 맨 위로 올라오면 |
| 시스템이 이를 (재개하는 것이 아니라) 재생성해야만 합니다. 사용자의 작업 내용을 |
| 잃어버리는 불상사를 피하려면 그 내용을 미리 보존해두어야 합니다. 이때 액티비티의 |
| {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} 콜백 |
| 메서드를 구현하는 방법을 씁니다.</p> |
| |
| <p>액티비티 상태를 저장하는 방법에 대한 자세한 정보는 <a href="{@docRoot}guide/components/activities.html#SavingActivityState">액티비티</a> |
| 문서를 참조하십시오.</p> |
| |
| |
| |
| <h2 id="ManagingTasks">작업 관리하기</h2> |
| |
| <p>Android가 작업과 백 스택을 관리하는 방식은 위에 설명된 바와 같고—같은 작업 안에서 |
| 연이어 시작된 모든 작업을 한곳에 배치하되 "후입선출" 스택에 두는 것—이 방식은 |
| 대부분의 애플리케이션에 아주 효과적입니다. 여러분은 액티비티가 작업과 연관된 방식이나 |
| 백 스택에서의 존재 방식에 대해 염려하지 않아도 됩니다. 그러나, 정상적인 동작을 인터럽트하기로 결정할 수도 |
| 있습니다. 애플리케이션의 액티비티 하나가 시작되면 새 작업을 시작하려 |
| 할 수도 있습니다(현재 작업 내에 배치되는 것 대신에). 아니면, 액티비티를 시작하면 그것의 |
| 기존 인스턴스 하나를 앞으로 가져오고자 할 수도 있습니다(백 스택 맨 위에서 새 인스턴스를 |
| 생성하는 것 대신에). 또는 백 스택에서 사용자가 작업을 떠날 때의 루트 액티비티를 제외하고 |
| 모든 액티비티를 지우고자 할 수도 있습니다.</p> |
| |
| <p>이 모든 것과 그 외에도 많은 것을 할 수 있는 것이 바로 |
| <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> |
| 매니페스트 요소 안에 있는 속성과, |
| {@link android.app.Activity#startActivity startActivity()}에 전달한 인텐트에 있는 플래그입니다.</p> |
| |
| <p>이런 면에서, 여러분이 사용할 수 있는 주요 <a href="{@docRoot}guide/topics/manifest/activity-element.html"> |
| {@code <activity>}</a> 속성은 다음과 같습니다.</p> |
| |
| <ul class="nolist"> |
| <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff"> |
| {@code taskAffinity}</a></li> |
| <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode"> |
| {@code launchMode}</a></li> |
| <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> |
| {@code allowTaskReparenting}</a></li> |
| <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear"> |
| {@code clearTaskOnLaunch}</a></li> |
| <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> |
| {@code alwaysRetainTaskState}</a></li> |
| <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish"> |
| {@code finishOnTaskLaunch}</a></li> |
| </ul> |
| |
| <p>그리고 다음은 여러분이 사용할 수 있는 주요 인텐트 플래그입니다.</p> |
| |
| <ul class="nolist"> |
| <li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li> |
| <li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li> |
| <li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li> |
| </ul> |
| |
| <p>다음 섹션에서는 이와 같은 매니페스트 속성과 인텐트 플래그를 사용하여 |
| 액티비티가 작업과 연관되는 방식을 정의하고 백 스택에서 액티비티가 동작하는 방식을 정의하는 방법을 배우게 됩니다.</p> |
| |
| <p>이외에도 별도로 작업과 액티비티를 표시하는 방법에 대한 고려 사항과 |
| 개요 화면에서의 관리 방법을 논합니다. 자세한 정보는 <a href="{@docRoot}guide/components/recents.html">개요 화면</a>을 |
| 참조하십시오. 보통은 개요 화면에 작업과 액티비티가 어떻게 표현될지는 |
| 시스템이 정의하도록 두어야 합니다. 이 동작을 개발자가 수정할 필요도 없습니다.</p> |
| |
| <p class="caution"><strong>주의:</strong> 대부분의 애플리케이션은 액티비티와 작업에 대한 |
| 기본 동작을 인터럽트하지 않는 것이 정상입니다. 액티비티가 기본 동작을 수정하는 것이 필요하다는 |
| 판단이 서면, 시작 과정 중에 액티비티의 유용성을 테스트하십시오. |
| 또한 다른 액티비티와 작업에서 <em>뒤로</em> 버튼을 써서 해당 액티비티로 돌아올 때에도 유용성을 테스트해야 합니다. |
| 사용자의 예상되는 동작과 충돌할 가능성이 있는 탐색 동작을 꼭 테스트하십시오.</p> |
| |
| |
| <h3 id="TaskLaunchModes">시작 모드 정의하기</h3> |
| |
| <p>시작 모드를 사용하면 액티비티의 새 인스턴스가 현재 작업과 연관된 방식을 정의할 수 있게 |
| 해줍니다. 여러 가지 시작 모드를 두 가지 방식으로 정의할 수 있습니다.</p> |
| <ul class="nolist"> |
| <li><a href="#ManifestForTasks">매니페스트 파일 사용하기</a> |
| <p>매니페스트 파일에서 액티비티를 선언하는 경우, 액티비티가 시작될 때 여러 작업과 어떤 식으로 |
| 연관을 맺어야 하는지 지정할 수 있습니다.</li> |
| <li><a href="#IntentFlagsForTasks">인텐트 플래그 사용하기</a> |
| <p>{@link android.app.Activity#startActivity startActivity()}를 호출하는 경우 |
| {@link android.content.Intent}에 플래그를 포함시켜 새 액티비티가 현재 작업과 어떻게 연관되어야 할지(또는 |
| 애초에 연관을 맺을지 아닐지) 선언하도록 할 수 있습니다.</p></li> |
| </ul> |
| |
| <p>따라서, 액티비티 A가 액티비티 B를 시작하면 액티비티 B는 자신의 매니페스트에서 |
| 현재 작업과 연관을 맺는 데 적당한 방식(연관을 맺어야 한다면)을 정의할 수 있고 액티비티 A 또한 |
| 액티비티 B가 현재 작업과 연관을 맺는 방식을 요청할 수 있습니다. 두 액티비티가 모두 액티비티 B가 작업과 |
| 연관되는 방식을 정의하는 경우, 액티비티 A의 요청(인텐트에 정의된 바를 따름)을 액티비티 B의 |
| 요청(자신의 매니페스트에서 정의)보다 우위로 인식합니다.</p> |
| |
| <p class="note"><strong>참고:</strong> 매니페스트 파일에 사용할 수 있는 시작 모드 중에는 |
| 인텐트의 플래그로 사용할 수는 없는 것도 있으며, 이와 마찬 가지로 인텐트의 플래그로 사용할 수 있는 시작 모드 중에는 |
| 매니페스트에서 정의할 수 없는 것도 있습니다.</p> |
| |
| |
| <h4 id="ManifestForTasks">매니페스트 파일 사용하기</h4> |
| |
| <p>매니페스트 파일에서 액티비티를 선언하는 경우, 액티비티가 작업과 |
| 어떤 식으로 연관되어야 할지 지정하려면 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> |
| 요소의 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code |
| launchMode}</a> 속성을 사용하면 됩니다.</p> |
| |
| <p><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code |
| launchMode}</a> 속성은 액티비티가 작업 안으로 들어가며 시작되는 방법에 대한 지침을 |
| 나타냅니다. |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code> |
| 속성에 할당할 수 있는 시작 모드는 네 가지가 있습니다.</p> |
| |
| <dl> |
| <dt>{@code "standard"} (기본 모드)</dt> |
| <dd>기본입니다. 시스템이 액티비티가 시작된 작업에서 액티비티의 새 인스턴스를 만들고 |
| 인텐트의 경로를 이것으로 지정합니다. 액티비티는 여러 번 인스턴트화될 수 있고, |
| 각 인스턴스는 서로 다른 작업에 속할 수 있으며 한 작업에 여러 개의 인스턴스가 있을 수 있습니다.</dd> |
| <dt>{@code "singleTop"}</dt> |
| <dd>액티비티의 인스턴스가 이미 현재 작업의 맨 위에 존재하는 경우, 시스템은 인텐트의 경로를 |
| 해당 인스턴스로 지정합니다. 이때 액티비티의 새 인스턴스를 만들기보다는 해당 인스턴스의 {@link |
| android.app.Activity#onNewIntent onNewIntent()} 메서드를 호출하는 방법을 |
| 통합니다. 액티비티는 여러 번 인스턴트화될 수 있고, 각 인스턴스는 서로 다른 작업에 |
| 속할 수 있으며 한 작업에 여러 개의 인스턴스가 있을 수 있습니다(다만 백 스택의 맨 위에 있는 |
| 액티비티가 액티비티의 기존 인스턴스가 <em>아닌</em> 경우에만 이것이 적용됩니다). |
| <p>예를 들어 어느 작업의 백 스택이 루트 액티비티 A와 액티비티 B, C, 그리고 맨 위의 액티비티 D로 |
| 구성되어 있다고 가정합니다(이 스택은 A-B-C-D 형태를 띠며 D가 맨 위에 있습니다). 유형 D의 액티비티에 대한 인텐트가 도착합니다. |
| D에 기본 {@code "standard"} 시작 모드가 있는 경우, 클래스의 새 인스턴스가 시작되고 이 스택은 |
| A-B-C-D-D가 됩니다. 하지만, D의 시작 모드가 {@code "singleTop"}인 경우, D의 |
| 기존 인스턴스가 해당 인텐트를 {@link |
| android.app.Activity#onNewIntent onNewIntent()}를 통해 받게 됩니다. 이것이 스택의 맨 위에 있기 때문입니다. 스택은 |
| 계속 A-B-C-D로 유지됩니다. 그러나 유형 B의 액티비티에 대한 인텐트가 도착하는 경우, |
| B의 새 인스턴스가 스택에 추가되며 이는 액티비티의 시작 모드가 {@code "singleTop"}이더라도 무관하게 적용됩니다.</p> |
| <p class="note"><strong>참고:</strong> 어느 액티비티의 새 인스턴스가 생성되면, |
| 사용자가 <em>뒤로</em> 버튼을 눌러 이전 액티비티로 되돌아갈 수 있게 됩니다. 그러나 액티비티의 기존 |
| 인스턴스가 |
| 새 인텐트를 처리하는 경우, 사용자가 <em>뒤로</em> 버튼을 눌러도 새 인텐트가 {@link android.app.Activity#onNewIntent |
| onNewIntent()}에 도착하기 전의 액티비티 |
| 상태로 |
| 되돌아갈 수 없습니다.</p> |
| </dd> |
| |
| <dt>{@code "singleTask"}</dt> |
| <dd>시스템이 새 작업을 만들고 새 작업의 루트에 있는 액티비티를 인스턴트화합니다. |
| 하지만, 액티비티의 인스턴스가 이미 별개의 작업에 존재하는 경우, 시스템은 인텐트의 경로를 |
| 기존 인스턴스로 지정합니다. 이때 새 인스턴스를 만들기보다 해당 인스턴스의 {@link |
| android.app.Activity#onNewIntent onNewIntent()} 메서드를 호출하는 방법을 통합니다. 한 번에 |
| 액티비티 인스턴스 한 개씩만 존재할 수 있습니다. |
| <p class="note"><strong>참고:</strong> 액티비티가 새 작업에서 시작되더라도, |
| <em>뒤로</em> 버튼을 누르면 여전히 사용자를 이전 액티비티로 돌려보냅니다.</p></dd> |
| <dt>{@code "singleInstance"}.</dt> |
| <dd>{@code "singleTask"}와 같습니다. 다만 시스템이 인스턴스를 보유하고 있는 작업 안으로 |
| 다른 어떤 액티비티도 시작하지 않는다는 것은 예외입니다. 액티비티는 언제나 자신의 작업의 유일무이한 구성원입니다. |
| 이것으로 시작한 액티비티는 모두 별개의 작업에서 열립니다.</dd> |
| </dl> |
| |
| |
| <p>또 다른 예로 Android 브라우저 애플리케이션이 있습니다. 이것은 웹 브라우저 액티비티가 항상 |
| 자신만의 작업에서 열려야 한다고 선언합니다. 이때 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 요소에 {@code singleTask} 시작 모드를 지정하는 방법을 씁니다. |
| 다시 말해 애플리케이션이 Android 브라우저를 열라는 인텐트를 발행하면 |
| 브라우저의 액티비티가 애플리케이션과 같은 작업에 배치되지 <em>않는다</em>는 |
| 뜻입니다. 그 대신, 브라우저에 대한 새 작업이 시작되거나, 브라우저에 이미 |
| 배경에서 실행 중인 작업이 있는 경우 해당 작업이 전경으로 불려나와 새 인텐트를 처리하게 |
| 됩니다.</p> |
| |
| <p>액티비티가 새 작업에서 시작되었든 액티비티를 시작한 것과 같은 작업에서 시작되었든 관계 없이 |
| <em>뒤로</em> 버튼을 사용하면 언제나 사용자를 이전 액티비티로 돌려보냅니다. 다만, |
| {@code singleTask} 시작 모드를 나타내는 액티비티를 시작한 다음 해당 |
| 액티비티의 인스턴스가 이미 배경 작업에 존재하는 경우, 그 작업 전체가 전경에 불려나옵니다. 이 시점에서 |
| 백 스택에는 이제 앞으로 가져온 작업에서 가져온 모든 액티비티가 포함되어 있으며, 이는 스택의 |
| 맨 위에 위치합니다. 그림 4는 이와 같은 유형의 시나리오를 나타낸 것입니다.</p> |
| |
| <img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" /> |
| <p class="img-caption"><strong>그림 4.</strong> 시작 모드가 "singleTask"인 액티비티가 |
| 백 스택에 추가되는 방법을 표현한 것입니다. 이 액티비티가 이미 자신의 백 스택을 가지고 있는 |
| 배경 작업의 일부인 경우, 해당 백 스택도 모두 전경으로 |
| 불려나오며, 이는 현재 작업 위에 배치됩니다.</p> |
| |
| <p>매니페스트 파일에서 시작 모드를 사용하는 것에 대한 자세한 정보는 |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> |
| 요소 문서를 참조하십시오. 여기에서 {@code launchMode} 속성과 허용된 값을 더 자세히 |
| 논합니다.</p> |
| |
| <p class="note"><strong>참고:</strong> 액티비티에 대하여 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 속성으로 지정한 동작을 |
| 재정의하려면 액티비티를 시작한 인텐트에 포함된 플래그를 사용하면 됩니다. 이 내용은 |
| 다음 섹션에서 논합니다.</p> |
| |
| |
| |
| <h4 id="#IntentFlagsForTasks">인텐트 플래그 사용하기</h4> |
| |
| <p>액티비티를 시작할 때면, 액티비티가 자신의 작업과 연관되는 기본 방식을 수정할 수 있습니다. |
| {@link |
| android.app.Activity#startActivity startActivity()}에 전달한 인텐트 안에 있는 플래그를 포함시키면 됩니다. 기본 동작을 수정하는 데 사용할 수 있는 |
| 플래그는 다음과 같습니다.</p> |
| |
| <p> |
| <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt> |
| <dd>액티비티를 새 작업에서 시작합니다. 지금 시작하고 있는 액티비티에 대해 이미 실행 중인 작업이 있으면, |
| 해당 작업의 마지막 상태를 복원하여 전경으로 불려나오고 액티비티는 새 인텐트를 |
| {@link android.app.Activity#onNewIntent onNewIntent()}에서 수신합니다. |
| <p>이렇게 하면 {@code "singleTask"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 값에서와 같은 동작을 발생시키며, |
| 이는 이전 섹션에서 논한 것과 같습니다.</p></dd> |
| <dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt> |
| <dd>시작되고 있는 액티비티가 현재 액티비티인 경우(백 스택 맨 위에 있는), 해당 액티비티의 새 인스턴스를 생성하는 대신 기존 |
| 인스턴스가 {@link android.app.Activity#onNewIntent onNewIntent()}에 |
| 대한 호출을 받습니다. |
| <p>이렇게 하면 {@code "singleTop"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 값에서와 같은 동작을 발생시키며, |
| 이는 이전 섹션에서 논한 것과 같습니다.</p></dd> |
| <dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt> |
| <dd>시작되고 있는 액티비티가 이미 현재 작업에서 실행 중인 경우, 해당 액티비티의 |
| 새 인스턴스를 시작하는 대신 그 위에 있는 모든 다른 액티비티가 |
| 소멸되고 이 인텐트는 해당 액티비티(이제 맨 위로 올라옴)의 재개된 인스턴스로, |
| {@link android.app.Activity#onNewIntent onNewIntent()}를 통해 전달됩니다. |
| <p>이 동작을 발생시키는 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> |
| 속성에 대한 값은 없습니다.</p> |
| <p>{@code FLAG_ACTIVITY_CLEAR_TOP}는 |
| {@code FLAG_ACTIVITY_NEW_TASK}와 함께 쓰이는 경우가 가장 보편적입니다. |
| 이들 플래그를 함께 사용하면 다른 작업에 있는 기존 액티비티의 위치를 |
| 찾아 이를 인텐트에 응답할 수 있는 위치에 놓을 한 가지 방편이 됩니다. </p> |
| <p class="note"><strong>참고:</strong> 지정된 액티비티의 시작 모드가 |
| {@code "standard"}인 경우, |
| 이것 또한 스택에서 제거되고 그 자리에 새 인스턴스가 대신 생성되어 수신되는 인텐트를 |
| 처리하게 됩니다. 이는 시작 모드가 |
| {@code "standard"}인 경우, 새 인텐트에 대해서는 항상 새 인스턴스가 생성되기 때문입니다. </p> |
| </dd> |
| </dl> |
| |
| |
| |
| |
| |
| <h3 id="Affinities">유사성 처리하기</h3> |
| |
| <p><em>유사성</em>이란 액티비티가 어느 작업에 소속되기를 선호하는지를 나타내는 것입니다. 기본적으로, |
| 같은 애플리케이션에서 나온 액티비티는 서로 유사성을 지니고 있습니다. 따라서, 기본적으로 |
| 같은 애플리케이션 안에 있는 모든 액티비티는 같은 작업 안에 있는 것을 선호합니다. 하지만 액티비티에 대한 기본 유사성은 개발자가 |
| 수정할 수 있습니다. 각기 다른 애플리케이션에서 정의된 |
| 액티비티가 하나의 유사성을 공유할 수도 있고, 같은 애플리케이션에서 정의된 여러 액티비티에 |
| 서로 다른 작업 유사성을 할당할 수도 있습니다.</p> |
| |
| <p>어느 액티비티라도 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> |
| 요소의 <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> 속성을 |
| 사용하여 유사성을 수정할 수 있습니다.</p> |
| |
| <p><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> |
| 속성은 문자열 값을 취합니다. 이는 |
| <a href="{@docRoot}guide/topics/manifest/manifest-element.html"> |
| {@code <manifest>} |
| </a> 요소에서 선언한 기본 패키지 이름과 달리 고유해야 합니다. 왜냐하면 시스템이 이 이름을 사용하여 애플리케이션의 기본 작업 유사성을 |
| 식별하기 때문입니다.</p> |
| |
| <p>유사성이 역할을 갖는 것은 다음과 같은 두 가지 상황에서입니다.</p> |
| <ul> |
| <li>액티비티를 시작한 인텐트에 |
| {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} |
| 플래그가 들어 있는 경우. |
| |
| <p>새로운 액티비티는 기본적으로 |
| {@link android.app.Activity#startActivity startActivity()}를 호출한 액티비티의 작업 안으로 들어가며 시작됩니다. 이것은 발신자와 같은 |
| 백 스택 위로 밀어내집니다. 하지만 |
| {@link android.app.Activity#startActivity startActivity()}에 |
| 전달된 인텐트에 {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} |
| 플래그가 들어있는 경우, 시스템은 새 액티비티를 담을 다른 작업을 찾습니다. 이는 새 작업인 경우가 많습니다. |
| 그렇지만 꼭 그래야 하는 것은 아닙니다. 새 액티비티와 같은 유사성을 가진 기존 작업이 이미 존재하는 경우, |
| 해당 액티비티는 그 작업 안으로 들어가며 시작됩니다. 그렇지 않으면, 새 작업을 시작합니다.</p> |
| |
| <p>이 플래그 때문에 액티비티가 새 작업을 시작하게 되고 사용자가 <em>홈</em> 버튼을 눌러 이 액티비티를 |
| 떠나고자 |
| 하는 경우, 사용자가 작업으로 도로 이동할 방법이 있어야 합니다. 엔티티 중에는(예를 들어 |
| 알림 관리자) 액티비티를 항상 외부 작업으로만 시작하고 자신의 일부로서는 절대 시작하지 않는 것이 있습니다. |
| 따라서 이들은 {@code FLAG_ACTIVITY_NEW_TASK}를 |
| {@link android.app.Activity#startActivity startActivity()}에 전달하는 인텐트에 포함시킵니다. |
| 이 플래그를 사용할 수 있는 외부 엔티티가 |
| 호출할 수 있는 액티비티를 가지고 있는 경우, 사용자가 시작된 작업에 돌아갈 수 있는 |
| 방법을 따로 가지고 있어야 합니다. 예를 들어 시작 관리자 아이콘을 이용한다든지 하는 방법입니다(작업의 루트 액티비티에 |
| {@link android.content.Intent#CATEGORY_LAUNCHER} 인텐트 필터가 있습니다. 아래의 <a href="#Starting">작업 시작하기</a> 섹션을 참조하십시오).</p> |
| </li> |
| |
| <li>액티비티의 <a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> |
| {@code allowTaskReparenting}</a> 속성이 {@code "true"}로 설정된 경우. |
| <p>이 경우, 액티비티는 자신이 시작한 작업에서 벗어나 유사성을 가진 다른 작업이 전경으로 |
| 나오면 그 작업으로 이동할 수 있습니다.</p> |
| <p>예를 들어 선택한 몇몇 도시에서 기상 상태를 예보하는 어느 액티비티가 |
| 여행 애플리케이션의 일부로 정의되어 있다고 가정합니다. 이것은 같은 애플리케이션에 있는 |
| 다른 여러 액티비티와 같은 유사성을 가지며(기본 애플리케이션 유사성) 이 속성으로 상위 재지정을 허용하기도 합니다. |
| 액티비티 중 하나가 일기 예보 액티비티를 시작하면, 이는 처음에는 액티비티와 같은 작업에 |
| 속합니다. 하지만 여행 애플리케이션의 작업이 전경으로 불려나오면 |
| 일기 예보 액티비티는 그 작업에 다시 할당되며 그 안에 표시됩니다.</p> |
| </li> |
| </ul> |
| |
| <p class="note"><strong>팁:</strong> {@code .apk} 파일에 사용자 쪽에서 보기에 하나 이상의 "애플리케이션"이 |
| 들어있는 경우, <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> |
| 속성을 사용하여 각 "애플리케이션"과 연관된 액티비티에 서로 다른 유사성을 할당하는 것이 좋습니다.</p> |
| |
| |
| |
| <h3 id="Clearing">백 스택 지우기</h3> |
| |
| <p>사용자가 작업을 오랜 시간 동안 떠나 있으면, 시스템이 루트 액티비티만 빼고 모든 액티비티를 |
| 해당 작업에서 지웁니다. 사용자가 다시 작업으로 돌아오면, 루트 액티비티만 복원됩니다. |
| 시스템이 이런 식으로 동작하는 것은 오랜 시간이 지난 다음에는 사용자가 전에 하던 일을 중단하고 |
| 새로운 일을 시작하기 위해 작업에 돌아올 가능성이 크기 때문입니다. </p> |
| |
| <p>이 동작을 수정하는 데 사용할 수 있는 액티비티 속성이 몇 가지 있습니다. </p> |
| |
| <dl> |
| <dt><code><a |
| href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code> |
| </dt> |
| <dd>이 속성이 작업의 루트 액티비티 안에서 {@code "true"}로 설정되어 있는 경우, |
| 방금 설명한 기본 동작이 일어나지 않습니다. |
| 작업은 오랜 시간이 지난 뒤에도 자신의 스택에 있는 모든 액티비티를 유지합니다.</dd> |
| |
| <dt><code><a |
| href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt> |
| <dd>이 속성이 작업의 루트 액티비티 안에서 {@code "true"}로 설정되어 있는 경우, |
| 사용자가 작업을 떠났다가 다시 돌아올 때마다 스택을 루트 액티비티까지 |
| 지웁니다. 바꿔 말하면, 이것은 |
| <a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> |
| {@code alwaysRetainTaskState}</a>와 정반대입니다. 사용자는 항상 작업의 초기 상태로 돌아오게 되며, |
| 이는 아주 잠깐 동안만 작업을 떠난 경우에도 마찬가지입니다.</dd> |
| |
| <dt><code><a |
| href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code> |
| </dt> |
| <dd>이 속성은 <a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a>와 같지만, |
| 작업 전체가 아니라 |
| 하나의 액티비티에서 작동합니다. 이것은 루트 액티비티를 포함한 모든 액티비티가 없어지게 |
| 하기도 합니다. 이것을 {@code "true"}로 설정하면, |
| 액티비티는 현재 세션에 대해서만 작업의 일부로 유지됩니다. 사용자가 작업을 떠났다가 |
| 다시 돌아오면 이 작업은 더 이상 존재하지 않습니다.</dd> |
| </dl> |
| |
| |
| |
| |
| <h3 id="Starting">작업 시작하기</h3> |
| |
| <p>액티비티를 작업의 진입 지점으로 설정하려면 여기에 작업에서 지정한 대로 |
| {@code "android.intent.action.MAIN"}이 있는 인텐트 필터를 부여하고 |
| {@code "android.intent.category.LAUNCHER"}를 |
| 지정된 카테고리로 설정하면 됩니다. 예:</p> |
| |
| <pre> |
| <activity ... > |
| <intent-filter ... > |
| <action android:name="android.intent.action.MAIN" /> |
| <category android:name="android.intent.category.LAUNCHER" /> |
| </intent-filter> |
| ... |
| </activity> |
| </pre> |
| |
| <p>이런 종류의 인텐트 필터를 사용하면 액티비티에 대한 아이콘과 레이블이 |
| 애플리케이션 시작 관리자에 표시되어 사용자에게 액티비티를 시작할 방법을 부여하며, |
| 액티비티를 시작하고 나면 이것이 생성한 작업에 언제든 돌아올 수 있게 됩니다. |
| </p> |
| |
| <p>이 두 번째 능력이 중요합니다. 사용자는 작업을 떠났다가 이 액티비티 시작 관리자를 사용하여 나중에 작업에 |
| 돌아올 수 있어야 합니다. 이러한 이유로, 액티비티가 항상 작업을 시작하는 것으로 표시하는 <a href="#LaunchModes">시작 |
| 모드</a> 두 가지, 즉 {@code "singleTask"}와 |
| {@code "singleInstance"}는 액티비티에 |
| {@link android.content.Intent#ACTION_MAIN} |
| 및 {@link android.content.Intent#CATEGORY_LAUNCHER} 필터가 있을 때에만 사용해야 합니다. 예를 들어 필터가 누락되면 다음과 같은 일이 |
| 발생합니다. 어느 인텐트가 {@code "singleTask"} 액티비티를 시작하여 새 작업을 시작하고, |
| 사용자가 이 작업에서 일하며 어느 정도 시간을 보냅니다. 그런 다음 사용자가 <em>홈</em> |
| 버튼을 누릅니다. 이제 이 작업은 배경으로 전송되었으며 눈에 보이지 않습니다. 이제 사용자가 작업으로 되돌아갈 |
| 방법이 없어졌습니다. 이는 애플리케이션 시작 관리자에 표시되지 않기 때문입니다.</p> |
| |
| <p>사용자가 액티비티로 되돌아갈 수 있도록 하는 것을 원치 않는 경우, |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> |
| 요소의 |
| <a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code finishOnTaskLaunch}</a> |
| 를 {@code "true"}로 설정하면 됩니다(<a href="#Clearing">스택 지우기</a>를 참조하십시오).</p> |
| |
| <p>작업과 액티비티가 개요 화면에서 어떻게 표시되고 관리되는지에 대한 |
| 자세한 정보는 <a href="{@docRoot}guide/components/recents.html"> |
| 개요 화면</a>에서 확인하실 수 있습니다.</p> |
| |
| <!-- |
| <h2>Beginner's Path</h2> |
| |
| <p>For more information about how to use intents to |
| activate other application components and publish the intents to which your components |
| respond, continue with the <b><a |
| href="{@docRoot}guide/components/intents-filters.html">Intents and Intent |
| Filters</a></b> document.</p> |
| --> |