Este artigo foi traduzido por máquina.

Aplicativos do Windows Phone 7

Crie aplicativos controlados por dados com o Windows Azure e o Windows Phone 7

Danilo Diaz

Nos últimos 30 anos, temos visto uma explosão na indústria de hardware de computador. De mainframes para computadores de mesa para dispositivos portáteis, o hardware cada vez mais poderoso mesmo quando ele encolhe. Os desenvolvedores têm, em certa medida, tornar-se um pouco estragados por esse constante aumento do poder de computação e agora esperam recursos ilimitados do computador em cada dispositivo para o qual eles escrevem aplicativos. Muitos desenvolvedores mais jovens não têm nenhuma lembrança de um tempo quando o tamanho e a eficiência de seu código foram fatores importantes.

As últimas tendências em desenvolvimento está abraçando o aumento da popularidade dos smartphones. Ao codificar para dispositivos do smartphone, muitos desenvolvedores tem que ajustar para o facto de que, apesar de telefones de hoje são extremamente poderosos em relação aos dispositivos de apenas alguns anos atrás, eles enfrentam limitações. Estas limitações estão relacionadas ao tamanho, a potência do processador, a memória e a conectividade. Você precisa entender como contornar essas limitações ao criar aplicativos móveis para garantir o bom desempenho e a melhor experiência de usuário.

Algumas das razões para menos do que um bom desempenho de aplicativo podem ser atribuídas diretamente para as decisões de design pobre pelo desenvolvedor. No entanto, em outros casos, alguns desses fatores não são diretamente no controle do desenvolvedor. Um aplicativo mal desempenho pode ser um sintoma de uma lenta ou serviço de terceiros off-line, queda de conexão banda larga móvel ou a natureza dos dados que você está trabalhando com (tais como streaming de arquivos de mídia ou grandes conjuntos de dados).

Qualquer que seja a causa pode ser, o desempenho percebido pelo usuário final do aplicativo deve ser uma das principais preocupações de qualquer desenvolvedor de software. Neste artigo, abordaremos algumas considerações de alto nível para a concepção de robustos, orientado a dados aplicativos de Windows 7 de telefone de uma forma que podem fornecer uma experiência de usuário grande e dimensionar graciosamente.

Vamos primeiro levar alguns instantes e configurar um cenário no qual possamos analisar alguns design e opções de codificação. Como exemplo, vamos trabalhar com um aplicativo de informações de viagens fictícia que fornece informações sobre vôos selecionados pelo usuário. Como mostrado em de Figura 1, a tela principal do aplicativo mostra um número de elementos de dados incluindo tempo atual e status dos vôos. Você pode ver que, como aplicativos tornam-se mais expressiva e centradas em dados, desenvolvê-los será um pouco mais difícil. Há simplesmente mais áreas onde seu código pode ser insuficiente.

image: The Flight Information Sample App

Figura 1 de amostra de informação de voo App

Bloqueio do Thread de interface do usuário

Vamos começar examinando o interface do usuário. É fácil interpretem o padrão Projetando o aplicativo como se você está codificando para a área de trabalho, então vamos dar uma olhada em alguns problemas de interface do usuário de telefone específico.

Quando um aplicativo não responde como esperado a comandos do usuário, o efeito sobre a experiência geral do usuário pode ser dramático. Resposta lenta para roubar, toque ou apertar pode ser prejudicial para o apelo global do app. No entanto, estas são questões muito simples para antecipar e resolver, como você verá.

Considere uma caixa de listagem. Quando um ItemTemplate contém imagens ou está carregando dados de um feed, há uma boa chance que o thread de interface do usuário será bloqueado e a interface do usuário fará uma pausa até as solicitações ou cálculos completos. Portanto, como desenvolver a interface do usuário, uma abordagem é para realizar cálculos longos — incluindo WebRequests — fora do segmento da interface do usuário. Na verdade, esta é uma boa abordagem para qualquer aplicativo, móvel ou não.

