[출처] http://msdn.microsoft.com/ko-kr/library/windows/apps/dn263169.aspx

C++ Windows 스토어 앱의 수명 주기 및 상태 관리(자습서 2/4)


C++ 자습서 시리즈의 이 부분에서는 수명 주기 이벤트에 반응하고 사용자 및 세션 데이터를 저장하도록 "Hello, world" 앱을 업데이트합니다.

Windows 8.1에서는 시스템의 속도 저하 또는 배터리 소모에 대해 걱정하지 않고 여러 앱을 시작하고 그 사이를 전환할 수 있습니다. 이는 시스템이 백그라운드에서 실행되는 앱을 자동으로 일시 중단하고 경우에 따라서는 닫기 때문입니다. 잘 설계된 앱은 시스템에서 일시 중단하고 닫고 다시 시작하는 중에도 전체 시간 동안 계속 실행되었던 것처럼 보입니다.

시작하기 전에...

  • 이 자습서는 시리즈 중 두 번째 자습서입니다. 이 자습서를 시작하기 전에 Hello World(C++)를 읽어보세요.
  • 이 자습서의 전체 코드는 코드 갤러리의 Hello World(C++) 샘플에서 확인할 수 있습니다.

앱의 수명 주기 정보

코드로 돌아가기 전에 먼저 앱의 수명 주기에 대해 잠깐 소개하겠습니다. 특정 시점에 앱은 실행 중이 아니거나, 실행 중이거나, 일시 중단 상태입니다. 활성화는 실행하지 않는 상태에서 실행 상태로의 전환에 사용되는 용어입니다. 활성화는 앱 수명 주기의 시작을 표시합니다.

y01.IC627028.png


앱이 실행 중일 때 사용자가 잠깐 조작을 멈추거나 Windows가 전원 부족 상태가 되면 앱이 일시 중단될 수 있습니다. 앱은 사용자가 일시 중단된 앱 사이를 신속하고 안정적으로 전환하여 다시 시작할 수 있도록 일시 중단 상태에서도 메모리에 계속 상주합니다. 앱이 일시 중단된 다음 다시 시작될 때 전체 시간 동안 실행하고 있었던 것처럼 보이도록 하기 위해 추가 코드를 작성할 필요가 없습니다.

그러나 Windows에서는 다른 앱을 위한 메모리를 확보하거나 전원을 절약하기 위해 언제든지 일시 중단된 앱을 닫을 수도 있습니다. 앱을 닫으면 메모리에서 언로드됩니다. 사용자가 앱을 다시 시작하면 시스템에서 앱을 활성화해야 합니다. 즉, 앱 데이터와 사용자 데이터를 다시 로드해야 합니다.

사용자가 Alt+F4를 누르거나 닫기 제스처를 사용하여 앱을 닫으면 앱은 10초간 일시 중단되었다가 닫힙니다.

Windows에서는 앱을 일시 중단시킬 때 해당 내용을 앱에 알리지만 앱을 닫을 때는 추가 알림을 제공하지 않습니다. 따라서 앱은 일시 중단 이벤트를 처리하고 이를 사용하여 상태를 저장하고 독점적인 리소스 및 파일 핸들을 즉시 해제해야 합니다.

좋은 사용자 환경을 만들기 위해서는 앱이 실행을 중단하지 않은 것처럼 보이도록 해야 합니다. 또한 앱은 사용자가 입력한 데이터, 사용자가 변경한 설정 등을 유지해야 합니다. 이는 Windows에서 앱을 닫을 경우 나중에 원래의 상태를 복원할 수 있도록 앱이 일시 중단되었을 때의 상태를 저장해야 한다는 의미입니다.

앱에서 관리해야 하는 데이터 유형에는 앱 데이터세션 데이터의 두 가지가 있습니다.

다음 단계에서는 이러한 유형의 데이터를 저장하도록 앱을 업데이트하는 방법을 보여 줍니다. 어떤 상태를 저장해야 할까요? 지금은 사용자가 자신의 이름 항목만 변경할 수 있습니다. 또한 사용자는 Say "Hello" 단추를 선택하여 개인 설정 인사말을 생성할 수 있습니다.

1단계: SuspensionManager 사용

