| page.title=작업 |
| page.tags=activity,intent |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>이 문서의 내용</h2> |
| <ol> |
| <li><a href="#Creating">액티비티 생성하기</a> |
| <ol> |
| <li><a href="#UI">사용자 인터페이스 구현하기</a></li> |
| <li><a href="#Declaring">매니페스트에서 액티비티 선언하기</a></li> |
| </ol> |
| </li> |
| <li><a href="#StartingAnActivity">액티비티 시작하기</a> |
| <ol> |
| <li><a href="#StartingAnActivityForResult">결과에 대한 액티비티 시작하기</a></li> |
| </ol> |
| </li> |
| <li><a href="#ShuttingDown">액티비티 종료하기</a></li> |
| <li><a href="#Lifecycle">액티비티 수명 주기 관리하기</a> |
| <ol> |
| <li><a href="#ImplementingLifecycleCallbacks">수명 주기 콜백 구현하기</a></li> |
| <li><a href="#SavingActivityState">액티비티 상태 저장하기</a></li> |
| <li><a href="#ConfigurationChanges">구성 변경 처리하기</a></li> |
| <li><a href="#CoordinatingActivities">액티비티 조정하기</a></li> |
| </ol> |
| </li> |
| </ol> |
| |
| <h2>Key 클래스</h2> |
| <ol> |
| <li>{@link android.app.Activity}</li> |
| </ol> |
| |
| <h2>참고 항목</h2> |
| <ol> |
| <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">작업 및 백 |
| 스택</a></li> |
| </ol> |
| |
| </div> |
| </div> |
| |
| |
| |
| <p>{@link android.app.Activity}는 일종의 애플리케이션 구성 요소로서, |
| 사용자와 상호작용할 수 있는 화면을 제공하여 전화 걸기, 사진 찍기, 이메일 보내기 또는 지도 보기 등의 일을 할 수 |
| 있습니다. 액티비티마다 창이 하나씩 주어져 이곳에 사용자 인터페이스를 끌어올 수 있습니다. 이 창은 |
| 일반적으로 화면을 가득 채우지만, 작은 창으로 만들어 다른 창 위에 띄울 수도 |
| 있습니다.</p> |
| |
| <p> 하나의 애플리케이션은 보통 여러 개의 액티비티가 느슨하게 서로 묶여 있는 형태로 |
| 구성됩니다. 통상 한 애플리케이션 내에서 하나의 액티비티가 "주요" 액티비티로 지정되며, |
| 사용자가 이 애플리케이션을 처음 실행할 때 이 액티비티가 사용자에게 표시됩니다. 그런 후 |
| 각각의 액티비티는 여러 가지 작업을 수행하기 위해 또 다른 액티비티를 시작할 수 있습니다. 새로운 |
| 액티비티가 시작될 때마다 이전 액티비티는 중단되지만 시스템은 해당 액티비티를 |
| 스택("백 스택")에 보존합니다. 새로운 액티비티가 시작되면, 이것이 백 스택 위로 밀려와 사용자의 |
| 시선을 끕니다. 백 스택은 기본적인 "후입선출" 방식을 지키므로, |
| 사용자가 현재 액티비티를 끝내고 <em>뒤로</em> 버튼을 누르면 해당 액티비티가 |
| 스택에서 튀어나와(소멸되고) 이전 액티비티를 재개합니다 (백 스택은 |
| <a href="{@docRoot}guide/components/tasks-and-back-stack.html">작업 |
| 및 백 스택</a> 문서에서 상세하게 논의합니다).</p> |
| |
| <p>한 액티비티가 새로운 액티비티의 시작으로 인해 중단된 경우, 이 상태 변경은 |
| 액티비티의 수명 주기 콜백 메서드를 통해 알려집니다. |
| 액티비티가 시스템 액티비티를 생성, 중단, 재시작, 제거하는 등의 상태 변화로 인해 받을 수 있는 콜백 메서드는 여러 가지가 있습니다. |
| |
| 각 콜백은 상태 변화에 알맞은 특정 작업을 수행할 기회를 제공합니다. |
| 예를 들어 액티비티가 중단되면 네트워크 또는 데이터베이스 연결과 같이 |
| 큰 개체는 모두 해제해야 합니다. 액티비티가 재개되면, 필요한 리소스를 |
| 다시 획득하여 중단된 작업을 재개할 수 있습니다. 이러한 상태 전환은 |
| 모두 액티비티 수명 주기의 일부입니다.</p> |
| |
| <p>이 문서의 남은 부분에서는 다양한 액티비티 상태 사이의 전환을 적절히 관리할 수 있도록 액티비티 수명 주기가 작동하는 방식을 자세히 논하는 등, |
| 액티비티를 구축하고 사용하는 기본적 방법을 |
| 설명합니다.</p> |
| |
| |
| |
| <h2 id="Creating">액티비티 생성하기</h2> |
| |
| <p>액티비티를 생성하려면 {@link android.app.Activity}의 하위 클래스(또는 이의 |
| 기존 하위 클래스)를 생성해야 합니다. 하위 클래스에서는 |
| 액티비티 생성, 중단, 재개, 소멸 시기 등과 같은 |
| 수명 주기의 다양한 상태 간 액티비티가 전환될 때 시스템이 호출하는 콜백 메서드를 구현해야 합니다. 가장 중요한 두 가지 콜백 메서드는 |
| 다음과 같습니다.</p> |
| |
| <dl> |
| <dt>{@link android.app.Activity#onCreate onCreate()}</dt> |
| <dd>이 메서드는 반드시 구현해야 합니다. 시스템은 액티비티를 생성할 때 이것을 호출합니다. |
| 구현하는 중에 액티비티의 필수 구성 요소를 초기화해야 |
| 합니다. |
| 무엇보다도 중요한 점은, 바로 여기서 {@link android.app.Activity#setContentView |
| setContentView()}를 호출해야 액티비티의 사용자 인터페이스 레이아웃을 정의할 수 있다는 점입니다.</dd> |
| <dt>{@link android.app.Activity#onPause onPause()}</dt> |
| <dd>시스템이 이 메서드를 호출하는 것은 사용자가 액티비티를 떠난다는 |
| 첫 번째 신호입니다(다만 이것이 항상 액티비티가 소멸 중이라는 뜻은 아닙니다). 현재 사용자 세션을 넘어서 |
| 지속되어야 하는 변경 사항을 커밋하려면 보통 이곳에서 해아 합니다(사용자가 |
| 돌아오지 않을 수 있기 때문입니다).</dd> |
| </dl> |
| |
| <p>여러 액티비티 사이에서 원활한 사용자 경험을 제공하고, 액티비티 중단이나 심지어 |
| 소멸을 초래할 수도 있는 예상치 못한 간섭을 처리하기 위해 사용해야 하는 다른 수명 주기 |
| 콜백 메서드도 여러 가지 있습니다. 모든 수명 주기 콜백 메서드는 나중에 |
| <a href="#Lifecycle">액티비티 수명 주기 관리</a> 섹션에서 자세히 논의할 것입니다.</p> |
| |
| |
| |
| <h3 id="UI">사용자 인터페이스 구현하기</h3> |
| |
| <p> 한 액티비티에 대한 사용자 인터페이스는 보기 계층—즉, |
| {@link android.view.View} 클래스에서 파생된 개체가 제공합니다. 각 보기는 액티비티 창 안의 특정한 직사각형 공간을 |
| 제어하며 사용자 상호 작용에 대응할 수 있습니다. 예를 들어, 어떤 보기는 사용자가 터치하면 |
| 작업을 시작하는 버튼일 수 있습니다.</p> |
| |
| <p>Android는 레이아웃을 디자인하고 정리하는 데 사용할 수 있도록 여러 가지 보기를 미리 만들어 |
| 제공합니다. "위젯"이란 화면에 시각적(이자 대화형) 요소를 제공하는 보기입니다. 예를 들어 |
| 버튼, 텍스트 필드, 확인란이나 그저 하나의 이미지일 수도 있습니다. "레이아웃"은 선형 레이아웃, 격자형 레이아웃, 상대적 레이아웃과 같이 하위 레이아웃에 대해 독특한 레이아웃 모델을 제공하는 {@link |
| android.view.ViewGroup}에서 파생된 |
| 보기입니다. 또한, {@link android.view.View}와 |
| {@link android.view.ViewGroup} 클래스(또는 기존 하위 클래스)의 아래로 내려가서 위젯과 레이아웃을 생성하고 |
| 이를 액티비티 레이아웃에 적용할 수 있습니다.</p> |
| |
| <p>보기를 사용하여 레이아웃을 정의하는 가장 보편적인 방식은 애플리케이션 리소스에 저장된 |
| XML 레이아웃 파일을 사용하는 것입니다. 이렇게 하면 액티비티의 동작을 정의하는 |
| 소스 코드와 별개로 사용자 인터페이스 디자인을 유지할 수 있습니다. |
| {@link android.app.Activity#setContentView(int) setContentView()}로 액티비티의 UI로서 레이아웃을 설정하고, |
| 해당 레이아웃의 리소스 ID를 전달할 수 있습니다. 그러나 액티비티 코드에 새로운 {@link android.view.View}를 생성하고 |
| 새로운 {@link |
| android.view.View}를 {@link android.view.ViewGroup}에 삽입하여 보기 계층을 구축한 뒤 루트 |
| {@link android.view.ViewGroup}을 {@link android.app.Activity#setContentView(View) |
| setContentView()}에 전달해도 해당 레이아웃을 사용할 수 있습니다.</p> |
| |
| <p>사용자 인터페이스 생성에 관한 정보는 <a href="{@docRoot}guide/topics/ui/index.html">사용자 인터페이스</a> 문서를 참조하십시오.</p> |
| |
| |
| |
| <h3 id="Declaring">매니페스트에서 액티비티 선언하기</h3> |
| |
| <p>시스템에서 액티비티에 액세스할 수 있게 하려면 이를 매니페스트 파일에서 |
| 선언해야만 합니다. 액티비티를 선언하려면 매니페스트 파일을 열고 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 요소를 |
| <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a> |
| 요소의 하위 항목으로 추가합니다. 예:</p> |
| |
| <pre> |
| <manifest ... > |
| <application ... > |
| <activity android:name=".ExampleActivity" /> |
| ... |
| </application ... > |
| ... |
| </manifest > |
| </pre> |
| |
| <p>액티비티 레이블, 액티비티 아이콘 또는 액티비티 UI 스타일용 테마와 같이 |
| 이 요소에 포함할 수 있는 속성이 여러 가지 있습니다. |
| <a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">{@code android:name}</a> |
| 속성이 유일한 필수 속성입니다. 이것이 액티비티의 클래스 이름을 지정합니다. 일단 |
| 애플리케이션을 게시하고 나면 이 이름을 변경해서는 안 됩니다. 이름을 변경하면 |
| 애플리케이션 바로 가기와 같은 일부 기능이 고장 날 수 있습니다(블로그 게시물의 <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">바꿀 수 없는 |
| 항목</a>을 참조하십시오).</p> |
| |
| <p>매니페스트에서 액티비티를 선언하는 것에 관한 자세한 정보는 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 요소 |
| 참고 자료를 참조하십시오.</p> |
| |
| |
| <h4>인텐트 필터 사용하기</h4> |
| |
| <p><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code |
| <activity>}</a> 요소 또한 여러 가지 인텐트 필터를 지정할 수 있습니다. 다른 애플리케이션 구성 요소가 이를 활성화하는 방법을 선언하기 위해 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code |
| <intent-filter>}</a>를 사용하는 |
| 것입니다.</p> |
| |
| <p>Android SDK 도구를 사용하여 새 애플리케이션을 생성하는 경우, 개발자를 위해 |
| 생성되어 있는 스텁 액티비티에 자동으로 인텐트 필터가 포함되어 있어 "주요" 동작에 |
| 응답하는 액티비티를 선언하며, 이는 "시작 관리자" 범주에 배치해야 합니다. 인텐트 필터는 다음과 |
| 같은 형태를 띱니다.</p> |
| |
| <pre> |
| <activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"> |
| <intent-filter> |
| <action android:name="android.intent.action.MAIN" /> |
| <category android:name="android.intent.category.LAUNCHER" /> |
| </intent-filter> |
| </activity> |
| </pre> |
| |
| <p><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code |
| <action>}</a> 요소는 이것이 애플리케이션으로 가는 "주요" 진입 지점이라는 것을 나타냅니다. <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code |
| <category>}</a> 요소는 이 액티비티가 시스템의 |
| 애플리케이션 시작 관리자에 목록으로 나열되어야 한다는 것을 나타냅니다(사용자가 이 액티비티를 시작할 수 있도록 해줌).</p> |
| |
| <p>애플리케이션이 자체 포함 방식이기를 원하고 다른 애플리케이션이 이 |
| 애플리케이션의 액티비티를 활성화하도록 허용하지 않고자 하면, 달리 인텐트 필터가 더 필요하지 않습니다. "주요" 동작과 "시작 관리자" 범주가 있는 |
| 액티비티는 하나뿐이어야 합니다(이전 예시 참조). 다른 애플리케이션에서 |
| 사용할 수 없게 하고자 하는 액티비티에는 인텐트 필터가 있으면 안 됩니다. |
| 이러한 액티비티는 명시적인 인텐트를 사용해 직접 시작할 수 있습니다(이 내용은 다음 섹션에서 논의).</p> |
| |
| <p>그러나, 액티비티가 다른 애플리케이션(및 본인의 애플리케이션)에서 |
| 전달된 암시적 인텐트에 응답하도록 하려면 액티비티에 추가로 인텐트 필터를 정의해야만 |
| 합니다. 응답하게 하고자 하는 각 인텐트 유형별로 |
| <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code |
| <action>}</a> 요소를 포함하는 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code |
| <intent-filter>}</a>를 하나씩 포함시켜야 하며, 선택 사항으로 <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code |
| <category>}</a> 요소 및/또는 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code |
| <data>}</a> 요소를 포함시킬 수 있습니다. 이와 같은 요소는 액티비티가 응답할 수 있는 인텐트의 유형을 |
| 나타냅니다.</p> |
| |
| <p>액티비티가 인텐트에 응답하는 방식에 관한 자세한 정보는 <a href="{@docRoot}guide/components/intents-filters.html">인텐트 및 인텐트 필터</a> |
| 문서를 참조하십시오.</p> |
| |
| |
| |
| <h2 id="StartingAnActivity">액티비티 시작하기</h2> |
| |
| <p>다른 액티비티를 시작하려면 {@link android.app.Activity#startActivity |
| startActivity()}를 호출한 다음 이에 시작하고자 하는 액티비티를 설명하는 {@link android.content.Intent}를 |
| 전달하면 됩니다. 인텐트는 시작하고자 하는 액티비티를 정확히 나타내거나, 수행하고자 하는 작업의 |
| 유형을 설명하는 것입니다(시스템이 적절한 액티비티를 선택하며, |
| 이는 |
| 다른 애플리케이션에서 가져온 것일 수도 있습니다). 인텐트는 소량의 데이터를 운반하여 시작된 액티비티에서 |
| 사용할 수 있습니다.</p> |
| |
| <p>본인의 애플리케이션 안에서 작업하는 경우에는, 알려진 액티비티를 시작하기만 하면 되는 경우가 잦습니다. |
| 이렇게 하려면 시작하고자 하는 액티비티를 명시적으로 정의하는 인텐트를 클래스 이름을 |
| 사용하여 생성하면 됩니다. 예를 들어, 다음은 한 액티비티가 {@code |
| SignInActivity}라는 이름의 다른 액티비티를 시작하는 방법입니다.</p> |
| |
| <pre> |
| Intent intent = new Intent(this, SignInActivity.class); |
| startActivity(intent); |
| </pre> |
| |
| <p>그러나, 애플리케이션이 다른 몇 가지 동작을 수행하고자 할 수도 있습니다. 예를 들어 이메일 보내기, 문자 |
| 메시지 보내기 또는 상태 업데이트 등을 액티비티의 데이터를 사용하여 수행하는 것입니다. 이 경우, 본인의 애플리케이션에 |
| 그러한 동작을 수행할 자체 액티비티가 없을 수도 있습니다. 따라서 기기에 있는 다른 애플리케이션이 |
| 제공하는 액티비티를 대신 활용하여 동작을 수행하도록 할 수 있습니다. 바로 이 부분에서 |
| 인텐트의 진가가 발휘됩니다. 수행하고자 하는 동작을 설명하는 인텐트를 생성하면 |
| 시스템이 적절한 액티비티를 |
| 다른 애플리케이션에서 시작하는 것입니다. 해당 인텐트를 |
| 처리할 수 있는 액티비티가 여러 개 있는 경우, 사용자가 어느 것을 사용할지 선택합니다. 예를 |
| 들어 사용자가 이메일 메시지를 보낼 수 있게 하려면, 다음과 같은 인텐트를 |
| 생성하면 됩니다.</p> |
| |
| <pre> |
| Intent intent = new Intent(Intent.ACTION_SEND); |
| intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); |
| startActivity(intent); |
| </pre> |
| |
| <p>인텐트에 추가된 {@link android.content.Intent#EXTRA_EMAIL} 추가 사항은 이메일이 전송되어야 할 이메일 주소의 |
| 문자열 배열입니다. 이메일 애플리케이션이 이 인텐트에 |
| 응답하면, 애플리케이션은 추가 사항이 제공한 문자열 배열을 읽어낸 다음 이를 이메일 작성 양식의 |
| "수신" 필드에 배치합니다. 이 상황에서 이메일 애플리케이션의 액티비티가 시작되고 사용자가 |
| 작업을 끝내면 본인의 액티비티가 재개되는 것입니다.</p> |
| |
| |
| |
| |
| <h3 id="StartingAnActivityForResult">결과에 대한 액티비티 시작하기</h3> |
| |
| <p>때로는 시작한 액티비티에서 결과를 받고 싶을 수도 있습니다. 그런 경우, |
| ({@link android.app.Activity#startActivity |
| startActivity()} 대신) {@link android.app.Activity#startActivityForResult |
| startActivityForResult()}를 호출해서 액티비티를 시작합니다. 그런 다음 후속 액티비티에서 결과를 |
| 받으려면, {@link android.app.Activity#onActivityResult onActivityResult()} 콜백 |
| 메서드를 구현합니다. 해당 후속 액티비티가 완료되면, 이것이 {@link |
| android.content.Intent} 형식으로 결과를 {@link android.app.Activity#onActivityResult onActivityResult()} |
| 메서드에 반환합니다.</p> |
| |
| <p>예를 들어 사용자가 연락처 중에서 하나를 고를 수 있도록 하고 싶을 수 있습니다. |
| 즉 여러분의 액티비티가 해당 연락처의 정보로 무언가 할 수 있도록 하는 것입니다. 그와 같은 인텐트를 생성하고 결과를 처리하려면 |
| 다음과 같이 하면 됩니다.</p> |
| |
| <pre> |
| private void pickContact() { |
| // Create an intent to "pick" a contact, as defined by the content provider URI |
| Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); |
| startActivityForResult(intent, PICK_CONTACT_REQUEST); |
| } |
| |
| @Override |
| protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
| // If the request went well (OK) and the request was PICK_CONTACT_REQUEST |
| if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { |
| // Perform a query to the contact's content provider for the contact's name |
| Cursor cursor = getContentResolver().query(data.getData(), |
| new String[] {Contacts.DISPLAY_NAME}, null, null, null); |
| if (cursor.moveToFirst()) { // True if the cursor is not empty |
| int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); |
| String name = cursor.getString(columnIndex); |
| // Do something with the selected contact's name... |
| } |
| } |
| } |
| </pre> |
| |
| <p>이 예시는 액티비티 결과를 처리하기 위해 {@link |
| android.app.Activity#onActivityResult onActivityResult()} 메서드에서 사용해야 할 기본 논리를 |
| 나타낸 것입니다. 첫 번째 조건은 요청이 성공적인지 확인합니다. 요청에 성공했다면 |
| {@code resultCode}가 {@link android.app.Activity#RESULT_OK}가 됩니다. 또한, 이 결과가 응답하는 요청이 |
| 알려져 있는지도 확인합니다. 이 경우에는 {@code requestCode}가 |
| {@link android.app.Activity#startActivityForResult |
| startActivityForResult()}와 함께 전송된 두 번째 매개변수와 일치합니다. 여기서부터 코드가 |
| {@link android.content.Intent}({@code data} 매개변수)로 반환된 데이터를 쿼리하여 액티비티 결과를 처리합니다.</p> |
| |
| <p>그러면 {@link |
| android.content.ContentResolver}가 콘텐츠 제공자에 대한 쿼리를 수행하고, 콘텐츠 제공자는 쿼리된 데이터를 읽을 수 있게 허용하는 |
| {@link android.database.Cursor}를 반환합니다. 자세한 내용은 |
| <a href="{@docRoot}guide/topics/providers/content-providers.html">콘텐츠 제공자</a> 문서를 참조하십시오.</p> |
| |
| <p>인텐트 사용에 관한 자세한 정보는 <a href="{@docRoot}guide/components/intents-filters.html">인텐트 및 인텐트 |
| 필터</a>문서를 참조하십시오.</p> |
| |
| |
| <h2 id="ShuttingDown">액티비티 종료하기</h2> |
| |
| <p>액티비티를 종료하려면 해당 액티비티의 {@link android.app.Activity#finish |
| finish()} 메서드를 호출하면 됩니다. |
| {@link android.app.Activity#finishActivity finishActivity()}를 호출하여 이전에 시작한 별도의 액티비티를 종료할 수도 있습니다.</p> |
| |
| <p class="note"><strong>참고:</strong> 대부분의 경우, 이와 같은 메서드를 사용하여 액티비티를 명시적으로 |
| 종료해서는 안 됩니다. 다음 섹션에서 액티비티 수명 주기에 관해 논의한 바와 같이, |
| Android 시스템이 액티비티의 수명을 대신 관리해주므로 직접 액티비티를 종료하지 |
| 않아도 됩니다. 이와 같은 메서드를 호출하면 예상되는 사용자 |
| 환경에 부정적인 영향을 미칠 수 있으며, 따라서 사용자가 액티비티의 이 인스턴스에 돌아오는 것을 절대 바라지 않는 경우에만 |
| 사용해야 합니다.</p> |
| |
| |
| <h2 id="Lifecycle">액티비티 수명 주기 관리하기</h2> |
| |
| <p>콜백 메서드를 구현하여 액티비티의 수명 주기를 관리하는 것은 |
| 강력하고 유연한 애플리케이션 개발에 |
| 대단히 중요한 역할을 합니다. 액티비티의 수명 주기는 다른 액티비티와의 관계, |
| 액티비티의 작업과 백 스택 등에 직접적으로 영향을 받습니다.</p> |
| |
| <p>액티비티는 기본적으로 세 가지 상태로 존재할 수 있습니다.</p> |
| |
| <dl> |
| <dt><i>재개됨</i></dt> |
| <dd>액티비티가 화면 전경에 있으며 사용자의 초점이 맞춰져 있습니다 (이 상태를 때로는 |
| "실행 중"이라고 일컫기도 합니다).</dd> |
| |
| <dt><i>일시정지됨</i></dt> |
| <dd>다른 액티비티가 전경에 나와 있고 사용자의 시선을 집중시키고 있지만, 이 액티비티도 여전히 표시되어 있습니다. 다시 말해, |
| 다른 액티비티가 이 액티비티 위에 표시되어 있으며 해당 액티비티는 부분적으로 투명하거나 |
| 전체 화면을 덮지 않는 상태라는 뜻입니다. 일시정지된 액티비티는 완전히 살아있지만({@link android.app.Activity} |
| 개체가 메모리에 보관되어 있고, 모든 상태 및 구성원 정보를 유지하며, |
| 창 관리자에 붙어 있는 상태로 유지됨), 메모리가 극히 부족한 경우 시스템이 중단시킬 수 있습니다.</dd> |
| |
| <dt><i>정지됨</i></dt> |
| <dd>이 액티비티가 다른 액티비티에 완전히 가려진 상태입니다(액티비티가 이제 |
| "배경"에 위치함). 중단된 액티비티도 여전히 살아 있기는 마찬가지입니다({@link android.app.Activity} |
| 개체가 메모리에 보관되어 있고, 모든 상태와 구성원 정보를 유지하시만 창 관리자에 붙어 있지 <em>않음</em> |
| ). 그러나, 이는 더 이상 사용자에게 표시되지 않으며 |
| 다른 곳에 메모리가 필요하면 시스템이 종료시킬 수 있습니다.</dd> |
| </dl> |
| |
| <p>액티비티가 일시정지 또는 중단된 상태이면, 시스템이 이를 메모리에서 삭제할 수 있습니다. 이러기 위해서는 |
| 종료를 요청하거나({@link android.app.Activity#finish finish()} 메서드를 호출) 단순히 이 액티비티의 프로세스를 중단시키면 |
| 됩니다. 액티비티가 다시 열릴 때에는(종료 또는 중단된 후에) 처음부터 다시 생성해야 |
| 합니다.</p> |
| |
| |
| |
| <h3 id="ImplementingLifecycleCallbacks">수명 주기 콜백 구현하기</h3> |
| |
| <p>위에서 설명한 바와 같이 액티비티가 여러 가지 상태를 오가며 전환되면, 이와 같은 내용이 |
| 여러 가지 콜백 메서드를 통해 통지됩니다. 콜백 메서드는 모두 후크로서, |
| 액티비티 상태가 변경될 때 적절한 작업을 하기 위해 이를 재정의할 수 있습니다. 다음의 골격 |
| 액티비티에는 기본 수명 주기 메서드가 각각 하나씩 포함되어 있습니다.</p> |
| |
| |
| <pre> |
| public class ExampleActivity extends Activity { |
| @Override |
| public void {@link android.app.Activity#onCreate onCreate}(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| // The activity is being created. |
| } |
| @Override |
| protected void {@link android.app.Activity#onStart onStart()} { |
| super.onStart(); |
| // The activity is about to become visible. |
| } |
| @Override |
| protected void {@link android.app.Activity#onResume onResume()} { |
| super.onResume(); |
| // The activity has become visible (it is now "resumed"). |
| } |
| @Override |
| protected void {@link android.app.Activity#onPause onPause()} { |
| super.onPause(); |
| // Another activity is taking focus (this activity is about to be "paused"). |
| } |
| @Override |
| protected void {@link android.app.Activity#onStop onStop()} { |
| super.onStop(); |
| // The activity is no longer visible (it is now "stopped") |
| } |
| @Override |
| protected void {@link android.app.Activity#onDestroy onDestroy()} { |
| super.onDestroy(); |
| // The activity is about to be destroyed. |
| } |
| } |
| </pre> |
| |
| <p class="note"><strong>참고:</strong> 이와 같은 수명 주기 메서드를 구현하려면, 항상 |
| 슈퍼클래스 구현을 호출한 다음에만 다른 작업을 시작할 수 있습니다(위의 예시 참조).</p> |
| |
| <p>이와 같은 메서드를 모두 합쳐 한 액티비티의 수명 주기 전체를 정의합니다. 이러한 메서드를 구현함으로써 |
| 액티비티 수명 주기 내의 세 가지 중첩된 루프를 모니터링할 수 있습니다. </p> |
| |
| <ul> |
| <li>한 액티비티의 <b>전체 수명</b>은 {@link |
| android.app.Activity#onCreate onCreate()} 호출과 {@link |
| android.app.Activity#onDestroy} 호출 사이를 말합니다. 액티비티는 {@link android.app.Activity#onCreate onCreate()}에서 |
| "전체" 상태(레이아웃 정의 등)의 설정을 수행한 다음 나머지 리소스를 |
| 모두 {@link android.app.Activity#onDestroy}에 해제해야 합니다. 예를 들어, |
| 액티비티에 네트워크에서 데이터를 다운로드하기 위해 배경에서 실행 중인 스레드가 있는 경우, 이는 |
| 해당 스레드를 {@link android.app.Activity#onCreate onCreate()}에서 생성한 다음 {@link |
| android.app.Activity#onDestroy}에서 그 스레드를 중단할 수 있습니다.</li> |
| |
| <li><p>액티비티의 <b>가시적 수명</b>은 {@link |
| android.app.Activity#onStart onStart()} 호출에서 {@link |
| android.app.Activity#onStop onStop()} 호출 사이를 말합니다. 이 기간 중에는 사용자가 액티비티를 화면에서 보고 이와 |
| 상호작용할 수 있습니다. 예컨대 {@link android.app.Activity#onStop onStop()}이 호출되어 |
| 새 액티비티가 시작되면 이 액티비티는 더 이상 표시되지 않게 됩니다. 이와 같은 두 가지 메서드 중에서 |
| 사용자에게 액티비티를 표시하는 데 필요한 리소스를 유지하면 됩니다. 예를 들어, |
| {@link |
| android.app.Activity#onStart onStart()}에서 {@link android.content.BroadcastReceiver}를 등록하고 UI에 영향을 미치는 변화를 모니터링하고 |
| {@link android.app.Activity#onStop onStop()}에서 등록을 해제하면 사용자는 여러분이 무엇을 표시하고 있는지 더 이상 볼 수 |
| 없게 됩니다. 시스템은 액티비티의 전체 수명 내내 {@link android.app.Activity#onStart onStart()} 및 {@link |
| android.app.Activity#onStop onStop()}을 여러 번 호출할 수 있으며, 이때 |
| 액티비티는 사용자에게 표시되었다 숨겨지는 상태를 오가게 됩니다.</p></li> |
| |
| <li><p>액티비티의 <b>전경 수명</b>은 {@link |
| android.app.Activity#onResume onResume()} 호출에서 {@link android.app.Activity#onPause |
| onPause()} 호출 사이를 말합니다. 이 기간 중에는 이 액티비티가 화면에서 다른 모든 액티비티 앞에 표시되며 사용자 입력도 |
| 여기에 집중됩니다. 액티비티는 전경에 나타났다 숨겨지는 전환을 자주 반복할 수 있습니다. 예를 들어 |
| , 기기가 절전 모드에 들어가거나 대화 상자가 |
| 나타나면 {@link android.app.Activity#onPause onPause()}가 호출됩니다. 이 상태는 자주 전환될 수 있으므로, 이 두 가지 메서드의 코드는 |
| 상당히 가벼워야 합니다. 그래야 전환이 느려 사용자를 기다리게 하는 일을 피할 수 있습니다.</p></li> |
| </ul> |
| |
| <p>그림 1은 액티비티가 상태 사이에서 취할 수 있는 이와 같은 루프와 경로를 나타낸 것입니다. |
| 직사각형이 액티비티가 여러 상태 사이를 전환할 때 작업을 수행하도록 |
| 구현할 수 있는 콜백 메서드를 나타냅니다. <p> |
| |
| <img src="{@docRoot}images/activity_lifecycle.png" alt="" /> |
| <p class="img-caption"><strong>그림 1.</strong> 액티비티 수명 주기입니다.</p> |
| |
| <p>같은 수명 주기 콜백 메서드가 표 1에 나열되어 있으며, 이 표는 각 콜백 |
| 메서드를 더욱 상세하게 설명하며 액티비티의 전반적인 |
| 수명 주기 내에서 각 메서드의 위치를 나타내기도 합니다. 여기에는 콜백 메서드가 완료된 다음 |
| 시스템이 액티비티를 중단시킬 수 있는지 여부도 포함되어 있습니다.</p> |
| |
| <p class="table-caption"><strong>표 1.</strong> 액티비티 수명 주기 |
| 콜백 메서드의 요약입니다.</p> |
| |
| <table border="2" width="85%" frame="hsides" rules="rows"> |
| <colgroup align="left" span="3"></colgroup> |
| <colgroup align="left"></colgroup> |
| <colgroup align="center"></colgroup> |
| <colgroup align="center"></colgroup> |
| |
| <thead> |
| <tr><th colspan="3">메서드</th> <th>설명</th> <th>완료 후 중단 가능?</th> <th>다음</th></tr> |
| </thead> |
| |
| <tbody> |
| <tr> |
| <td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td> |
| <td>액티비티가 처음 생성되었을 때 호출됩니다. |
| 이곳에서 일반적인 정적 설정을 모두 수행해야 합니다. |
| 즉 보기 생성, 목록에 데이터 바인딩하기 등을 말합니다. 이 메서드에는 |
| 액티비티의 이전 상태가 캡처된 경우 해당 상태를 포함한 |
| 번들 개체가 전달됩니다(이 문서 나중에 나오는 <a href="#actstate">액티비티 상태 저장하기</a>를 참조하십시오 |
| ). |
| <p>이 뒤에는 항상 {@code onStart()}가 따라옵니다.</p></td> |
| <td align="center">아니요</td> |
| <td align="center">{@code onStart()}</td> |
| </tr> |
| |
| <tr> |
| <td rowspan="5" style="border-left: none; border-right: none;"> </td> |
| <td colspan="2" align="left"><code>{@link android.app.Activity#onRestart |
| onRestart()}</code></td> |
| <td>액티비티가 중단되었다가 다시 시작되기 직전에 |
| 호출됩니다. |
| <p>이 뒤에는 항상 {@code onStart()}가 따라옵니다.</p></td> |
| <td align="center">아니요</td> |
| <td align="center">{@code onStart()}</td> |
| </tr> |
| |
| <tr> |
| <td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td> |
| <td>액티비티가 사용자에게 표시되기 직전에 호출됩니다. |
| <p>액티비티가 전경으로 나오면 {@code onResume()}이 뒤에 따라오고, |
| 액티비티가 숨겨지면 {@code onStop()}이 뒤에 따라옵니다.</p></td> |
| <td align="center">아니요</td> |
| <td align="center">{@code onResume()} <br/>또는<br/> {@code onStop()}</td> |
| </tr> |
| |
| <tr> |
| <td rowspan="2" style="border-left: none;"> </td> |
| <td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td> |
| <td>액티비티가 시작되고 사용자와 상호 작용하기 직전에 |
| 호출됩니다. 이 시점에서 액티비티는 액티비티 |
| 스택의 맨 위에 있으며, 사용자 입력이 입력되고 있습니다. |
| <p>이 뒤에는 항상 {@code onPause()}가 따라옵니다.</p></td> |
| <td align="center">아니요</td> |
| <td align="center">{@code onPause()}</td> |
| </tr> |
| |
| <tr> |
| <td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td> |
| <td>시스템이 다른 액티비티를 재개하기 직전에 |
| 호출됩니다. 이 메서드는 일반적으로 데이터를 유지하기 위해 저장되지 않은 변경 사항을 |
| 커밋하는 데, 애니메이션을 비롯하여 CPU를 소모하는 기타 작업을 중단하는 등 |
| 여러 가지 용도에 사용됩니다. 이 메서드는 무슨 일을 하든 매우 빨리 끝내야 합니다. |
| 이것이 반환될 때까지 다음 액티비티가 재개되지 않기 때문입니다. |
| <p>액티비티가 다시 전경으로 돌아오면 {@code onResume()}이 뒤에 따라오고 |
| 액티비티가 사용자에게 보이지 않게 되면{@code onStop()}이 뒤에 따라옵니다. |
| </td> |
| <td align="center"><strong style="color:#800000">예</strong></td> |
| <td align="center">{@code onResume()} <br/>또는<br/> {@code onStop()}</td> |
| </tr> |
| |
| <tr> |
| <td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td> |
| <td>액티비티가 더 이상 사용자에게 표시되지 않게 되면 호출됩니다. 이것은 |
| 액티비티가 소멸되고 있기 때문에 일어날 수도 있고, 다른 액티비티 |
| (기존 것이든 새로운 것이든)가 재개되어 이것을 덮고 있기 때문일 수도 있습니다. |
| <p>액티비티가 다시 사용자와 상호 작용하면 |
| {@code onRestart()}가 뒤에 따라오고 액티비티가 사라지면 |
| {@code onDestroy()}가 뒤에 따라옵니다.</p></td> |
| <td align="center"><strong style="color:#800000">예</strong></td> |
| <td align="center">{@code onRestart()} <br/>또는<br/> {@code onDestroy()}</td> |
| </tr> |
| |
| <tr> |
| <td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy |
| onDestroy()}</code></td> |
| <td>액티비티가 소멸되기 전에 호출됩니다. 이것이 액티비티가 받는 |
| 마지막 호출입니다. 이것이 호출될 수 있는 경우는 액티비티가 |
| 완료되는 중이라서(누군가가 여기에 <code>{@link android.app.Activity#finish |
| finish()}</code>를 호출해서)일 수도 있고, 시스템이 공간을 절약하기 위해 액티비티의 이 인스턴스를 일시적으로 소멸시키는 |
| 중이기 때문일 수도 있습니다. 이와 같은 |
| 두 가지 시나리오는 <code>{@link |
| android.app.Activity#isFinishing isFinishing()}</code> 메서드로 구분할 수 있습니다.</td> |
| <td align="center"><strong style="color:#800000">예</strong></td> |
| <td align="center"><em>없음</em></td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <p>"완료 후 중단 가능?"이라는 레이블이 붙은 열은 |
| 시스템이 <em>메서드가 반환된 후</em> 액티비티 코드의 다른 줄을 실행하지 않고도 |
| 언제든 이 액티비티를 호스팅하는 프로세스를 중단시킬 수 있는지 여부를 나타냅니다. 다음 세 가지 메서드가 "예"로 표시되어 있습니다({@link |
| android.app.Activity#onPause |
| onPause()}, {@link android.app.Activity#onStop onStop()} 및 {@link android.app.Activity#onDestroy |
| onDestroy()}). {@link android.app.Activity#onPause onPause()}가 세 가지 메서드 중에서 |
| 첫 번째이므로, 액티비티가 생성되면 {@link android.app.Activity#onPause onPause()}는 프로세스가 <em>지워지기 전에</em> |
| 반드시 호출되는 마지막 메서드입니다. |
| 시스템이 비상 시에 메모리를 복구해야 할 경우, {@link |
| android.app.Activity#onStop onStop()}와 {@link android.app.Activity#onDestroy onDestroy()}는 |
| 호출되지 않을 수도 있습니다. 따라서, 중요한 영구적 데이터(사용자 편집 등)를 보관하기 위해 작성하는 경우에는 {@link android.app.Activity#onPause onPause()}를 사용해야 |
| 합니다. 그러나, {@link android.app.Activity#onPause onPause()} 중에 |
| 어느 정보를 유지해야 할지는 조심해서 선택해야 합니다. 이 메서드에 차단 절차가 있으면 |
| 다음 액티비티로의 전환을 차단하고 사용자 경험을 느려지게 할 수 있기 |
| 때문입니다.</p> |
| |
| <p> <b>중단 가능한</b> 열에 "아니요"로 표시된 메서드는 액티비티를 호스팅하는 프로세스를 |
| 보호하여 호출된 즉시 중단되지 않도록 방지합니다. 따라서 액티비티는 |
| {@link android.app.Activity#onPause onPause()}가 반환되는 시기부터 |
| {@link android.app.Activity#onResume onResume()}이 호출되는 시기 사이에 중단시킬 수 있습니다. 다시 중단시킬 수 있는 상태가 되려면 |
| {@link android.app.Activity#onPause onPause()}가 다시 호출되어 반환되어야 합니다. </p> |
| |
| <p class="note"><strong>참고:</strong> 표 1에 나타난 이런 정의에 |
| 따르면 엄밀히 말해 "중단 가능한" 것이 아닌 액티비티라도 시스템이 중단시킬 수는 있습니다. 다만 이것은 다른 리소스가 없는 |
| 극단적인 상황에서만 발생합니다. 액티비티가 중단될 수 있는 시기가 |
| 언제인지는 <a href="{@docRoot}guide/components/processes-and-threads.html">프로세스 및 |
| 스레딩</a> 문서에서 보다 자세히 논의합니다.</p> |
| |
| |
| <h3 id="SavingActivityState">액티비티 상태 저장하기</h3> |
| |
| <p><a href="#Lifecycle">액티비티 수명 주기 관리하기</a> 도입부에서는 액티비티가 |
| 일시중지되거나 |
| 중단되었더라도 액티비티의 상태는 그대로 유지된다고 잠시 언급한 바 있습니다. 이것은 |
| {@link android.app.Activity} 개체가 일시중지되거나 중단된 경우에도 |
| 메모리 안에 그대로 보관되었기 때문에 가능합니다. 즉 이 액티비티의 구성원과 현재 상태에 대한 모든 정보가 아직 살아 있다는 뜻입니다. 따라서, 사용자가 |
| 액티비티 내에서 변경한 모든 내용도 그대로 유지되어 액티비티가 전경으로 |
| 돌아갈 때("재개"될 때) 그와 같은 변경 사항도 그대로 존재하게 됩니다.</p> |
| |
| <p>그러나 시스템이 메모리를 복구하기 위해 액티비티를 소멸시키는 경우에는 {@link |
| android.app.Activity} 개체가 소멸되므로 시스템이 액티비티의 상태를 온전히 유지한 채로 간단하게 재개할 수 없게 |
| 됩니다. 대신, 사용자가 다시 이 액티비티로 이동해 오면 시스템이 {@link android.app.Activity} 개체를 |
| 다시 생성해야 합니다. 하지만, 사용자는 시스템이 |
| 해당 액티비티를 소멸시켰다가 다시 생성했다는 것을 모릅니다. |
| 따라서 액티비티가 예전과 똑같을 것이라고 예상할 것입니다. 이런 상황에서는 |
| 액티비티 상태에 관한 정보를 저장할 수 있는 추가 콜백 메서드 |
| {@link |
| android.app.Activity#onSaveInstanceState onSaveInstanceState()}를 구현하여 액티비티 상태에 관한 중요한 정보를 보존할 수 있습니다.</p> |
| |
| <p>시스템이 {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} |
| 를 호출한 다음에 액티비티를 소멸되기 쉽게 만듭니다. 시스템은 {@link |
| android.os.Bundle#putString putString()}와 {@link |
| android.os.Bundle#putInt putInt()} 같은 메서드를 사용하여, 이 메서드에 |
| 액티비티에 관한 정보를 이름-값 쌍으로 저장할 수 있는 {@link android.os.Bundle}을 전달합니다. |
| 그리고 시스템이 애플리케이션 프로세스를 지우고 |
| 사용자가 액티비티로 다시 돌아오면, 시스템이 액티비티를 다시 생성하고 |
| {@link android.os.Bundle}을 {@link android.app.Activity#onCreate onCreate()}와 {@link |
| android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}에게 전달합니다. 이들 메서드 중 |
| 하나를 사용하여 {@link android.os.Bundle}에서 저장된 상태를 추출하고 액티비티 상태 |
| 를 복원할 수 있습니다. 복구할 상태 정보가 없는 경우, 여러분에게 전달되는 {@link |
| android.os.Bundle}은 null입니다(액티비티가 처음 생성되었을 때 이런 경우가 |
| 발생합니다).</p> |
| |
| <img src="{@docRoot}images/fundamentals/restore_instance.png" alt="" /> |
| <p class="img-caption"><strong>그림 2.</strong> 액티비티의 상태가 온전한 채로 사용자의 |
| 초점에 다시 돌아오는 데에는 두 가지 방식이 있습니다. 하나는 액티비티가 소멸되었다가 다시 생성되어 액티비티가 |
| 이전에 저장된 상태를 복구해야 하는 경우, 다른 하나는 액티비티가 중단되었다가 재개되었으며 |
| 액티비티 상태가 온전히 유지된 경우입니다.</p> |
| |
| <p class="note"><strong>참고:</strong> 상태를 저장할 필요가 없는 경우도 있으므로 액티비티가 소멸되기 전에 {@link |
| android.app.Activity#onSaveInstanceState onSaveInstanceState()}가 호출된다는 보장은 없습니다 |
| |
| (예컨대 사용자가 |
| 명시적으로 |
| 액티비티를 닫기 위해 <em>뒤로</em> 버튼을 눌러서 액티비티를 떠날 때가 이에 해당합니다). 시스템이 {@link android.app.Activity#onSaveInstanceState |
| onSaveInstanceState()}를 호출하는 경우, {@link |
| android.app.Activity#onStop onStop()} 전에 호출하는 것이 일반적이며 {@link android.app.Activity#onPause |
| onPause()} 전에 호출할 가능성도 높습니다.</p> |
| |
| <p>그러나 아무것도 하지 않고 {@link |
| android.app.Activity#onSaveInstanceState onSaveInstanceState()}를 구현하지 않더라도, |
| {@link android.app.Activity} 클래스의 기본 구현 {@link |
| android.app.Activity#onSaveInstanceState onSaveInstanceState()}가 일부 액티비티 상태를 복구합니다. 특히, 기본 |
| 구현은 레이아웃에서 {@link |
| android.view.View}가 나올 때마다 해당하는 {@link |
| android.view.View#onSaveInstanceState onSaveInstanceState()} 메서드를 호출하고, 이 때문에 각 보기가 저장해야 하는 자체 관련 정보를 제공할 수 |
| 있게 해줍니다. Android 프레임워크를 사용하는 위젯은 거의 대부분 이 메서드를 |
| 필요에 따라 구현하므로, UI에 눈에 보이는 변경이 있으면 모두 자동으로 저장되며 액티비티를 다시 |
| 생성하면 복구됩니다. 예를 들어, {@link android.widget.EditText} 위젯은 사용자가 입력한 모든 텍스트 |
| 를 저장하고 {@link android.widget.CheckBox} 위젯은 확인 여부를 저장합니다. |
| 여러분이 해야 할 유일한 작업은 상태를 저장하고자 하는 각 위젯에 고유 ID(<a href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a> |
| 속성 포함)를 제공하는 것입니다. 위젯에 ID가 없으면 시스템이 그 위젯의 상태를 |
| 저장할 수 없습니다.</p> |
| |
| <div class="sidebox-wrapper"> |
| <div class="sidebox"> |
| <p>또한, |
| {@link android.R.attr#saveEnabled android:saveEnabled} 속성을 {@code "false"}로 설정하거나 |
| {@link android.view.View#setSaveEnabled setSaveEnabled()} 메서드를 호출해서 레이아웃의 보기가 상태를 저장하지 못하도록 명시적으로 막을 수 있습니다. 보통은 이것을 비활성화해서는 |
| 안 되지만, 액티비티 UI의 상태를 다르게 복구하고자 하는 경우 그렇게 할 수도 있습니다.</p> |
| </div> |
| </div> |
| |
| <p>{@link |
| android.app.Activity#onSaveInstanceState onSaveInstanceState()}의 기본 구현이 액티비티 UI의 유용한 정보를 저장하지만 |
| 추가 정보를 저장하려면 이를 재설정해야 할 수도 있습니다. |
| 예를 들어, 액티비티 수명에서 변경된 구성원 값을 변경해야 할 수도 있습니다( |
| UI에서 복구된 값과 상관관계가 있을 수 있지만 이런 UI 값을 보유한 구성원은 기본적으로 복구되지 않습니다 |
| ).</p> |
| |
| <p>{@link |
| android.app.Activity#onSaveInstanceState onSaveInstanceState()}의 기본 구현이 UI 상태를 저장하는 데 도움이 되기 때문에, |
| 추가 상태 정보를 저장하기 위해 이 메서드를 재정의하려면 |
| 작업을 하기 전에 항상{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}의 슈퍼클래스 구현 |
| 을 호출해야 합니다. 이와 마찬가지로 {@link |
| android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}를 재정의하는 경우, 이것의 슈퍼클래스 구현을 호출해야 하기도 합니다. |
| 이렇게 해야 기본 구현이 보기 상태를 복구할 수 있습니다.</p> |
| |
| <p class="note"><strong>참고:</strong> {@link android.app.Activity#onSaveInstanceState |
| onSaveInstanceState()}의 호출이 보장되지 않으므로 |
| 이것은 액티비티의 일시적 상태(UI의 상태 |
| )를 기록하는 데에만 사용하고, 영구 데이터를 보관하는 데 사용해서는 안 됩니다. 대신, 사용자가 액티비티를 떠날 때 영구적인 데이터(데이터베이스에 저장되어야 |
| 하는 데이터 등)를 저장하려면 {@link |
| android.app.Activity#onPause onPause()}를 사용해야 합니다.</p> |
| |
| <p>애플리케이션의 상태 저장 기능을 시험하는 좋은 방법은 기기를 회전해보고 화면 방향이 |
| 바뀌는지 확인하는 것입니다. 화면 방향이 바뀌면 시스템은 액티비티를 |
| 소멸시켰다가 다시 생성하여 새 화면 구성에서 이용할 수 있을지 모르는 대체 |
| 리소스를 적용합니다. 이 이유 하나만으로도 액티비티가 다시 생성되었을 때 상태를 |
| 완전히 복구할 수 있어야 한다는 점이 대단히 중요합니다. 사용자는 애플리케이션을 사용하면서 화면을 |
| 자주 돌리기 때문입니다.</p> |
| |
| |
| <h3 id="ConfigurationChanges">구성 변경 처리하기</h3> |
| |
| <p>몇몇 기기 구성은 런타임 중에 변경될 수 있습니다(예: 화면 방향, 키보드 가용성 |
| 및 언어 등). 이러한 변경이 발생하면 Android는 실행 중인 액티비티를 다시 생성합니다 |
| (시스템이 {@link android.app.Activity#onDestroy}를 호출하고 즉시 {@link |
| android.app.Activity#onCreate onCreate()}를 호출합니다). 이런 동작은 |
| 여러분이 제공한 대체 리소스로 애플리케이션을 자동으로 다시 로딩함으로써 새로운 구성에 애플리케이션이 적응하는 것을 돕도록 |
| 설계되었습니다 |
| (예: 다양한 화면 방향과 크기에 대한 다양한 레이아웃).</p> |
| |
| <p>액티비티를 적절히 설계하여 화면 방향 변경으로 인한 재시작을 감당할 수 있으며 |
| 위에 설명한 것처럼 액티비티 상태를 복구할 수 있도록 하면, 애플리케이션이 액티비티 수명 주기에서 |
| 예기치 못한 이벤트가 일어나도 더욱 탄력적으로 복구될 수 있습니다.</p> |
| |
| <p>이러한 재시작을 처리하는 가장 좋은 방법은 이전 섹션에서 논의한 바와 같이 |
| {@link |
| android.app.Activity#onSaveInstanceState onSaveInstanceState()}와 {@link |
| android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}(또는 {@link |
| android.app.Activity#onCreate onCreate()})를 사용하여 액티비티 상태를 저장하고 복구하는 것입니다.</p> |
| |
| <p>런타임에 발생하는 구성 변경과 그 처리 방법에 대한 자세한 정보는 |
| <a href="{@docRoot}guide/topics/resources/runtime-changes.html">런타임 변경 |
| 처리하기</a>에 대한 가이드를 읽어보십시오.</p> |
| |
| |
| |
| <h3 id="CoordinatingActivities">액티비티 조정하기</h3> |
| |
| <p>한 액티비티가 다른 액티비티를 시작하면, 둘 모두 수명 주기 전환을 겪습니다. 첫 번째 액티비티는 |
| 일시중지하고 중단되는 반면(배경에서 계속 보이는 경우에는 중단되지 않습니다만), 다른 액티비티는 |
| 생성되는 것입니다. 이와 같은 액티비티가 디스크 또는 다른 속에 저장된 데이터를 공유하는 경우, |
| 첫 번째 액티비티는 두 번째 액티비티가 생성되기 전에 완전히 중단되지 않는다는 점을 이해하는 것이 중요합니다. |
| 그렇다기보다는, 두 번째 액티비티의 시작 과정이 첫 번째 액티비티 중단 과정과 겹쳐 일어납니다. |
| </p> |
| |
| <p>수명 주기 콜백은 분명히 정의된 순서가 있으며 특히 두 개의 액티비티가 |
| 같은 프로세스 안에 있으면서 하나가 다른 하나를 시작하는 경우 순서가 더욱 확실합니다. 다음은 액티비티 A가 |
| 액티비티 B를 시작할 때 발생하는 작업 순서입니다. </p> |
| |
| <ol> |
| <li>액티비티 A의 {@link android.app.Activity#onPause onPause()} 메서드가 실행됩니다.</li> |
| |
| <li>액티비티 B의 {@link android.app.Activity#onCreate onCreate()}, {@link |
| android.app.Activity#onStart onStart()}, {@link android.app.Activity#onResume onResume()} |
| 메서드가 순차적으로 실행됩니다 (이제 사용자는 액티비티 B에 시선을 집중합니다).</li> |
| |
| <li>그런 다음, 액티비티 A가 더 이상 화면에 표시되지 않는 경우 이 액티비티의 {@link |
| android.app.Activity#onStop onStop()} 메서드가 실행됩니다.</li> |
| </ol> |
| |
| <p>이처럼 수명 주기 콜백의 순서를 예측할 수 있기 때문에 한 액티비티에서 다른 액티비티로 전환되는 |
| 정보를 관리할 수 있습니다. 예를 들어 첫 번째 액티비티가 중단될 때 데이터베이스에 |
| 내용을 작성해서 다음 액티비티가 그 내용을 읽을 수 있도록 하려면, 데이터베이스에는 |
| {@link android.app.Activity#onPause onPause()} 중에({@link |
| android.app.Activity#onStop onStop()} 중이 아니라) 쓰기 작업을 해야 합니다.</p> |
| |
| <!-- |
| <h2>Beginner's Path</h2> |
| |
| <p>For more information about how Android maintains a history of activities and |
| enables user multitasking, continue with the <b><a |
| href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back |
| Stack</a></b> document.</p> |
| --> |