Adam Barrus는 라이브 앱을 위한 앱 수명 주기 관리에서 Windows 8에 새롭게 도입된 앱 수명 주기에 대해 설명했습니다. 가장 많이 받는 질문은 "제 앱이 화면에 떠 있지 않을 때, 파일을 다운로드하거나 이메일을 수신하거나 또는 음악을 재생하는 것과 같은 중요한 작업을 해야 한다면 어쩌죠?"라는 것입니다. 1부와 2부로 구성된 이번 시리즈에서는 앱이 백그라운드에서 실행할 수 있는 여러 종류의 작업과 이러한 시나리오를 지원하는 코드를 소개합니다.

Windows 8 백그라운드 모델

효율적인 배터리 사용은 Windows 8 및 앱 모델을 설계할 때 중요하게 고려된 사항이었습니다. Pat Stemen의 Windows 8 빌드 블로그 관련 은 왜 이러한 부분이 Windows 8 설계에 있어 중요한가를 자세히 소개할 뿐 아니라, 배터리 수명을 향상시키기 위해 우리가 시스템에 도입한 기술에 대해서도 설명합니다. 아시다시피, 장치의 배터리 수명에 가장 큰 영향을 미치는 요인은 장치에서 실행되는 앱입니다. 이러한 점을 염두에 두고 우리는 배터리 수명을 극대화하는 것을 목표로 Windows 8 앱 수명 주기를 설계했습니다. 그렇다고 이것이 앱 모델의 백그라운드 작업을 방해한다는 의미는 아닙니다. 이번 글에서는 Windows 8에서의 백그라운드 시나리오에 대해 설명합니다. 보다 자세한 정보는 Windows 8 빌드 블로그 관련 Ben Srour와 Sharif Farag의 글, 응용 프로그램을 위한 전력 효율성 향상을 참고하세요.

Windows 8의 백그라운드 모델을 설계할 때 앱이 백그라운드에서 수행하는 작업 가운데 사용자가 원하는 일반적인 시나리오를 구분하였으며, 전원 효율성을 높이기 위해 API를 추가하였습니다. 다음은 전원 효율 개선과 관련된 글에서 설명한 바 있는 Windows 8 지원 시나리오입니다.

시나리오

설명

백그라운드 다운로드 또는 업로드

앱은 백그라운드 전송 API를 사용하여 데이터를 백그라운드에서 업로드 및 다운로드할 수 있습니다. 여기서 OS에서 자체적으로 업로드 또는 다운로드를 수행하며, 사진으로부터 앱 코드를 추출하여 배터리 수명을 극대화할 수 있도록 합니다.

백그라운드 오디오

당연히 백그라운드에서의 음악 청취가 가능해야 합니다. 어떤 종류의 미디어나 커뮤니케이션 앱이라도 백그라운드에서 오디오를 재생할 수 있습니다. 시스템 및 전원 효율을 극대화하기 위해 사용자가 오디오를 일시 중지했을 때는 앱도 일시 중지됩니다.

공유

앱이 공유 참(Share Charm)을 사용하여 클라우드 서비스로 콘텐츠를 전송할 때 이 작업은 백그라운드에서 완료됩니다. 공유 작업 중 데이터 전송에 대한 자세한 정보는 개발자 센터에서 확인 가능합니다.

장치 동기화

화면에 앱이 보이지 않아도 카메라와 같은 연결된 장치와 PC 간에 콘텐츠를 동기화할 수 있습니다.

라이브 타일

일시 중지 상태에서도 앱이 Windows 8 PC에 푸시 알림을 전송하여 앱의 라이브 타일에 최신 콘텐츠를 표시할 수 있습니다. 더 자세한 정보는 뛰어난 라이브 타일 환경 만들기를 참고하세요.

알림 스케줄링

타일(일정 약속 등)을 업데이트하거나 알림 창을 띄우는 방식으로 앱이 특정한 시간에 일정을 알릴 수 있습니다. 앱에서 이러한 일정을 스케줄링하지만 알림을 제공하는 작업은 Windows의 몫이며, 배터리 영향을 최소화하는데 도움이 됩니다. 자세한 정보는 개발자 센터에서 확인하세요.

백그라운드 작업

일시 정지된 앱이 기능상 자체 코드를 실행해야만 하는 경우 Windows 8은 사용자에게 백그라운드 작업을 생성하는 기능을 제공합니다. 이 백그라운드 작업은 시간이나 시스템 이벤트 또는 수신되는 푸시 알림과 같은 외부 트리거에 반응하여 작동하게 되며, 전원 최적화 방식으로 백그라운드 작업을 수행할 수 있도록 리소스를 자체적으로 제한합니다. 이를 활용하는 앱의 가장 일반적인 예는 이메일과 VoIP, IM 앱입니다. 이들 앱은 배터리 사용 중 백그라운드에서 또는 대기 모드에 연결된 상태에서 사용자의 데이터를 동기화할 수 있습니다. 자세한 내용은 2부에서 설명할 예정입니다.