Hello World(C++)에서는 기본 MainPage 파일을 기본 페이지 템플릿을 기반으로 한 파일로 바꿨습니다. 기본 페이지 템플릿을 사용했을 때 Visual Studio에서 \Common\ 폴더의 해당 프로젝트에 여러 파일을 추가했습니다. 이러한 파일 중 하나에는 앱의 수명 주기 관리를 간소화하는 도우미 클래스인 SuspensionManager 클래스가 포함되어 있습니다. 이 클래스는 여러 가지 작업을 수행합니다. 앱 페이지를 호스트하는 Frame의 탐색 상태를 저장 및 복원합니다. 이 한 페이지 앱에서는 탐색 상태를 저장하는 것이 별로 중요해 보이지 않지만 앱에 여러 페이지를 추가하게 되면 매우 중요해집니다. 또한 이 클래스는 각 페이지에 해당 상태를 저장 및 복원할 수 있는 기회를 제공합니다. SuspensionManager는 페이지 상태 데이터를 직렬화하고 앱의 로컬 저장소에 XML 파일로 저장합니다.

앱에서 SuspensionManager 클래스를 사용하려면 먼저 메인 앱 Frame을 등록해야 합니다. 등록을 마치면 SuspensionManager는 앱의 각 페이지에 대해 알고 있으며, 탐색 상태를 저장 및 복원할 수 있습니다. App.xaml.cpp의 OnLaunched 메서드에서 Frame을 생성하고 바로 등록합니다.

Dn263169.wedge(ko-kr,WIN.10).gifSuspensionManager를 사용하려면 다음과 같이 하세요.

  1. 솔루션 탐색기에서 App.xaml.cpp를 엽니다.
  2. 다음 #include 지시문을 추가합니다.
    #include "Common\SuspensionManager.h"
    
    
  3. OnLaunched 메서드에서 SuspensionManager::RegisterFrame 정적 메서드를 호출하여 루트 Frame을 등록합니다. rootFrame = ref new Frame(); 문 바로 뒤에 다음 문을 배치합니다.
    HelloWorld::Common::SuspensionManager::RegisterFrame(rootFrame, "appFrame");
    
    

2단계: 앱 상태 저장

일반적으로 개발자가 앱에서 관리해야 하는 데이터 유형에는 앱 데이터세션 데이터의 두 가지가 있습니다. 앱 데이터는 전체 세션에서 유지되며 사용자가 항상 액세스할 수 있어야 합니다. 이 앱에서는 nameInputTextBoxText가 앱 데이터입니다. 항상 앱의 전체 수명 주기 동안 증분식으로 중요한 앱 데이터를 저장해야 합니다. 앱에서 일시 중단 이벤트 처리기의 코드를 실행할 수 있는 시간은 최대 5초에 불과하므로 앱이 일시 중단되기 전에 중요한 앱 데이터가 영구적 저장소에 저장되도록 해야 합니다.

Windows에서는 앱 데이터 관리에 도움이 되는 Windows.Storage.ApplicationData 개체를 제공합니다. 이 개체에는 ApplicationDataContainer를 반환하는 RoamingSettings 속성이 있습니다. 개발자는 이 ApplicationDataContainer를 사용하여 전체 세션에서 유지되는 앱 데이터를 저장할 수 있습니다. 사용자가 자신의 이름을 입력할 때 로밍 ApplicationDataContainer에 사용자 이름을 저장해 보겠습니다.

참고  이 자습서에서는 RoamingSettings의 사용 방법을 보여 줍니다. 로밍 설정 앱 데이터 컨테이너를 사용하면 여러 컴퓨터에서 사용자가 액세스할 수 있도록 데이터를 손쉽게 저장할 수 있습니다. 기본적으로 데이터는 백그라운드에서 클라우드에 업로드됩니다. 로컬 설정 앱 데이터 컨테이너(LocalSettings)를 사용할 수 있지만 컴퓨터별 정보를 저장하려는 경우에만 사용해야 합니다.

앱에 적합한 수준에서 자주 영구 앱 데이터를 저장합니다. 여기에서는 사용자가 사용자 이름을 입력하면 TextBox::TextChanged 이벤트를 처리하고 사용자 이름을 저장합니다.

Dn263169.wedge(ko-kr,WIN.10).gif앱 데이터를 저장하려면

  1. 솔루션 탐색기에서 MainPage.xaml를 엽니다.
  2. XAML 또는 디자인 보기에서 MainPage.xaml에 추가한 nameInput TextBox을 선택합니다.
  3. 속성 창에서 이벤트 단추(이벤트 단추)를 선택합니다.
  4. 이벤트 목록에서 TextChanged 이벤트를 찾습니다. 해당 이벤트의 텍스트 상자에 TextChanged 이벤트를 처리하는 함수의 이름을 "NameInput_TextChanged"로 입력합니다.
  5. Enter 키를 누릅니다. 이벤트 처리기 메서드가 MainPage.xaml.cpp에서 만들어지고 이벤트 발생 시 실행될 다음 코드를 추가할 수 있도록 코드 편집기에서 열립니다. 이벤트 처리기에서 nameInput 텍스트를 roamingSettings에 저장합니다.
     auto roamingSettings =
            Windows::Storage::ApplicationData::Current->RoamingSettings;
        roamingSettings->Values->Insert("userName", nameInput->Text);
        if (roamingSettings->Values->HasKey("userName"))
        {
            nameInput->Text = roamingSettings->Values->Lookup("userName")->ToString();
        }
    
    
  6. F5 키를 눌러 앱을 빌드 및 실행합니다. 텍스트 상자에 이름을 입력하면 해당 이름이 저장됩니다.