Outro problema que pode criar problemas de desempenho é quando você estiver vinculando muitos itens para o ItemSource sem limitação de injeção no controle ListBox. Uma abordagem melhor seria vincular uma ObservableCollection e preencher alguns itens na coleção cada ms de 20-30. Isso desbloqueia o segmento interface do usuário para ser responsivo ao usuário.

No caso de nosso aplicativo de exemplo, nós também estamos fazendo uso pesado de imagens na tela. O ListBox deve realmente fazer download da imagem para exibir os dados. Enquanto isso parece OK, fazer este trabalho no thread da UI bloquearia o usuário de qualquer entrada do gesto. Carregamento de imagens em um segmento de plano de fundo resolve uma série de problemas tanto em termos de requisitos de memória e liberando o segmento interface do usuário, enquanto ao mesmo tempo fazendo o pedido mais rápido.

Tudo o que podemos exibir ao usuário deve ser processado. Processamento requer layout, alinhamento e cálculo para exibir corretamente. Como mais camadas são adicionadas à interface do usuário, cálculo e processamento global custa aumento. Embora Silverlight já virtualiza o interface do usuário, ele não virtualiza os dados que está sendo vinculados. Isto significa que se vincular itens de 10000 a nossa caixa de listagem, Silverlight iria instanciar todos os 10000 ListItems antes que eles foram processados.

Lembre-se de que você está a ligação de dados e manter o limite definido tão pequeno quanto possível. Se você precisar lidar com grandes conjuntos de itens de dados-bind, considere a possibilidade de manipulação dinamicamente o processamento nos bastidores. Isso é verdadeiro de aplicativos de desktop, bem como, é claro — o impacto destas opções é amplificado apenas em um telefone.

ValueConverters pode ter um impacto drástico no desempenho de processamento, porque eles são definidos usando código personalizado e processamento não pode ser pré-determinado e armazenado em cache antes do layout e o processamento de elemento real.

Lidando com dados

Em seguida, precisamos de falar sobre o armazenamento de dados no Windows 7 de telefone. Vamos apenas ir direto ao ponto: Não há nenhum mecanismo de banco de dados relacional disponível para os desenvolvedores. SQL Server Compact (SQL CE) é instalado com o sistema operacional Windows 7 de telefone, mas atualmente não há nenhum API disponível para os desenvolvedores. Assim a criação de um banco de dados para armazenar dados de aplicativo — em nosso exemplo, viagem de informações — não está indo para o trabalho.

Dito isto, há uma ampla gama de opções de obtenção de dados para e de nosso aplicativo. Uma abordagem comum é usar um serviço de nuvem, como Windows Azure para persistência de dados. Existem muitas tecnologias disponíveis para a criação da camada de serviço do seu aplicativo, descanso e SOAP que está sendo o mais popular. SOAP é a primeira escolha para muitos desenvolvedores, mas pensamos que resto fornece um método de fazer solicitações de dados mais eficiente e mais simples de implementar.

Empregamos alguns métodos que fornecem dados para o aplicativo e que podemos acessar usando expressões de resto como estas:

/Trip/Create/PHL-BOS-SEA/xxxx/2010-04-10
/Flight/CheckStatus/US743

RESTO permite-nos usar XML ou JSON para um formato de mensagem.

Do ponto de vista da Web front-end, escolhemos o ASP.NET MVC framework (asp. NET/mvc) porque permite-nos processar o pedido e retornar qualquer tipo de marcação usando um modo de exibição personalizado.

Nosso aplicativo de exemplo precisa lidar com informações de viagem e vôo, por isso criamos um FlightController e um TripController que interceptar solicitações para esta informação:

// GET: /Flight/CheckStatus/US743
public ActionResult CheckStatusByFlight(
  string flightNumber) {
  return CheckStatus(flightNumber, DateTime.Now);
}

// GET: /Flight/RegisterInterest/US743/2010-04-12
public ActionResult CheckStatus(
  string flightNumber, DateTime date) {
  Flight f = new Flight(flightNumber, date);
  GetFlightStatus(f);
  return new XmlResultView<Flight>(f);
}

Para fornecer métodos de acesso simplificado e salvar alguns bytes de largura de banda, se a data é hoje pode criar um método de atalho para obter esses dados sem especificar implicitamente hoje.