이제 Metro 스타일 앱에서 몇 가지 일반적인 시나리오를 어떻게 실행하는지 알아보겠습니다. 아울러 이러한 기능을 기술적인 측면에서 자세히 알아보고 그 장점을 설명하겠습니다.

이 시리즈에서 다룰 시나리오는 다음과 같습니다. 처음 두 가지 항목은 이 글에서 다루고, 나머지 두 가지 시나리오는 2부에서 살펴볼 예정입니다.

  • 백그라운드 다운로드 또는 업로드
  • 백그라운드 오디오
  • 백그라운드 작업 - 장치가 AC 전원에 연결된 상태에서의 작업
  • 백그라운드 작업 - POP3 메일 서버로부터 매 15분마다 다운로드

이제 화제를 코드로 옮겨 Windows 8에서 코드를 실행하는 것이 얼마나 간단한지 알아보겠습니다. 여기서 제시하는 샘플 코드는 모든 면에서 완전한 코드가 아니라 단지 예를 들기 위한 것입니다. 이를테면, 오류 수정 등은 고려하지 않았습니다.

백그라운드 다운로드 또는 업로드

사진 업로드, 동영상이나 음악 다운로드 등의 콘텐츠 전송은 여러 다양한 앱에서 이루어지는 일반적인 시나리오입니다. 백그라운드 전송 네임스페이스는 사용자가 포그라운드 및 백그라운드 모두에서 데이터 전송에 사용할 수 있는 간단하고도 강력한 API를 제공합니다. API는 사용자가 앱의 핵심적인 역할에 집중할 수 있도록 사용자 대신 많은 일들을 수행합니다. 따라서 전원 효율을 극대화하고, 네트워크 결함에 유연하게 대응하며, 네트워크 비용을 절감합니다. 이제 구체적인 예를 통해 BackgroundTransfer를 사용하여 파일 다운로드하는 방법을 살펴보도록 하지요.

BackgroundDownloader는 대부분의 다운로드 또는 업로드 시나리오를 수행하도록 하는 주요 클래스입니다. 아래의 예는 소스 URI와 대상 파일을 가져오는 BackgroundDownloader 클래스를 사용하여 새로운 DownloadOperation 객체를 생성하는 과정을 보여 줍니다. 다운로드 설정에 의해 HandleDownloadAsync가 다운로드를 시작하기 위해 호출됩니다. 다음 JavaScript의 경우에는 다른 기능의 호출 없이 즉시 다운로드를 시작할 수 있습니다.

JavaScript

function downloadFile(uri, destinationFile) 
{
// Create a new download operation.
download = downloader.createDownload(uri, newFile);
// Start the download and persist the promise to be able to cancel the download.
promise = download.startAsync().then(complete, error, progress);
}
                

C#

private async void DownloadFile(Uri source, StorageFile destinationFile)
{
BackgroundDownloader downloader = new BackgroundDownloader();
DownloadOperation download = downloader.CreateDownload(source, destinationFile);

// Attach progress and completion handlers.
await HandleDownloadAsync(download, true);
}
             

이 코드 샘플은 실제로 다운로드를 시작하기 위해 StartAsync를 호출하기 전에 새로운 DownloadOperation에 처리기를 연결하는 과정을 보여 줍니다. 아래에 소개한 것과 같이 다운로드 작업을 열거할 때 AttachAsync를 호출하면 처리기를 다시 연결하는 경우에도 이와 동일한 방법이 사용됩니다.

C#

private async Task HandleDownloadAsync(DownloadOperation download, bool start)
{
// Create progress callback
Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
// Create cancellation token
CancellationTokenSource cts = new CancellationTokenSource();

if (start)
{
// Start the download and attach a progress handler.
await download.StartAsync().AsTask(cts.Token, progressCallback);
}
else
{
// The download was scheduled in a previous session, re-attach the progress handler.
await download.AttachAsync().AsTask(cts.Token, progressCallback);
}
}


앱이 백그라운드 다운로드 작업을 시작한 뒤에는 설사 중지되더라도 다운로드 작업은 백그라운드에서 계속 실행됩니다. 이후 앱이 다시 시작되면 사용자는 다운로드 작업에 대한 진행 및 완료 상황을 통보받게 됩니다. 앱이 일시 중지 후 종료된 경우 이전 백그라운드 다운로드 작업의 완료분 이후부터 다운로드 작업이 다시 시작됩니다. 다음 코드 샘플은 C# 및 JavaScript에서 다운로드 작업이 어떻게 열거되는지를 보여 줍니다.

