본문 바로가기

TechLog

WP 실버라이트 프로그램의 시작과 종료, 툼스토닝

최근의 스마트폰 운영체제는 빠른 응답성을 위해 현재 사용자가 사용하고 있는 앱과 핵심 시스템 프로세스만 디바이스의 CPU 자원을 사용할 수 있도록 설계되어 있으며, 스마트폰의 앱을 종료했다가 실행하더라도 사용자가 느끼기에 ‘항상 실행 상태에 있는 것처럼’ 보이도록 디자인 되어 있다. 스마트폰의 특성상 스마트폰 앱은 짧은 시간 동안에 실행과 종료를 반복하게 되며, 이 과정에서 스마트폰의 앱은 부족한 CPU와 메모리 자원을 효율적으로 사용하여 빠른 응답성을 보이도록 개발되어야 한다. 실행 상태를 유지하는 것과 빠른 응답성은 서로 상보(trade-off) 관계에 있는데, 지속적으로 메모리 자원을 소비해야 실행 상태를 유지할 수 있지만, 그에 따라 소비되어야 할 메모리는 유한하기 때문이다. 그리하여 모바일 운영체제는 대부분 현재의 실행 상태를 가급적 최소한의 메모리를 소모하면서 저장해두고, 앱이 다시 실행될 때에 실행 상태를 다시 가져와 복원하는 형태의 작업 전환 방식을 사용하고 있다.

만약 WP7 폰에서 윈도 운영체제처럼 작업 표시줄을 두고 여러 앱을 오가도록 설계한다면 어떨까? 마이크로소프트가 Windows Mobile 시대로 돌아가서 자사의 모바일 사업을 말아먹으려고 결심하지 않는 이상 그런 설계는 말도 안 될 일일 것이다.

WP7에서는 다행히 작업 표시줄을 사용하는 대신, 일종의 스택(Stack)을 구현하여 실행중인 앱을 관리한다. 이러한 스택 방식은 여타 모바일 운영체제의 프로그램 전환 기능과는 약간 다른 점이 있는데, 이 스택에 저장되는 실행 단위는 프로그램 내의 페이지까지도 포함한다. 예를 들어 이런 상황을 생각해보자. 전화 앱으로 A에게 전화를 걸고 나서, A의 주소를 업데이트해야 할 일이 있어서 연락처 앱을 실행한 다음, A의 연락처를 찾고, A의 연락처를 편집했다고 하자. 이럴 경우 여타 스마트폰 환경에서는 ‘전화’ 앱과 ‘연락처’ 앱 사이의 프로그램 전환이 일어나겠지만, WP7의 경우, A의 연락처 편집이 끝난 상태에서 뒤로 가기 버튼을 연속해서 누르면 A의 연락처 편집 화면, 연락처 검색 화면, 전화 화면이 연속적으로 전환될 것이다. 다시 말해, 여타 스마트폰 운영체제에서는 앱 단위의 전환이 일어난다고 하면, WP7 내에서는 작업 단위로 전환이 일어나며, 이 작업 단위가 하나의 페이지이다. 굳이 비슷한 예를 찾자면, 뒤로 가기 버튼을 눌러서 지금까지 탐색한 페이지를 살펴볼 수 있는, 웹 브라우저와 비슷한 개념으로 움직인다고 볼 수 있다. WP7에서는 이러한 스택 방식의 작업 전환 방식을 통해, 뒤로 가기 버튼과 시작 버튼을 사용해서 앱 사이를 전환할 수 있다.

WP7에서는 디바이스의 제한된 리소스를 아껴서 써야 하기 때문에, 스택에 들어간 어플리케이션은 가능한 최소한의 정보만을 유지해야 한다. WP7에서는 뒤로 가기 버튼을 눌러 어플리케이션의 전환이 일어나면, 실행 중이던 프로그램은 잠시 멈추는(Suspend) 것이 아니라 실제로 프로세스가 종료(Terminate)된다. 종료된 프로그램이 스택에서 사라진 다음에 프로그램을 실행하면, 해당 프로그램은 처음부터 다시 실행된다.

WP7의 실버라이트에서는 이렇게 프로그램이 실행/종료되는 과정에서, 프로그램 스스로가 자신이 종료되기 직전의 상태를 저장해 두었다가 다시 복원하는데 필요한 도구(이벤트와 저장소) 등을 제공하고 있다. 또한, 이렇게 프로그램 스스로가 자신의 상태를 저장하는 작업을 툼스토닝(Tombstoning)이라고 부르고 있다. 이러한 프로그램의 시작과 종료에 관련된 이벤트는 하나의 앱 단위에서 처리되며, App 클래스가 이러한 이벤트를 처리하는 역할을 한다.

프로젝트를 하나 생성하고 App.xaml 파일을 살펴보자. ApplicationLifetimeObjects이 정의되어 있는 부분에서 다음과 같은 태그가 정의되어 있는 것을 볼 수 있다.

<Application.ApplicationLifetimeObjects>
    <!--Required object that handles lifetime events for the application-->
    <shell:PhoneApplicationService 
        Launching="Application_Launching" Closing="Application_Closing" 
        Activated="Application_Activated" Deactivated="Application_Deactivated"/>
</Application.ApplicationLifetimeObjects>

PhoneApplicationService 클래스에 정의된 이벤트를 통해 앱의 시작과 종료에 관련된 이벤트가 처리되고 있다. 이 태그는 프로그램이 실행되면서 객체가 되며, PhoneApplicationService의 정적 프로퍼티인 Current를 통해 접근할 수 있다.

Shell 접두어는 App.xaml 파일의 상단을 살펴보면 알 수 있지만, PhoneApplicationService 클래스가 Microsoft.Phone.Shell 네임스페이스에 속해 있음을 나타낸다. 이렇게 App.xaml에 정의되어 있는 이벤트에 대한 핸들러 코드(이벤트를 실제로 처리하는 코드)는 App.xaml.cs에 정의되어 있다. 실제 핸들러 코드는 다음과 같이 기술된다:

 
private void Application_Launching(object sender, LaunchingEventArgs e)
{

}

private void Application_Activated(object sender, ActivatedEventArgs e)
{

}

private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{

}

private void Application_Closing(object sender, ClosingEventArgs e)
{

}

 

위에 나타난 각 이벤트는 다음과 같은 상황에서 발생한다.

 

실행 Launching

시작 화면에서 프로그램을 선택해 실행할 경우

닫힘 Closing

뒤로 가기 버튼을 눌러 프로그램을 닫을 경우

비활성화 Deactivated

시작 버튼을 눌러 실행중이던 프로그램을 종료했을 경우 (이 상태가 툼스토닝된 상태이다)

활성화 Activated

툼스토닝 상태에서 프로그램이 다시 시작될 경우

 

위 내용을 읽고 언뜻 생각해보면, ‘비활성화’라는 단어는 마치 윈도에서 실행한 프로그램을 최소화하여 감추어 둔 것과 비슷한 느낌이 든다. ‘잠시 프로그램을 비활성화해둔 것일 뿐이니까 메모리는 잘 보존되어 있겠지?’라고 생각할 수도 있겠으나, 그렇지 않다. 프로그램이 비활성화 상태로 들어가면 프로그램에서 유지되던 모든 변수 및 데이터는 지워진다. 비활성화 상태와 활성화 상태를 오가는 프로그램의 상태를 저장하려면 State 프로퍼티 컬렉션을 사용하거나 격리된 저장소 등 기타 수단을 사용해 WP 디바이스 내부에 필요한 내용을 저장해야 한다.