Dados armazenados em cache e persistentes

O serviço de Estado do voo é um elemento em nosso aplicativo que não está em nosso controle e assim será parte do puzzle de desempenho. Como aplicação bem-sucedida pode receber um número considerável de pedidos, é importante pensar em uma estratégia de cache.

Normalmente, quanto mais próximo o vôo é a partida, quanto maior o número de pedidos de suas informações é previsível. Números mais altos de perto-simultâneo solicitações podem afetar não apenas o desempenho do aplicativo, mas também os custos associados a armazenar e manipular os dados. Como regra geral, aplicativos de Windows Azure acumulam cargas de largura de banda tanto no pedido e retorno e serviços de informação de voo também poderão incorrer em custos de acesso. O volume de dados retornados terá de ser não mais do que o que é necessário para o aplicativo.

A plataforma Windows Azure fornece uma ampla gama de opções de armazenamento de dados — de tabelas, bolhas e filas para armazenamento de banco de dados-como relacional via SQL Azure. Decidimos usar SQL Azure porque ele usa técnicas de programação SQL Server familiares e nos permite facilmente armazenar e acessar dados em cache de voo e as informações de viagem persistente.

Figura 2 mostra a camada de armazenamento simples que temos projetados usando o Entity Framework.

image: Flight Data Storage Schema

Figura 2 de esquema de armazenamento de dados de voo

Retornando dados

Podemos retornar dados para o cliente através de nosso modo de exibição personalizado. Porque estamos usando ASP.NET MVC, cada modo de exibição deve derivar de ActionResult e implementar ExecuteResult.

Como mencionado anteriormente, podemos fornecer representações XML ou JSON de informação de voo através do nosso serviço de descanso. Vamos dar uma olhada na opção XML primeiro. O serializador para produzir XML requer um tipo, então vamos criar uma classe de genéricos como mostrado em de Figura 3.

Figura 3 serialização XML

public class XmlResultView<T> : ActionResult {
  object _model = null;
  public XmlResultView(object model) {
    this._model = model;
  }

  public override void ExecuteResult(ControllerContext context) {
    // Create where to write 
    MemoryStream mem = new MemoryStream();

    // Pack characters as compact as possible, 
    // remove the decl, do not indent.
XmlWriterSettings settings = new XmlWriterSettings() { 
      Encoding = System.Text.Encoding.UTF8, 
      Indent = false, OmitXmlDeclaration = true };
    XmlWriter writer = XmlTextWriter.Create(mem, settings);
    
    // Create a type serializer
    XmlSerializer ser = new XmlSerializer(typeof(T));

    // Write the model to the stream
    ser.Serialize(writer, _model);

    context.HttpContext.Response.OutputStream.Write(
      mem.ToArray(), 0, (int)mem.Length);
  }
}

Estamos tão facilmente poderia trabalhar com JSON para nossos dados. O único elemento de nossa solução que mudaria seria o conteúdo do método ExecuteResult. Usando JsonResult, podemos produzir o retorno JSON de nosso serviço em apenas algumas linhas de código:

// Create the serializer
var result = new JsonResult();
// Enable the requests that originate from an HTTP GET
result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
// Set data to return
result.Data = _model;
// Write the data to the stream
result.ExecuteResult(context);

Que tal salvar dados ao dispositivo real? Não faria sentido para forçar o aplicativo para extrair dados do serviço de cada vez que o usuário precisa acessar as informações de viagem. Embora não haja nenhum armazenamento de dados relacionais em Windows 7 de telefone, os desenvolvedores têm acesso a um recurso chamado de armazenamento isolado. Isso funciona apenas como armazenamento isolado do Silverlight 4, mas sem um limite de tamanho.

Existem dois métodos principais que você precisa para salvar e recuperar dados do telefone: SaveData e GetSavedData. Exemplos mostrando como seria usar estes para o app de informação de voo são mostrados em de Figura 4.

Figura 4 de Salvar e recuperar dados locais