세션 데이터는 앱에서 사용자의 현재 세션과 관련된 임시 데이터입니다. 사용자가 앱을 닫거나, 컴퓨터를 다시 부팅하거나, 컴퓨터를 로그오프하면 세션이 종료됩니다. 이 앱에서는 greetingOutputTextBlockText가 세션 데이터입니다. Windows에서 앱을 일시 중단하고 닫는 경우에만 이 데이터를 복원합니다. 앱이 이전에 있었던 페이지와 동일한 페이지로 복원되고 SuspensionManager에서 복원되는 페이지의 상태를 알 수 있도록 앱 Frame의 탐색 상태를 저장해야 합니다. 또한 페이지 자체의 상태도 저장해야 합니다. 이제 greetingOutput 텍스트를 저장합니다. SuspensionManager 클래스를 사용하여 Application.Suspending 이벤트 처리기에 세션 상태를 저장합니다.

상태를 저장할 수 있는 다른 방법에 대한 자세한 내용은 앱 데이터 관리상태를 효율적으로 사용을 참조하세요.

App.xaml.cpp 파일에는 Application.Suspending 이벤트의 처리기가 포함되어 있습니다. 이 이벤트 처리기는 Windows에서 앱을 일시 중단하려고 할 때 호출됩니다. 앱이 닫히는 경우 이 처리기가 앱의 상태를 저장할 수 있습니다. 여기에서는 SuspensionManager 클래스를 사용하여 세션 상태를 저장하는 작업을 단순화합니다. 이 클래스는 앱의 탐색 상태를 저장하고 활성 페이지의 세션 상태를 저장할 수 있는 기회를 제공합니다.

Dn263169.wedge(ko-kr,WIN.10).gif세션 상태를 저장하려면

  1. 솔루션 탐색기에서 App.xaml.cpp를 엽니다.
  2. 파일 맨 위에 다음 지시문을 추가합니다.
    #include <ppltasks.h>
    using namespace concurrency;
    
    
  3. OnSuspending 이벤트 처리기 메서드에 다음 줄을 추가합니다.
     //TODO: Save application state and stop any background activity
     auto deferral = e -> SuspendingOperation->GetDeferral();
     create_task(HelloWorld::Common::SuspensionManager::SaveAsync())
     .then([deferral]() {deferral->Complete(); });
    
    
    

    SaveAsync를 호출하면 Frame의 탐색 상태가 저장되고 Page에서 SaveState 메서드에 해당 콘텐츠를 저장할 수 있게 됩니다.

    경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
    어린이용이며, 설치가 필요없는 브라우저 게임입니다.
    https://s1004games.com

  4. 페이지 상태를 저장하려면 솔루션 탐색기에서 MainPage.xaml.cpp를 열고 SaveState 메서드에 다음 코드를 추가합니다.
    // Insert adds a new key or replaces value if key already exists.
    e->PageState->Insert("greetingOutputText", greetingOutput->Text);
    
    
    

    SuspensionManager 클래스에서 pageState 사전을 직렬화하고 XML 파일에 저장합니다. pageState에 저장된 데이터는 이 세션에 대해서만 저장됩니다. 여기에서 greetingOutput 텍스트를 저장합니다.

  5. 빌드 > 솔루션 빌드를 선택하여 앱이 오류 없이 빌드되는지 확인합니다.

앱이 닫히기 전에 앱의 상태를 저장하려면 이 작업만 수행하면 됩니다. 이제 다음에 사용자가 앱을 시작할 때 앱의 상태를 복원하는 방법에 대해 알아보겠습니다.

3단계: 앱 상태 복원

앞에서 App.xaml.cpp 파일에 앱의 활성화를 처리하는 코드가 포함되어 있음을 확인했습니다. 앱을 활성화하는 방법에는 여러 가지가 있습니다. 여기에서는 Launch 활성화와 OnLaunched 메서드를 살펴보겠습니다.