C#

// Enumerate downloads that were running in the background before the app was closed.
private async Task DiscoverActiveDownloadsAsync()
{
activeDownloads = new List<DownloadOperation>();

// Get all current download operations
IReadOnlyList<DownloadOperation> downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();

if (downloads.Count > 0)
{
List<Task> tasks = new List<Task>();
foreach (DownloadOperation download in downloads)
{
// Attach progress and completion handlers.
tasks.Add(HandleDownloadAsync(download, false));
}

await Task.WhenAll(tasks);
}
}
               
JavaScript
function discoverActiveDownloads() 
{
// Enumerate outstanding downloads.
Windows.Networking.BackgroundTransfer.BackgroundDownloader.getCurrentDownloadsAsync().done
(function (downloads) {
// If downloads from previous app state exist, reassign callbacks and persist to global array.
for (var i = 0; i < downloads.size; i++) {
download[i].attachAsync().then(complete, error, progress);
}
}
}

2부에서 소개할 다른 백그라운드 작업처럼 다운로드 및 업로드 작업도 동일한 리소스 제한을 받게 됩니다. BackgroundTransfer에 대한 자세한 내용은 백그라운드에서 전송 데이터 개요, API 네임스페이스, 백그라운드 전송 다운로드, 샘플을 참고하거나, //BUILD HTTP 서비스와 연결된 소셜 앱 제작 세션을 확인하세요.

백그라운드 오디오

Windows 8에서는 간단하면서 효과적으로 오디오를 재생하는 앱을 개발하는 것이 훨씬 수월해졌습니다. Windows 8은 스트림 범주 분류를 이용해 MediaControl 클래스에서 사용자 경험을 개선하고자 제작된 시스템 레벨 컨트롤과 미디어 전송 레벨을 제공합니다. 이제 백그라운드에서 오디오를 재생하는 앱을 만드는 방법에 대해 살펴보겠습니다. 오디오를 실제로 재생하는 방법이나 미디어 컨트롤 클래스에 대해서는 자세히 다루지 않겠습니다. 오디오 기술에 대한 자세한 내용은 Metro 스타일 앱에서 오디오 재생 백서를 참고하세요.

백그라운드에서 오디오를 재생하려면 앱은 다음의 세 가지 주요 요건을 충족시켜야 합니다.

  • 백그라운드 오디오 선언은 앱 매니페스트에 있어야 합니다.
  • Communications나 BackgroundCapableMedia 중 한곳에 스트림 범주(msAudioCategory)를 설정해야 합니다.
  • 미디어 전송 컨트롤을 위해 앱을 등록해야 합니다.

앱에 백그라운드 오디오 선언을 추가하려면 Visual Studio에서 간단히 앱의 매니페스트를 열기만 하면 됩니다. [선언] 탭에서 선언 드롭다운 메뉴의 [백그라운드 작업]을 선택하고 여기에 매니페스트를 추가합니다. 지원 작업 형식에서 [오디오]를 선택하고 JavaScrip 앱의 시작 페이지를 지정하거나 앱이 C# 혹은 C++ 또는 VB인 경우 시작점을 지정합니다.

Visual Studio의 매니페스트 선언

앱에서 오디오를 재생하는 가장 손쉬운 방법은 HTML5 <오디오> 요소를 사용하는 것입니다. <오디오> 요소에서 msAudioCategory 특성을 추가하여 시스템이 최적화된 성능을 제공하고 앱 오디오에 대한 사용자 경험을 개선하도록 합니다. 예를 들어, 가능한 한 저전력 재생 메커니즘을 이용하거나, 해당 앱이 백그라운드에서 실행되는 동안에도 특정 소리가 재생되도록 할 수도 있으며, 경우에 따라서 다른 소리가 선명하게 들리도록 특정 소리의 볼륨을 낮추거나 음소거를 할 수 있습니다.

다음은 오디오 범주를 적절하게 설정하여 오디오가 재생되도록 한 HTML 코드 샘플입니다.

<audio msAudioCategory="BackgroundCapableMedia" controls="controls"> 
<source src="song.mp3"/>
</audio>

다음은 동일한 기능이 수행되도록 한 JavaScript입니다. 소스 요소를 설정하기 전에는 msAudioCategory 특성을 설정해야 합니다. 그렇지 않으면 시스템이 오디오 범주를 찾을 수 없게 됩니다.

JavaScript
function PlayAudio () 
{
// Create new audio tag for "BackgroundCapableMedia" class
if(!audtag)
{
audtag = document.createElement('audio');
audtag.setAttribute("id", "audtag");
audtag.setAttribute("controls", "true");
audtag.setAttribute("msAudioCategory", "backgroundcapablemedia");
audtag.setAttribute("src", "song.mp3");
document.getElementById("scenario1Output").appendChild(audtag);
audtag.load();
}
}
        

다음은 출력 오디오 스트림에서 오디오 카테고리를 설정한 C# 코드 샘플입니다. FileOpenPicker를 사용해 파일을 선택하려면 SelectFile 기능을 사용하고, SetAudioCategory를 불러와 선택된 스트림에 AudioCategory를 설정합니다.

C#
public async void SelectFile()
{
// Choose file using the picker
Windows.Storage.Pickers.FileOpenPicker picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.MusicLibrary;

// Add a filter so only mp3 files are displayed
picker.FileTypeFilter.Add(".mp3");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
OutputMedia.AutoPlay = false;

// Run on the UI thread because it updates UI controls
await cw.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
OutputMedia.SetSource(stream, file.ContentType);
});
}
}