public static IEnumerable<Trips> GetSavedData() {
  IEnumerable<Trips> trips = new List<Trips>();
  try {
    using (var store = 
      IsolatedStorageFile.GetUserStoreForApplication()) {
      string offlineData = 
        Path.Combine("TravelBuddy", "Offline");
      string offlineDataFile = 
        Path.Combine(offlineData, "offline.xml");

      IsolatedStorageFileStream dataFile = null;

      if (store.FileExists(offlineDataFile)) {
        dataFile = 
          store.OpenFile(offlineDataFile, FileMode.Open);
        DataContractSerializer ser = 
          new DataContractSerializer(
          typeof(IEnumerable<Trips>));

        // Deserialize the data and read it 
        trips = 
          (IEnumerable<Trips>)ser.ReadObject(dataFile);
        dataFile.Close();
      }
      else
        MessageBox.Show("No data available");
    }
  }

  catch (IsolatedStorageException) {
    // Fail gracefully
  }

  return trips;
}

public static void SaveOfflineData(IEnumerable<Trips> trip) {
  try {
    using (var store = 
      IsolatedStorageFile.GetUserStoreForApplication()) {

      // Create three directories in the root.
store.CreateDirectory("TravelBuddy");

      // Create three subdirectories under MyApp1.
string offlineData = 
        Path.Combine("TravelBuddy", "Offline");

      if (!store.DirectoryExists(offlineData))
        store.CreateDirectory(offlineData);

      string offlineDataFile = 
        Path.Combine(offlineData, "offline.xml");
      IsolatedStorageFileStream dataFile = 
        dataFile = store.OpenFile(offlineDataFile, 
        FileMode.OpenOrCreate);

      DataContractSerializer ser =
        new DataContractSerializer(typeof(IEnumerable<Trip>));
      ser.WriteObject(dataFile, trip);
                   
      dataFile.Close();
    }
  }

  catch (IsolatedStorageException) {
    // Fail gracefully
  }
}

Lidar com falhas de rede

As redes usadas por dispositivos móveis podem ter conectividade amplamente variável — às vezes, tornando-se totalmente indisponível devido a localização, congestionamento ou até mesmo usuários se desconectar manualmente (em caso de modo avião, por exemplo). Você tem que aceitar isso como um fato da vida. Como os desenvolvedores de aplicativos móveis deve levar isso em consideração ao criar aplicativos.

Outro tipo de falha de rede é falha de camada de serviço. Muitos aplicativos móveis consumam dados de serviços de terceiros. Estes serviços não podem vir com contratos de nível de serviço, que deixa seu aplicativo à mercê do provedor. Em outras palavras, é fora de seu controle, e você tem que estar preparado para lidar com as paralisações.

Independentemente da origem da falha de rede, você ainda precisará fornecer a melhor experiência de usuário possível. Você precisará fornecer algum nível de funcionalidade em caso de qualquer tipo de falha de rede. Para a nossa aplicação de status de vôo, isso significa que nós queremos permitir que o usuário acesse tanta informação quanto possível, mesmo se a conectividade de rede for perdida do servidor ou do lado do cliente.

Existem várias maneiras de conseguir isso. Por agora, nós vamos concentrar-se em três maneiras simples em que você poderia fazer isso: obter os dados enquanto você pode, dados em cache localmente e cache de dados em um servidor que você controla.

Usando notificações de envio

Quando o usuário insere as informações de viagem para o aplicativo, as informações serão enviadas para um serviço de nuvem. O serviço, em seguida, irá manter sondagem os vários serviços que fornecem seus dados de vôo e do tempo. Ele também procura por alterações nos dados ao longo do tempo, como uma mudança de status de vôo ou um aeroporto que relata um atraso.

Quando uma alteração for encontrada, você deseja obter informações para o usuário como pronta e eficiente possível. Uma maneira de fazer isso é para o serviço enviar as informações para o aplicativo cliente. Isso fornecerá ao usuário acessar o conjunto mais recente de dados disponíveis no momento que os dados disponibilizados. Porque os dados foi enviados para o cliente, os dados estão disponíveis mesmo que o usuário perde sua conexão de rede.

Nós pode fazer isso com o nosso serviço de Azure do Windows por meio de notificação de envio do telefone de Windows. O recurso de notificação de envio do telefone de Windows é composto por três componentes: monitorar serviços, o serviço de notificação de envio de Microsoft e uma método de manipulação de mensagens.

