액티비티에서 finish() 를 호출하여 액티비티를 소멸하는 신호를 주거나 사용자가 Back 버튼을 눌렀을 때와 같이, 일반적으로 앱을 파괴하도록 하는 몇가지의 시나리오가 있습니다.시스템은 화면 전면(foreground)에 있는 액티비티가 더 많은 리소스들을 요구하면 메모리를 복구하기 위해 오랫동안 사용되지 않고 있는 백그라운드(background) 프로세스(process)를 셧다운(shut down)해야만 하므로 여러분의 액티비티를 파괴할 지도 모릅니다.
사용자가 Back 버튼을 누르거나 액티비티 스스로 finish 를 해서 여러분의 액티비티를 파괴(destroy)했다는 것은 액티비티는 더이상 필요로 하지 않다는 것을 표시하는 행위이므로 액티비티 인스턴스는 영원히 사라진 다는 개념입니다. 어쨋든, 시스템이 시스템 제약으로 인하여 액티비티를 파괴할 때(보통의 앱 동작을 안하고), 심지어 실제로 액티비티 인스턴스(instance)가 파괴되더라도 시스템은 액티비티가 존재했었다는 것을 기억합니다. 그래서 시스템은 액티비티가 파괴될 때 액티비티의 상태가 기록되어 있는 저장된 데이터 세트(set)를 사용하여 새로운 액티비티 인스턴스를 생성합니다. 이전 상태를 복구하는데 사용하는 저장된 데이터(data)는 "instance state" 라고 불려지며 key-value 쌍으로 저장된 Bundle 객체의 컬렉션(collection)입니다.
Caution : 여러분의 액티비티는 사용자가 화면을 회전할 때 마다 파괴되고(destroyed) 다시 생성(recreated) 됩니다. 화면의 방향이 바뀌어질때, 시스템이 전면(foreground)에 있는 액티비티를 파괴하고(destroyed) 다시 생성(recreated) 하는 이유는 화면의 설정값들이 바뀔 수도 있고 액티비티가 대체 자원(alternative resources)을 필요로 할 수 도 있기 때문입니다.(마치 레이아웃layout 처럼)
기본적으로, 시스템은 액티비티 레이아웃안에 있는 각 뷰(View) 객체에 대한 정보( EditText 객체 안에 작성되어 있는 텍스트와 같은)를 저장하기 위해 Bundle 인스턴스를 사용합니다. 그래서 만약 여러분의 액티비티 인스턴스가 파괴되고 다시 생성된다면, 레이아웃의 상태는 여러분이 별도의 코드를 작성하지 않고도 복구되어집니다. 어쨋든, 여러분의 액티비티는 사용자의 액티비티 진행상황을 저장하고 있는 멤버변수와 같이 더 많은 상태정보를 가져야 할 수도 있습니다.
Note : Android 시스템이 액티비티안에 있는 뷰의 상태를 복구하기 위해서는 반드시 각 View 들이 android:id 속성에 적용된 유니크한 ID 를 가지고 있어야만 합니다.
액티비티 상태에 대한 추가적인 데이터를 저장하기 위해서, 여러분은 onSaveInstanceState() 콜백(callback) 메소드를 오버라이드(override) 해야만 합니다. 시스템은 사용자가 액티비티를 떠날 때 이 메소들을 호출하며, 액티비티가 의도하지 않게 파괴(destroyed)되어 질때, 저장되어 질 Bundle 객체를 매개변수로 전달합니다. 만약 시스템이 나중에 액티비티 인스턴스(instance)를 다시 생성해야 한다면, onRestoreInstanceState()와 onCreate() 메소드, 둘 모두에게 같은 Bundle 객체를 전달합니다.
그림 2. 시스템이 여러분의 액티비티를 stop 하기 시작하면서, onSaveInstanceState()를 호출합니다.(1) 그래서 여러분은 액티비티를 다시 생성(recreate) 해야하는 경우에 저장하고 싶은 상태 데이터를 추가적으로 지정할 수 있습니다. 만약 액티비티가 파괴되고 같은 인스턴스가 다시 생성되어야 한다면, 시스템은 onCreate() 메소드(1) 와 onRestoreInstanceState() 메소드(3), 둘 모두에 (1)과정에서 정의된 상태 데이터를 전달합니다.
액티비티 상태 저장하기(Save Your Activity State)
---------------------------------------------
여러분의 액티비티가 stop 되기 시작하면서, 시스템은 onSaveInstanceState()를 호출합니다. 그래서 여러분의 액티비티(Activity)는 key-value 쌍의 컬렉션(collection)으로 상태 정보를 저장할 수 있습니다. 기본적으로 이 메소드는 EditText의 Text 나 ListView의 스크롤 위치(scroll position) 같은 액티비티 뷰 계층 상태를 저장하도록 구현되어 있습니다.
액티비티에 대한 추가적인 상태 정보를 저장하기 위해서는 반드시 onSaveInstanceState()를 구현해야만 합니다. 그리고 key-value쌍의 Bundle 객체를 추가해야만 합니다. 예를 들어:
static final String STATE_SCORE = "playerScore"; static final String STATE_LEVEL = "playerLevel"; ... @Override public void onSaveInstanceState(Bundle savedInstanceState) { // Save the user's current game state savedInstanceState.putInt(STATE_SCORE, mCurrentScore); savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state super.onSaveInstanceState(savedInstanceState); } |
Caution : 기본 구현으로 뷰 계층의 상태를 저장할 수 있도록 onSaveInstanceState() 메소드의 슈퍼클래스(superclass)는 항상 호출해야 합니다.
액티비티 상태 복구하기(Restore Your Activity State)
---------------------------------------------
이전에 destroyed된 액티비티가 다시 생성(recreate)되어 질 때, 여러분은 시스템이 전달한 Bundle 객체로 부터 저장된 상태를 회복할 수 있습니다. onCreate()와 onRestoreInstance() 콜백(callback) 메소드, 둘 모두 인스턴스들(instances)의 상태 정보를 가지고 있는 같은 Bundle 객체를 받게 됩니다.
onCreate() 메소드는 액티비티가 처음 만들어지든 이전에 파괴된 것이 다시 만들어지든 상관없이 호출되어 지기 때문에, 여러분은 반드시 데이터를 읽기 전에 먼저 Bundle 객체가 null 인지 아닌지 체크해야만 합니다. 만약 null 이면, 시스템은 파과되기 이전상태를 복구하는 대신에 새로운 액티비티의 인스턴스를 생성합니다.
onCreate()안에서 몇가지 상태 데이터를 저장하는 방법에 대한 예입니다.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance if (savedInstanceState != null) { // Restore value of members from saved state mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } else { // Probably initialize members with default values for a new instance } ... } |
onCreate() 메소드에서 상태를 복구하는 대신에 onStart() 메소드 다음에 호출되는 onRestoreInstanceState()를 선택할 수도 있습니다. 시스템은 복구하기위한 상태가 저장되어 있을 때만 이 메소드를 호출하기 때문에 여러분은 Bundle 객체가 null 인지 아닌지 체크할 필요가 없습니다.
public void onRestoreInstanceState(Bundle savedInstanceState) { // Always call the superclass so it can restore the view hierarchy super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } |
Caution : 기본적으로 뷰 계층의 상태를 복구할 수 있도록 구현된 onRestoreInstatanceState()의 슈퍼클래스의 메소드는 항상 호출해야만 합니다.
실행 중에 다시 시작하라는 이벤트(화면이 회전할 때와 같이)로 인해 액티비티가 다시 생성되야 할 때에 대한 자세한 내용을 알고싶다면 개발자 사이트의 Handling Runtime Changes 를 읽어보시기 바랍니다.
'Android 개발자사이트 튜토리얼' 카테고리의 다른 글
프레그먼트 만들기 (Creating a Fragment) (0) | 2015.03.27 |
---|---|
Fragment 로 Dynamic(동적) UI 만들기 (0) | 2015.03.27 |
액티비티 정지하기와 재시작하기(Stopping and Restarting an Activity) (0) | 2015.03.27 |
액티비티 일시정지하기와 이어하기(Pausing and Resuming an Activity) (0) | 2015.03.27 |
Activity 시작하기(Starting) 2 (0) | 2015.03.27 |