// Set the audio category on the output stream
public void SetAudioCategory(AudioCategory category)
{
OutputMedia.AudioCategory = category;
}
      

앱이 백그라운드에서 오디오를 재생할 수 있게 하는 두 가지 오디오 범주에는 BackgroundCapableMedia와 Communications가 있습니다. 재생되는 오디오 스트림 형식에 따라 시스템이 오디오 스트림에 대해 최적의 실행 특성을 선택할 수 있도록 적절한 오디오 범주를 선택합니다.

오디오 스트림 형식

설명

BackgroundCapableMedia

백그라운드에서 계속 재생해야 하는 오디오의 예는 다음과 같습니다.

· 로컬 미디어 재생:

· 로컬 재생 목록

· 스트리밍 라디오

· 스트리밍 재생 목록

· 뮤직 비디오

· 스트리밍 오디오/라디오, YouTube, Netflix 등

Communications

오디오 스트리밍 커뮤니케이션 오디오의 예는 다음과 같습니다.

· VoIP(Voice over IP)

· 실시간 채팅 또는 기타 통화 유형

Windows 8 Metro 스타일 앱은 전체 화면에 표시되기 때문에, 앱 사용자가 백그라운드에서 음악을 들을 때 전송 컨트롤에 등록하지 않아도 음악이 중단되지 않습니다. 앱을 시스템 전송 컨트롤에 등록한 후 사용자가 하드웨어 볼륨 단추 중 하나를 누르면 시스템 전송 컨트롤이 화면에 나타납니다. 앱 미디어 전송 컨트롤을 Metro 스타일 앱에 추가하는 자세한 방법은 시스템 전송 컨트롤 개발자 지침을 참고하세요.

지금까지 다양한 내용을 살펴보았습니다. 이제 여러분의 앱은 백그라운드에서 오디오를 중단 없이 재생할 수 있습니다. 단, 백그라운드에서 오디오를 재생하면 앱이 활성화 상태가 되기 때문에 시스템 성능이나 배터리 수명이 저하되지 않는지 확인해야 합니다. 앱에서 오디오의 재생이 멈추면 곧바로 Windows가 중단됩니다. 자세한 내용은 Metro 스타일 앱에서의 오디오 재생 백서를 참고하세요.

요약

이로써, 백그라운드에서 앱의 효율성을 높이는 방법에 대한 1부가 끝났습니다. 1부에서는 백그라운드에서 오디오를 재생하는 방법과 앱이 중단된 상태에서 백그라운드 업로드나 다운로드를 수행하는 방법에 대해 알아보았습니다. 2부에서는 백그라운드 작업을 이용해 앱이 중단된 상태에서 백그라운드에 기능을 제공하는 코드 작성법을 배워보겠습니다.

- Windows 프로그램 관리자, Hari Pulapaka

리소스

링크

유형

주요 내용

백그라운드에서 데이터 전송

빠른 시작

백그라운드 전송에 대한 도움말

API 네임스페이스

API 문서

백그라운드 전송 API 네임스페이스

백그라운드 전송 다운로드 샘플

프로젝트 샘플

백그라운드 전송 API 사용을 보여 주는 앱 샘플

HTTP 서비스와 연결된 소셜 앱 제작

//BUILD 세션

연결된 앱 제작을 소개하는 //BUILD 세션

Metro 스타일 앱에서의 오디오 재생

백서

백그라운드에서의 오디오 재생 방법에 대한 백서

시스템 전송 컨트롤 개발자 지침

백서

뮤직 앱 개발을 위한 미디어 전송 컨트롤 사용 백서

API 네임스페이스

API 문서

기본 미디어 지원 API