Um serviço de monitor é um serviço de nuvem que procura constantemente novas informações para a nossa aplicação. Vamos discutir isso com mais detalhes posteriormente.

O serviço de notificação de envio é parte dos serviços Microsoft hospedado que são usados para retransmitir mensagens para dispositivos Windows 7 de telefone. Este serviço está disponível para todos os desenvolvedores de aplicativo Windows 7 de telefone.

O método de manipulador de mensagem faz o que o nome sugere: Ele simplesmente recebe mensagens do serviço de notificação de envio.

Existem três tipos de notificação padrão no Windows telefone 7: Notificações de azulejo, Push e brinde. As notificações são uma parte importante da experiência do usuário e você precisa considerar cuidadosamente a sua utilização. Notificações repetitivas ou intrusivas podem degradar o desempenho do seu aplicativo e outros em execução no dispositivo. Eles também podem incomodar os usuários. Considere a freqüência na qual as notificações são enviadas e os tipos de eventos que você deseja chamar a atenção dos usuários.

No Windows telefone 7, as notificações são entregues via processamento em lotes, assim que a transação não pode ser instantânea. A atualidade da notificação não é garantida e a decisão sobre como entregar a notificação para o cliente é tratada pelo serviço;o serviço faz o melhor para determinar quão rapidamente ele pode entregar a mensagem para o telefone.

O fluxo de trabalho para notificações de envio é:

  1. Aplicativo cliente solicita uma conexão de canal para o serviço de notificação de envio.
  2. O serviço de notificação de envio responde com o canal URI.
  3. O aplicativo cliente envia uma mensagem para o serviço de monitoramento com o canal de serviço de notificação de envio URI, bem como uma carga.
  4. Quando o serviço de monitoramento detecta uma alteração das informações (voo cancelamentos, atrasos de vôo ou alertas de tempo em nosso aplicativo de exemplo) termina uma mensagem para o serviço de notificação de envio.
  5. O serviço de notificação de envio retransmite a mensagem para o dispositivo de Windows 7 de telefone.
  6. O manipulador de mensagens processa a mensagem no dispositivo.

Cache de dados localmente

Outra maneira de tornar os dados disponíveis para seu aplicativo é armazenar em cache localmente para que haja sempre alguns dados na interface do usuário. Em seguida, você pode usar outros meios em segundo plano para atualizar os dados locais (se possível). A vantagem desse método é que o aplicativo pode carregar e ser utilizável rapidamente mesmo se Atualizando informações tem de ocorrer de forma assíncrona nos bastidores.

Em suma, você usa o armazenamento isolado para salvar o conjunto mais recente de dados. Quando o aplicativo é aberto, ele imediatamente pega todos os dados disponíveis no local de armazenamento isolado e processa-lo. Entretanto, o aplicativo chama o serviço de Azure do Windows para obter informações atualizadas. Se novas informações são encontradas, tem serializado e transferidos para o dispositivo, armazenamento isolado é atualizado, e tornar a interface do usuário novamente com informações atualizadas. Para uma melhor experiência de usuário, você provavelmente deseja indicar na interface de usuário que foi atualizadas as informações de data e hora.

Em uma nota lateral, se o aplicativo está usando o padrão de design Model-View-ViewModel (MVVM), a atualização para o interface do usuário pode acontecer automaticamente através de recursos de ligação de dados do Silverlight. Para obter mais informações sobre MVVM e Silverlight, consulte o artigo de Robert McCarter, "problemas e soluções com Model-View-ViewModel," US msdn.microsoft.com/magazine/ff798279 .

Cache de dados no seu servidor

Não há um meio termo entre empurrando dados diretamente ao seu aplicativo como torna-se disponível e armazenar dados no dispositivo: cache-lo em seu aplicativo de nuvem até que o aplicativo Windows telefone 7 solicita-lo e pegar dados de serviços de terceiros.