앱은 실행되고 있지 않다가 사용자가 활성화할 때마다 시작됩니다. 앱이 실행되면 Windows는 시작 화면을 표시합니다.

App.xaml.cpp에서 앱 정품 인증을 처리하는 코드를 살펴보겠습니다. 이 코드는 OnLaunched 메서드를 재정의합니다. 이 메서드의 코드는 활성화가 Launch 활성화인 경우에만 실행됩니다. 다른 종류의 활성화를 처리하도록 다른 메서드를 재정의할 수 있지만 여기에서는 이를 다루지 않습니다. 자세한 내용은 응용 프로그램 수명 주기를 참조하세요.

먼저 코드는 Frame을 선언하고 여기에 현재 창의 콘텐츠를 할당하려고 시도합니다.

auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);

창에 Frame이 이미 있으면 앱이 이미 초기화된 것이므로 Frame 초기화를 건너뜁니다.

앱이 초기화되지 않은 경우 이 코드는 앱 페이지를 호스트할 Frame을 만듭니다. SuspensionManager를 통해 Frame을 등록합니다. 이는 1단계에서 추가한 코드입니다.

다음에는 이 코드에서 이전 실행 상태를 확인하여 앱이 마지막으로 어떻게 닫혔는지를 파악합니다. 이전 실행 상태가 Terminated인 경우, 이는 마지막으로 앱이 실행되었을 때 Windows에서 앱을 일시 중단한 다음 닫았음을 의미합니다. 그러한 경우에는 앱의 상태를 복원해야 합니다.

// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
		  // Create a Frame to act as the navigation context and associate it with
		  // a SuspensionManager key
		  rootFrame = ref new Frame();
	  	HelloWorld::Common::SuspensionManager::RegisterFrame(rootFrame, "appFrame");

	  	if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
		  {
		    	// TODO: Restore the saved session state only when appropriate, scheduling the
		    	// final launch steps after the restore is complete
		    
		  }

		  if (rootFrame->Content == nullptr)
		  {
		    	// When the navigation stack isn't restored navigate to the first page,
		    	// configuring the new page by passing required information as a navigation
		    	// parameter
	    		if (!rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments))
		    	{
			       	throw ref new FailureException("Failed to create initial page");
		    	}
	  	}

		  // Place the frame in the current Window
	  	Window::Current->Content = rootFrame;

	  	// Ensure the current window is active
	  	Window::Current->Activate();
	}


이제 코드는 Frame에 콘텐츠가 있는지 확인합니다. 앱이 실행 중이거나 탐색 상태가 복원된 경우에는 Frame에 이미 콘텐츠가 있습니다. 그렇지 않으면 Frame이 앱의 첫 번째 페이지로 이동합니다. 이 경우에는 MainPage로 이동합니다.

if (rootFrame->Content == nullptr)
{
			 // When the navigation stack isn't restored navigate to the first page,
			 // configuring the new page by passing required information as a navigation
			 // parameter
			 if (!rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments))
			 {
			     throw ref new FailureException("Failed to create initial page");
			 }
}


마지막으로 코드는 창을 활성화합니다.

 // Ensure the current window is active
 Window::Current->Activate();


앱이 시작될 때 발생하는 작업에 대해 알아보았으므로 이제 앱 상태를 복원하는 방법에 대해 알아보겠습니다.