Esta técnica requer uma nova camada de abstração em seu aplicativo. Em essência, o objetivo aqui é remover a dependência de um serviço de terceiros do seu aplicativo. O serviço recebe e armazena em cache os dados para as dependências de serviço de terceiros. Se o serviço for desativado, você terá, pelo menos, alguns dados em cache que você pode fornecer para a aplicação em dispositivos.

Um serviço como este poderia facilmente clonado ou estendido para puxar os dados de vários serviços, assim, reduzir a dependência em qualquer um fornecedor ou fonte de dados, o que facilita muito a fornecedores de mudanças.

Para obter mais informações sobre como configurar soluções centradas em dados no Windows Azure, consulte "alimentando o motor do seu aplicativo com o Windows Azure Storage" por Kevin Hoffman e Nathan Dudek ( msdn.microsoft.com/magazine/ee335721 ). Além disso, embora não diretamente focado em cenários de Windows 7 de telefone, artigo de Paul Stubb, "Criar um Silverlight 4 Web Part para SharePoint 2010," é boa leitura em design de ligados a dados para Silverlight e Web services ( msdn.microsoft.com/magazine/ff956224 ).

Serviço de monitoramento

Como mencionado anteriormente, o recurso de notificação é uma parte importante do nosso aplicativo de status de vôo. Esse recurso é realmente composto por vários serviços diferentes dentro do aplicativo. Talvez mais importante para a utilidade do aplicativo, o serviço de monitoramento periodicamente controla os serviços de dados de terceiros e transmite informações como atrasos de vôo, atrasos de aeroporto e alertas de tempo de volta para o dispositivo.

No nosso aplicativo, o serviço de monitoramento lê a lista atual de voos e códigos de aeroporto e usa essas informações para coletar dados relevantes. Essas informações são armazenadas em seguida, voltar no banco de dados SQL Azure como uma entrada de cache para que ele possa ser recuperado pelo serviço /Flight/CheckStatus mostrado anteriormente. Nosso serviço de monitoramento é implementado com um papel de trabalhador de Azure do Windows. O principal objetivo deste papel de trabalhador é extrair informações de status sobre atrasos nos vôos e status de aeroporto para vôo coleção todos os usuários do. A freqüência de puxar atualização aumenta à medida que se aproxima a hora de partida do voo.

Para algumas idéias sobre como você poderia implementar um serviço como esse, não se esqueça de check-out do projeto Azure publicação-assinatura no CodePlex ( azurepubsub.codeplex.com ) ou ler o post do blog de Joseph Fultz, "Migrando o serviço Windows Azure trabalhador papel: Conversão de exemplo usando armazenamento de imagem"( bit.ly/aKY8iv ).

Juntando as peças

Espero que nós te dei uma visão ampla das questões que você precisará considerar ao criar um aplicativo do Windows 7 telefone orientados a dados. Capacidade de resposta da interface do usuário, bem como tempo de acesso às suas fontes de dados, joga em fazer uma ótima experiência do usuário para seu aplicativo.

Para aprofundar um pouco mais, comece com artigo de Joshua Partlow, "Ficando começou com Windows telefone ferramentas de desenvolvimento" ( msdn.microsoft.com/magazine/gg232764 ). Você também pode ver o artigo, "Desenvolvendo e Implantando o Windows Azure Apps no Visual Studio 2010," por Jim Nakashima, Hani Atassi e Danny Thorpe ( msdn.microsoft.com/magazine/ee336122 ).

Para montar seu desenvolvimento Windows Azure e Windows telefone 7, dê uma olhada no artigo de Ramon Arjona, "Windows Phone e a nuvem — uma introdução" ( msdn.microsoft.com/magazine/ff872395 ).

é um divulgador de desenvolvedor para o distrito de Microsoft mid-Atlantic Estado. Nessa função, ele ajuda os desenvolvedores a entender a estratégia e as ofertas de produto Microsoft.

Max Zilberman é um arquiteto evangelista nos distritos de Nova York e mid-Atlantic Estados. Antes de se juntar à Microsoft, Zilberman ocupou vários cargos de técnicos sênior em uma seguradora de saúde de nível superior.

Graças a seguinte especialista técnico para revisão deste artigo: Ramon Arjona