Dn263169.wedge(ko-kr,WIN.10).gif앱의 상태를 복원하려면

  1. 앱이 종료된 경우 SuspensionManager::RestoreAsync 메서드를 호출합니다.

    RestoreAsync를 호출하면 Frame의 탐색 상태가 복원되고 Page에서 해당 콘텐츠를 복원할 수 있게 됩니다.

    if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
    {
    			// TODO: Restore the saved session state only when appropriate, scheduling the
    			// final launch steps after the restore is complete
    			HelloWorld::Common::SuspensionManager::RestoreAsync();
    
    
    
  2. MainPage.xaml.cpp에서 LoadState 메서드에 페이지 상태를 복원하는 코드를 추가합니다.
    1. 먼저 pageState 사전이 있는지, greetingOutputText라는 키가 있는지 여부를 확인합니다. 키가 있으면 이 키를 사용하여 greetingOutput 텍스트를 복원합니다.
      // Restore values stored in session state.
      if( e->PageState != nullptr && e->PageState->HasKey("greetingOutputText"))
      {
          greetingOutput->Text = e->PageState->Lookup("greetingOutputText")->ToString();
      }
      
      
      
    2. 다음으로, 사용자 이름을 로드합니다. 여기에서는 여러 세션에 설쳐 사용자 이름 데이터를 유지하기 위해 RoamingSettings 앱 데이터 컨테이너에 이 데이터를 저장합니다. 이제 사용자 이름이 존재하는지 여부를 확인하고 존재하는 경우 이를 표시해 보겠습니다.
       // Restore values stored in app data.
       auto roamingSettings =
           Windows::Storage::ApplicationData::Current->RoamingSettings;
       if (roamingSettings->Values->HasKey("userName"))
       {
           nameInput->Text = roamingSettings->Values->Lookup("userName")->ToString();
       }
      
      
      

    다음은 LoadState 메서드의 전체 코드입니다.

    /// <summary>
    /// Populates the page with content passed during navigation.  Any saved state is also
    /// provided when recreating a page from a prior session.
    /// </summary>
    /// <param name="navigationParameter">The parameter value passed to
    /// <see cref="Frame::Navigate(Type, Object)"/> when this page was initially requested.
    /// </param>
    /// <param name="pageState">A map of state preserved by this page during an earlier
    /// session.  This will be null the first time a page is visited.</param>
    void MainPage::LoadState(Object^ sender, Common::LoadStateEventArgs^ e)
    { 
        (void) sender;	// Unused parameter
    	   // Restore values stored in session state.
    	   if( e->PageState != nullptr && e->PageState->HasKey("greetingOutputText"))
    	   {
    		    greetingOutput->Text = e->PageState->Lookup("greetingOutputText")->ToString();
    	   }
    
    	   // Restore values stored in app data.
    	   auto roamingSettings =
    		      Windows::Storage::ApplicationData::Current->RoamingSettings;
    	   if (roamingSettings->Values->HasKey("userName"))
    	   {
    	       nameInput->Text = roamingSettings->Values->Lookup("userName")->ToString();
    	   }
    }
    
    

이제 앱을 빌드하고 실행하여 세션 상태가 어떻게 저장 및 복원되는지 확인할 수 있습니다. 지금까지는 디버그 모드에서 앱을 실행하고 디버그 > 디버깅 중지를 선택하여 Visual Studio에서 앱을 테스트했습니다. 그러나 이렇게 하면 앱에서 정상 종료를 수행하여 Suspending 이벤트가 발생하지 않게 됩니다. Microsoft Visual Studio에서 다른 기능을 사용하여 앱 일시 중단, 닫기 및 복원을 시뮬레이트할 수 있습니다.

Dn263169.wedge(ko-kr,WIN.10).gif앱 일시 중단, 닫기 및 복원을 시뮬레이트하려면

  1. F5를 눌러 디버그 모드에서 앱을 실행합니다.
  2. 입력 상자에 이름을 입력하고 "Say "Hello""를 선택합니다. 인사말이 표시됩니다.
  3. Visual Studio의 디버그 위치 도구 모음에서 일시 중단 단추 옆의 드롭다운 메뉴를 엽니다.

    디버그 위치 도구 모음은 디버거가 실행 중인 동안 기본적으로 표시됩니다. 이 도구 모음이 보이지 않는 경우 보기 > 도구 모음 > 디버그 위치를 선택하여 표시합니다.

    y02.IC646700.png


  4. 일시 중단 및 종료를 선택합니다.

    Visual Studio에서 앱의 일시 중단 및 닫기를 시뮬레이트하여 Suspending 이벤트가 발생하고 상태 관리 코드가 실행됩니다.

  5. F5 키를 눌러 앱을 다시 실행합니다. 앱이 이전 상태로 복원됩니다.
  6. 텍스트 상자에 다른 이름을 입력하고 "Say "Hello""를 선택합니다.
  7. Visual Studio에서 디버그 > 디버깅 중지를 선택하여 앱을 닫습니다.
  8. F5 키를 눌러 앱을 다시 실행합니다.

    입력 시 저장되었으므로 마지막으로 입력한 이름이 복원됩니다. Suspending 이벤트가 발생하지 않아 세션 상태가 저장되지 않았으므로 인사말은 복원되지 않습니다.

요약

축하합니다. 두 번째 자습서를 마쳤습니다! Windows 스토어 앱에서 앱 데이터와 세션 상태를 저장하는 방법에 대해 알아보았습니다.

코드 보기

난관에 봉착했나요? 또는 작업의 확인이 필요하세요? 코드 갤러리의 Hello World(C++) 샘플을 참조하세요.

다음 단계

이 자습서 시리즈의 다음 부분에서는 Visual Studio의 디자인 도구를 사용해 좀 더 복잡한 UI를 만드는 방법에 대해 알아봅니다. 탐색, 레이아웃 및 보기(C++)를 참조하세요.






본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수

등록된 글이 없습니다.

대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED