Вы находитесь на странице: 1из 84

EDITORIAL

Ano 3 - 23 Edio - 2009 ISSN 1677918-5 - Impresso no Brasil

Corpo Editorial
Editor Geral

Rodrigo Oliveira Spnola


editorwebmobile@devmedia.com.br
Editor Geral
Adriano Santos
adrianosantos@devmedia.com.br

Atendimento ao Leitor
A DevMedia conta com um departamento exclusivo
para o atendimento ao leitor. Se voc tiver algum problema no recebimento do seu exemplar ou precisar de
algum esclarecimento sobre assinaturas, exemplares
anteriores, endereo de bancas de jornal, entre outros,
entre em contato com:

Sub Editores

Carmelita Mullin - Atendimento ao Leitor


www.devmedia.com.br/central/default.asp
(21) 3382-5038

Capa

Antonio Xavier
webdesigner@devmedia.com.br

Kaline Dolabella
Gerente de Marketing e Atendimento
kalined@terra.com.br
(21) 3382-5038

Na Web

H muito que os Web Services vm sendo utilizados em aplicaes


comerciais para resolver acima de tudo o problema da Babel
dos sistemas, permitindo que vrios sistemas escritos em linguagens
distintas se comuniquem por meio de servios (mtodos) que so
expostos para que outros mdulos ou sistemas possam acess-los. Para isso, a tecnologia XML associada ao protocolo SOAP so os protagonistas deste cenrio. Ela
utilizada como canal comum de comunicao e juntos constituem a arquitetura
SOA (Service Oriented Architecture Arquitetura Orientada Servio).
Provado o sucesso destes no universo das tecnologias do lado do servidor
(como PHP, JSP, JSF, etc), to logo a tecnologia tornou-se disponvel para o mundo
ubquo por meio de implementao do protocolo SOAP para as vrias linguagens de programao mvel.
Neste contexto, a WebMobile destaca nesta edio duas matrias muito interessantes sobre o uso de web services em aplicaes mveis:
Utilizando Web Services no Google Android: Este artigo demonstrar passo a
passo como se acessar um Web Service utilizando a biblioteca KSOAP2 em Android.
Para isso, ser criada uma aplicao que acessa um Web Service pblico disponvel
em www.maniezo.com.br que ser utilizado para consultar o CEP de determinada
localidade e retorna informaes adicionais, mostrando tambm a localizao correspondente deste CEP no mapa usando o Google Android Maps.
Conferindo o tempo com Android: Neste artigo voc vai descobrir como
acessar e utilizar web services com Android. Para isto, ser desenvolvida uma
aplicao de consulta ao tempo.
Esta edio ainda traz muitos outros artigos, passando por assuntos como:
Android, iPhone, desenvolvimento .NET para web e mobile. Desejo uma tima
leitura!
Um abrao e at a prxima!

Publicidade

Guinther Pauli
Luciano Pimenta

www.devmedia.com.br/webmobile/pagina.asp

Reviso

Gregory Monteiro - gregory@clubedelphi.net


Thiago Vincenzo - thiago.v.ciancio@devmedia.com.br

Kaline Dolabella
publicidade@devmedia.com.br

Diagramao

Para fechar parcerias ou aes especficas de marketing com a DevMedia, entre em contato com:

Romulo Araujo - romulo@devmedia.com.br

Distribuio

Fernando Chinaglia Dist. S/A


Rua Teodoro da Silva, 907
Graja - RJ - 206563-900

Rodrigo Oliveira Spnola

Para informaes sobre veiculao de anncio na


revista ou no site entre em contato com:

Kaline Dolabella
publicidade@devmedia.com.br
kalined@terra.com.br

editor@portalwebmobile.com.br

NDICE
NDICE
6 - Depurando JavaScript com NetBeans
Melissa Villela

12 - Ajuste fino da JVM para aplicaes Web


Augusto Marinho

22 - Criando um aplicativo LBS para consulta de pontos tursticos em cidades


Fale com o Editor!
muito importante para a equipe saber o que
voc est achando da revista: que tipo de artigo
voc gostaria de ler, que artigo voc mais gostou

Ricardo Ogliari
entre em contato com os editores, informando o
ttulo e mini-resumo do tema que voc gostaria
de publicar:

e qual artigo voc menos gostou. Fique a vontade

Rodrigo Oliveira Spnola - Editor da Revista

para entrar em contato com os editores e dar a

editorwebmobile@devmedia.com.br

30 - Conferindo o tempo com Android


Cezar Augustus Signori

35 - Utilizando Web Services no Google Android


sua sugesto!
Se voc estiver interessado em publicar um artigo

Ramon Ribeiro Rabello

45 - Introduo ao desenvolvimento de aplicaes para o iPhone com o iPhone SDK

na revista ou no site WebMobile Magazine,

Rogrio Arajo

55 - Crie seu mini YouTube usando WPF


Claudio Silva

66 - Maximize a qualidade do seu cdigo


Thomas Semple

74 - Manipulao de dados atravs do Silverlight com Astoria


Thomas Semple

Feedback
eu

D seu voto sobre este artigo, atravs do link:

d i o

A Web Mobile tem que ser feita aoD seu feedback sobre esta edio!
seu gosto.
Para isso, precisamos saber o que voc, leitor, acha da revista!
A .NET Magazine tem que ser feita ao seu
D seu voto sobre este artigo, atravs do link:
gosto. Para isso, precisamos saber o que
www.devmedia.com.br/webmobile/feedback acha da revista!
voc, leitor,

D
s

D seu feedback sobre esta edio!

sobre e
s

A revista WebMobile parte integrante da assitura WebMobile Plus.


Para mais informaes sobre o pacote WebMobile Plus, acesse:
http://www.devmedia.com.br/webmobile/pagina.asp

Apoio

e
ta

Assinatura

Informativo Web Mobile


Portal Web Mobile
www.devmedia.com.br/webmobile/

Na DevMedia, o leitor de banca tambm ganha!

Brinde na web desta edio


Aulas de Java
Aplicao Completa Utilizando Hibernate - Aula 1 - Primeiros Passos: Nesta aula abordamos o download
do servidor de aplicao e a definio do banco de dados.

Aplicao Completa Utilizando Hibernate - Aula 2 - Definindo as Entidades: Nesta aula abordamos a
criao das entidades referentes s tabelas criadas no banco de dados. Este procedimento um dos mais
importantes para entender como proceder no restante do desenvolvimento. Criamos tambm algumas
propriedades adicionais para resolver possveis problemas de design em uma aplicao normal.

Vdeos

Aplicao Completa Utilizando Hibernate - Aula 3 - Trabalhando com Entidades: Nesta aula
continuamos criando as entidades relacionadas com o banco de dados. Veremos como criar as entidades e
fazer os relacionamentos UM-PARA-MUITOS e MUITOS-PARA-UM.
Aulas de .NET:
Mobilidade com SmartPhone Parte I e II: Veja nesta vdeo aula como criar projetos mobile para
SmartPhone no Visual Studio 2005.

Para visualizar acesse o link:


http://www.devmedia.com.br/articles/listcomp.asp?keyword=wm23&codigobanca=camaleao
Gostou das vdeo aulas? O portal www.devmedia.com.br possui mais de 2 mil vdeo aulas e dezenas de cursos
online sobre desenvolvimento de software! Agora voc pode comprar as vdeo aulas que preferir e fazer sua prpria
combinao de vdeos! Saiba mais em www.devmedia.com.br/creditos

Edies Anteriores da Web Mobile


Voc pode comprar todas as edies anteriores da WebMobile na verso impressa ou verso digital! Veja
abaixo as opes:
Edies anteriores em formato impresso acesse https://seguro.devmedia.com.br/edicoes_anteriores.asp
Edies anteriores em formato online (2 opes):
I) Com a assinatura GOLD, voc tem acesso integral a todas as edies j lanadas da WebMobile Saiba
mais em http://www.devmedia.com.br/assgold/

Feedback
eu

D seu feedback sobre esta edio!


sobre e
s

edio
ta

D
s

II) Com Crditos DevMedia, voc pode comprar uma edio online avulsa ou pode comprar somente os
*artigos* que voc desejar voc pode at mesmo misturar artigos de vrias edies, de forma 100%
online! Para saber mais sobre Crditos DevMedia, acesse www.devmedia.com.br/creditos; Para visitar a
biblioteca digital de artigos da WebMobile, visite http://www.devmedia.com.br/assgold/listmag.asp?site=5

A WebMobile tem que ser feita ao seu gosto. Para isso, precisamos saber o que voc, leitor, acha da revista!
D seu voto sobre esta edio, artigo por artigo, atravs do link:
www.devmedia.com.br/webmobile/feedback
Para votar, voc vai precisar do cdigo de banca desta edio, que : camaleao

Edio 50 - SQL Magazine 5

Depurando JavaScript
com NetBeans
Como utilizar um ambiente de
desenvolvimento web integrando
diversas tecnologias

De que se trata o artigo


Neste artigo vamos entender como o desenvolvimento Web pode ficar mais
simples utilizando um ambiente de desenvolvimento integrado, com destaque na
depurao com JavaScript, utilizando a IDE NetBeans.
Para que serve
O artigo apresenta como possvel depurar JavaScript utilizando o prprio
ambiente de desenvolvimento. Isso auxilia o desenvolvedor na construo de
aplicaes Java Web.
Em que situao o tema til
O artigo til para aqueles que ainda no conhece as facilidades de depurao de cdigo JavaScript no NetBeans. Alm disso, o uso desta caracterstica
traz mais facilidade ao desenvolvimento de aplicaes Java Web.

Melissa Villela
melissa@globalcode.com.br

Experincia em projetos de anlise, arquitetura, diagramao e programao


de sistemas corporativos, com slidos conhecimentos em OO, UML e ferramentas de desenvolvimento, alm dos principais frameworks para desenvolvimento Web, com nfase em JSF. Acumula mais de 2000 horas ministrando treinamento nas carreiras Globalcode, alm de palestras e tutorais nos principais
eventos nacionais. Certificada em: SCJA, SCJP 1.4 e 1.5 e SCWCD 5.

WebMobile Magazine - Depurando JavaScript com NetBeans

os dias de hoje o desenvolvimento de uma aplicao


Web utiliza diversas tecnologias como HTML, JavaScript, Java, CSS, entre outras. Neste artigo vamos
entender como o desenvolvimento Web pode ficar mais simples utilizando um ambiente de desenvolvimento integrado,
com destaque na depurao com JavaScript, utilizando a IDE
NetBeans. Para isso, utilizaremos um exemplo prtico para
ilustrar os conceitos apresentados.
A verso 6.5 do NetBeans suporta depurao de JavaScript
nos browsers FireFox, Internet Explorer, Opera e Safari. Para
assegurar que o processo de depurao apresentado neste
artigo funcione, siga o passo a passo do Quadro de instalao
e configurao do ambiente.

Desenvolvendo a aplicao
Neste artigo, desenvolveremos uma aplicao para cadastrar
clientes. Como regras de negcio: (1) foi estabelecido que o
campo nome obrigatrio; (2) para o campo estado civil, se
selecionado a opo casado, a aplicao deve mostrar dinamicamente um campo para preenchimento do nome do cnjuge,
que tambm ser obrigatrio.

Java W eb

Quadro 1. Instalao e configurao do ambiente


Voc pode usar os links disponveis no quadro links teis para
fazer download dos software que sero utilizados no ambiente de
desenvolvimento:
JDK verso 6u10, embora seja vivel utilizar tambm a verso 5.
NetBeans verso 6.5 perfil Java Web e EE
FireFox verso 3.0.4
Os processos de instalao so feitos seguindo o padro sugerido
pelos prprios software, no h necessidade de nenhuma configurao
adicional:
1 - Faa instalao do JDK;
2 - Faa instalao do NetBeans, selecionando o item para instalao
do Tomcat;
3 - Faa instalao do FireFox.
Agora vamos configurar, no NetBeans, a verso do browser compatvel
para depurao do JavaScript:
1 - Execute o NetBeans;
2 - Selecione no menu Ferramentas o item Opes;
3 - Selecione o item Miscelnia;
4 - Selecione a aba JavaScript;
5 - Nesta aba, selecione os browsers que voc deseja utilizar para
depurar o JavaScript, no esquea de confirmar a verso do browser
que voc utilizar para depurao, conforme a imagem da Figura 1.

Figura 2. Criando um projeto Web com NetBeans

Figura 3. Criando um projeto Web com NetBeans

Figura 1. Configurando o NetBeans

Para o formulrio do cadastro de cliente utilizaremos um


arquivo JSP e para a execuo das regras de negcio utilizaremos JavaScript.
Para criar a aplicao, abra o NetBeans e siga os passos:
1 - Selecione no menu Arquivo o item Novo Projeto;
2 - Clique na opo Categorias Java Web e Projetos Aplicao Web, conforme o modelo da Figura 2;
3 - Clique em Prximo e ser exibida uma tela para configurar
o nome e a localizao do projeto, siga o modelo da Figura 3;
4 - Clique em Prximo e configure os dados do container Java,
para a aplicao que ser desenvolvida utilizaremos o Tomcat
conforme a Figura 4;

Figura 4. Criando um projeto Web com NetBeans

Aps a criao do projeto vamos desenvolver a pgina de


cadastro. Para isto, clique com o boto direito do mouse sobre
o projeto e selecione o item Novo e o subitem JSP (Figura 5),
nomeie seu JSP com o nome cadastroCliente.jsp (Figura 6).
Como nossa aplicao consiste basicamente no formulrio de
cadastro de clientes, vamos configurar para que o JSP criado seja
a pgina principal da nossa aplicao. Para isso expanda o item
Arquivos de configurao do projeto e abra o arquivo web.xml,

Edio 23 - WebMobile Magazine

Listagem 1. Verso 01 do cadastroCliente.jsp

Figura 5. Criando um novo JSP

<%@page contentType=text/html pageEncoding=ISO-8859-1%>


<html>
<head>
<meta http-equiv=Content-Type content=text/html; charset=UTF-8>
<title>Modelo depurao JavaScript</title>
</head>
<body>
<form>
<table border=1>
<thead>
<tr>
<th colspan=2>Cadastro de cliente</th>
</tr>
</thead>
<tbody>
<tr>
<td>Nome</td>
<td><input type=text id=txtNome/></td>
</tr>
<tr>
<td>Estado civil</td>
<td>
<select id=selEstCivil>
<option>Solteiro</option>
<option>Casado</option>
<option>Divorciado</option>
<option>Vivo</option>
<option>Outros</option>
</select>
</td>
</tr>
<tr id=linhaConjuge>
<td><label id=lblConjuge>Nome do conjuge</label></td>
<td><input type=text id=txtConjuge value= /></td>
</tr>
<tr>
<td colspan=2><input type=submit value=Gravar /></td>
</tr>
</tbody>
</table>
</form>
</body>
</html>

Criando um script
Figura 6. Nomeando o JSP

Vamos dar incio criao do script para a regra de negcios


que ser utilizada no cadastro. Para isso, insira logo aps o
elemento <html> o elemento <script>, conforme abaixo:
<html>
<script type=text/javascript> // aqui vai o cdigo JavaScript </
script>
... continua

Figura 7. Colocando a pgina de cadastro como pgina principal da


aplicao

posicione o arquivo no item Pginas (Figura 7) e adicione na linha


de Arquivos de boas-vindas o arquivo cadastroCliente.jsp.
A Listagem 1 mostra a primeira verso do formulrio de
cadastro, neste cdigo importante destacar a utilizao do
atributo id em diversos elementos do documento HTML,
o uso deste atributo facilita a manipulao dos elementos
com JavaScript.

WebMobile Magazine - Depurando JavaScript com NetBeans

Dentro do elemento <script> vamos inserir quatro funes e


uma varivel para processar a regra de negcios, so eles:
Varivel valorEstadoCivil
Funo carregaValorEstadoCivil
Funo escondeConjuge
Funo carregaConjuge
Funo valida
O IDE NetBeans possui um excelente suporte a JavaScript,
inclusive com recurso de auto-complete do cdigo. Ao digitar
as funes que vamos demonstrar nos prximos itens deste artigo, voc poder utilizar este recurso de maneira automtica,
ou simplesmente apertando as teclas ctrl + espao (veja a Figura
8 para entender melhor como funciona o auto-complete).

Funo carregaValorEstadoCivil
Esta funo responsvel por carregar a varivel com o texto
do estado civil selecionado pelo usurio. Ser utilizada por
outras funes que precisam conhecer a opo do estado civil
selecionado pelo usurio.

Java W eb

Figura 8. Recurso de auto-complete para JavaScript

No cdigo da Listagem 2 recuperamos, do documento html,


o ndice do elemento selecionado no combo que contm o id
selEstCivil (linha 3). Conhecendo este ndice vamos atribuir
o texto da opo selecionada na varivel valorEstadoCivil
(declarada na linha 1).
Listagem 2. Funo carregaValorEstadoCivil
1. var valorEstadoCivil = ;
2. function carregaValorEstadoCivil(){
3.
var indEstadoCivil = document.getElementById(selEstCivil).
selectedIndex;
4.
valorEstadoCivil = document.getElementById(selEstCivil).
options[indEstadoCivil].text;
5. }

Funo escondeConjuge
Esta funo ser utilizada em dois momentos, ao carregar o
arquivo e quando o valor selecionado no combo de estado civil
for diferente da opo casado.
Demarcamos no documento html toda a linha da tabela que
contm as clulas com informaes sobre o cnjuge, utilizando o
id linhaConjuge (<tr id=linhaConjuge>). Com esta demarcao
podemos facilmente controlar o desaparecimento da linha na
pgina conforme mostra o trecho de cdigo da Listagem 3.
Listagem 3. Funo escondeConjuge
1. function escondeConjuge(){
2.
var linhaConjuge = document.getElementById(linhaConjuge);
3.
linhaConjuge.style.display = none;
4. }

Na linha 2 estamos recuperando o elemento com o id linhaConjuge e na linha 3 com o uso de CSS estamos dizendo que
o elemento no deve ser exibido.

Funo carregaConjuge
Esta funo responsvel por mostrar o elemento demarcado com o id linhaConjuge quando o usurio selecionar a

opo casado e tambm responsvel por acionar a funo


escondeConjuge quando o usurio selecionar qualquer outra
opo (ver Listagem 4).
Listagem 4. Funo carregaConjuge
function carregaConjuge(){
1.
carregaValorEstadoCivil();
2.
if(valorEstadoCivil == Casado){
3.
var linhaConjuge = document.getElementById(linhaConjuge);
4.
linhaConjuge.style.display = table-row;
5.
}else{
6.
escondeConjuge();
7.
}
8. }

Na linha 2 chamamos a funo carregaValorEstadoCivil


para atualizar o valor da varivel valorEstadoCivil, depois
comparamos o valor da varivel com a String Casado para
saber se o usurio selecionou a opo casado. Se esta opo
foi selecionada, recuperamos a linha da tabela que contm as
clulas com dados do cnjuge, e exibimos estes dados, conforme o cdigo da linha 5. Se o usurio selecionou outra opo,
diferente de casado, chamamos a funo escondeConjuge, j
demonstrada anteriormente.

Funo valida
Por ltimo temos a funo valida, que responsvel por verificar se os campos obrigatrios foram preenchidos antes do envio
dos dados do cadastro para o servidor (ver Listagem 3).
Na linha 3 estamos recuperando o elemento com o id txtNome, caso ele seja nulo ou vazio mostramos na linha 5 uma
mensagem ao usurio dizendo que o campo nome obrigatrio
e na linha 7 estamos saindo da funo, uma vez que os dados
esto invlidos.
Se o campo nome foi preenchido corretamente, a linha 10
atualiza o valor selecionado no combo de estado civil e caso o
combo estiver com a opo casado selecionada, validaremos se
o campo com o nome do cnjuge foi corretamente preenchido.

Edio 23 - WebMobile Magazine

Completando o documento HTML

<body onload=escondeConjuge();>

Agora que criamos as funes de JavaScript, vamos mudar


alguns elementos do html para acrescentar a chamada das
funes.
No elemento <body> vamos acrescentar a chamada funo
escondeConjuge atravs do evento onload. Desta maneira toda
vez que o documento html for chamado os dados do cnjuge
sero omitidos.

No elemento <form>, evento onsubmit, acrescentaremos a


chamada da funo valida, assim os dados sero validados
antes do envio para o servidor.

Listagem 5. Funo valida


1. unction valida(){
f
2.
// campo nome obrigatorio
3.
var campoNome = document.getElementById(txtNome);
4.
if(campoNome.value==null ||campoNome.value.length<=0){
5.
alert(Campo nome obrigatorio);
6.
campoNome.focus();
7.
return false;
8.
}
9.
// campo nome do conjuge obrigatorio
10.
carregaValorEstadoCivil();
11.
if(valorEstadoCivil==Casado){
12.
var campoNomeConjuge = document.
getElementById(txtConjuge);
13.
if(campoNomeConjuge.value==null
||campoNomeConjuge.value.length<=0){
14.
alert(Campo nome do conjuge obrigatorio);
15.
campoNomeConjuge.focus();
16.
return false;
17.
}
18.
}
19.
return true;
20.
}

<form onsubmit=return valida();>

Por ltimo, no elemento <select> que representa o combo


de estado civil, colocaremos no evento onchange a chamada
ao mtodo carregaConjuge, para que todas as vezes que o
usurio mudar a opo do combo os dados do cnjuge possam
ser atualizados.
<select id=selEstCivil onchange=carregaConjuge();>

Pronto, agora que j temos a pgina que contempla todas as


regras de negcios solicitadas pela aplicao, vamos depurar
nossa aplicao. Veja o arquivo cadastroCliente.jsp completo
na Listagem 6.

Depurando o script
Para depurar o arquivo, o NetBeans solicita autorizao para
instalao de um plug-in no browser selecionado ao executar a
opo de debug pela primeira vez (para este artigo usaremos
o Firefox e o plug-in que ser instalado o Firebug).
Para depurar a aplicao, importante selecionarmos um

Listagem 6. Verso final do cadastroCliente.jsp


<%@page contentType=text/html pageEncoding=ISO-8859-1%>
<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN
http://www.w3.org/TR/html4/loose.dtd>
<html>
<script type=text/javascript>
var valorEstadoCivil = ;
function valida(){
// campo nome obrigatorio
var campoNome = document.getElementById(txtNome);
if(campoNome.value==null ||campoNome.value.length<=0){
alert(Campo nome obrigatorio);
campoNome.focus();
return false;
}
// campo nome do conjuge obrigatorio
carregaValorEstadoCivil();
if(valorEstadoCivil==Casado){
var campoNomeConjuge = document.
getElementById(txtConjuge);
if(campoNomeConjuge.value==null
||campoNomeConjuge.value.length<=0){
alert(Campo nome do conjuge obrigatorio);
campoNomeConjuge.focus();
return false;
}
}
return true;
}
function carregaConjuge(){
// valida se o combo de estado civil foi selecionado a
// opcao de casado
carregaValorEstadoCivil();
if(valorEstadoCivil == Casado){
var linhaConjuge = document.getElementById
(linhaConjuge);
linhaConjuge.style.display = table-row;
}else{
escondeConjuge();
}
}
function escondeConjuge(){
var linhaConjuge = document.getElementById(linhaConjuge);
linhaConjuge.style.display = none;
}
function carregaValorEstadoCivil(){
var indEstadoCivil = document.
getElementById(selEstCivil).selectedIndex;
valorEstadoCivil = document.

10

WebMobile Magazine - Depurando JavaScript com NetBeans

getElementById(selEstCivil).options[indEstadoCivil].text;
}
</script>
<head>
<meta http-equiv=Content-Type content=text/html;
charset=UTF-8>
<title>Modelo depurao JavaScript</title>
</head>
<body onload=escondeConjuge();>
<form onsubmit=return valida();>
<table border=1>
<thead>
<tr>
<th colspan=2>Cadastro de cliente</th>
</tr>
</thead>
<tbody>
<tr>
<td>Nome</td>
<td><input type=text id=txtNome/></td>
</tr>
<tr>
<td>Estado civil</td>
<td>
<select id=selEstCivil
onchange=carregaConjuge();>
<option>Solteiro</option>
<option>Casado</option>
<option>Divorciado</option>
<option>Vivo</option>
<option>Outros</option>
</select>
</td>
</tr>
<tr id=linhaConjuge>
<td><label id=lblConjuge>Nome do
conjuge</label></td>
<td><input type=text id=txtConjuge
value= /></td>
</tr>
<tr>
<td colspan=2><input type=submit
value=Gravar /></td>
</tr>
</tbody>
</table>
</form>
</body>
</html>

Java W eb

ponto de parada (breakpoint), para isto basta clicar com o mouse na barra lateral do cdigo e demarcar um ponto de parada.
A linha demarcada ser nosso ponto de parada e ficar com o
fundo rosa para distinguir das demais linhas, veja a Figura 9,
onde selecionei o ponto de parada na linha da funo valida.

do JavaScript e continuar depurando a aplicao do lado do


servidor.

Figura 12. Teclas de atalho para depurar JavaScript

Tambm ser disponibilizado todos os processos tradicionais


de depurao para JavaScript, como watch expression, entre
outros. Na Figura 13 estamos depurando o mtodo valida e
conseguimos verificar o valor digitado pelo usurio usando o
recurso de watch. Para isto basta selecionar o trecho de cdigo
que voc deseja visualizar, clicar com o boto direito sobre a
expresso e selecionar o item Novo observador.

Figura 9. Ponto de parada no JavaScript

Figura 13. Utilizando o recurso watch expression

Agora vamos selecionar o item do menu Depurar e o subitem


Depurar Projeto(javascript), o NetBeans vai exibir uma caixa de
opes, Figura 10, para que voc selecione o que depurar. Selecione o item Java do lado do servidor com JavaScript do lado do
cliente, e tambm selecione qual o browser voc deseja instalar
o depurador, em seguida ser exibido um aviso informando que
ser instalado um plug-in no browser selecionado, Figura 11.

Concluso
Quando vamos construir uma aplicao, normalmente utilizamos mais do que um ambiente de desenvolvimento devido
necessidade de trabalharmos com mais de uma tecnologia.
Os ambientes de desenvolvimento integrados esto cada vez
mais poderosos e completos, e por isso vale a pena expandir
nossos conhecimentos estudando e abrindo espao para outros ambientes que nem sempre so aqueles que utilizamos
no dia a dia.
O NetBeans tem evoludo muito rpido na integrao de
diversas tecnologias, como JavaScript, JRuby, Groovy, entre
outros e pode tornar-se uma boa alternativa para o desenvolvimento da sua aplicao.
Links teis
Link para download do JDK
http://java.sun.com/javase/downloads/index.jsp

Figura 10. Seleo da opo para depurao

Link para download do NetBeans


http://www.netbeans.org/downloads/
Link para download do FireFox
http://br.mozdev.org/firefox/download.html
Mais sobre JavaScript
http://www.w3schools.com/js/default.asp

Figura 11. Aviso sobre a instalao do plug-in no browser

O NetBeans iniciar o processo de execuo do Tomcat e em


seguida ir abrir o browser selecionado automaticamente, e vai
parar no ponto selecionado na aplicao, o ponto de parada selecionado ficar com o fundo verde, agora basta utilizar as teclas
de atalho para continuar a execuo do cdigo, Figura 12.
O processo de depurao com JavaScript independente do
processo de depurao do Java, podemos parar a depurao

Mais sobre HTML


http://www.w3schools.com/html/default.asp

D seu feedback sobre esta edio!


A Web Mobile tem que ser feita ao seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/webmobile/feedback

Edio 23 - WebMobile Magazine

11

Ajuste fino da JVM para


aplicaes Web
Desmistificando o gerenciamento
de memria

De que se trata o artigo


O artigo visa o gerenciamento de memria utilizado pela Java Virtual Machine e as
formas existentes de otimizao das JVMs instanciadas na memria de acordo com
a caracterstica das aplicaes e do ambiente (Hardware + Sistema Operacional) em
que a aplicao se encontra em produo. Alm disso, conhecer as caractersticas das
aplicaes junto com as caractersticas do ambiente computacional ao qual as aplicaes esto hospedadas um fator bastante relevante para identificar a melhor forma
de otimizar o gerenciamento de memria pela Java Virtual Machine.
Para que serve
O artigo apresenta de uma forma bem objetiva como possvel otimizar os recursos computacionais, mais especificamente memria voltil, utilizados pela Java
Virtual Machine (JVM) na interpretao dos Byte Codes, e apresentar as opes
disponibilizadas pela Sun para inicializarmos uma aplicao Java.
Em que situao o tema til
O artigo til para intervenes pr-ativas ou corretivas no processo de
consumo de memria voltil pelas aplicaes e otimizao das regies de
memria utilizadas pela Java Virtual Machine.

Augusto Marinho
augusto@claimant.com.br

Analista de Sistemas formado pela UNESA atuando h trs anos com projetos de desenvolvimento de software utilizando a tecnologia Java para
aplicaes Web. Atualmente, atua como consultor Java numa grande empresa de telecomunicaes e; com consultoria em treinamentos Java para
Claimant, que o seu mais novo desafio profissional.

12

WebMobile Magazine - Ajuste fino da JVM para aplicaes Web

s, desenvolvedores, muitas vezes focamos nosso


trabalho na implementao de solues para o
software que est sendo desenvolvido, e acabamos
no nos preocupando com o desempenho da aplicao no
ambiente de produo. muito difcil estimar o quanto nossa
aplicao ser demandada por requisies e o quanto dessas
requisies iro impactar no desempenho da aplicao e do
consumo dos recursos de hardware, mais especificamente
memria voltil.
Para podermos ter esta percepo, por mais que planejemos,
s conseguimos ter estes parmetros de demanda real quando
a aplicao entra em produo. Atravs do alinhamento da
nossa atividade de desenvolvimento de software, juntamente
com a equipe de infraestrutura, conseguimos ter um feedback
do desempenho da aplicao e do consumo de memria voltil
pela aplicao.
neste contexto que se torna importante e um diferencial
interessante ao desenvolvedor Java conhecer as possibilidades de otimizao da Java Virtual Machine (JVM ver Nota
DevMan 1) no processo de gerenciamento de memria e
a forma como a JVM utiliza este recurso de hardware. Na
grande maioria das vezes, estas opes de otimizao acabam passando despercebidas, onde s iremos dar a devida
importncia a esta otimizao quando a situao j no est
muito confortvel.

Java W eb

Nota do DevMan 1
Java Virtual Machine JVM (Mquina Virtual Java)
Uma Mquina Virtual Java (Java Virtual Machine JVM) um conjunto de programas de software e estrutura de dados que usa um modelo de mquina virtual para a
execuo de outros programas computacionais e scripts. O modelo usado por uma JVM
aceita uma forma de linguagem intermediria de computador comumente referenciada como bytecode Java. Esta linguagem representa conceitualmente o conjunto de
instrues de uma arquitetura orientada a pilha. Em 2006 foi estimado que existe um
nmero em torno de 4 bilhes de dispositivos de JVM habilitados em todo o mundo.
As Mquinas Virtuais Java operam sobre bytecode Java, que normalmente, mas
no necessariamente, gerado a partir de cdigo Java; uma JVM pode tambm ser
usada para implementar linguagens de programao diferentes de Java. Por exemplo, cdigo fonte em Adapode ser compilado para bytecode Java, que poder ento
ser executado por uma JVM.
A JVM um componente crucial da Plataforma Java. Visto que JVMs esto disponveis para muitas plataformas de hardware e software, Java pode ser tanto middlewaree uma plataforma da a marca: escreve uma vez, roda em qualquer lugar
(write once, run anywhere). O uso do mesmo bytecode para todas as plataformas
permite que a linguagem seja descrita como compila uma vez, roda em qualquer
lugar (compile once, run anywhere).
A JVM distribuda junto com um conjunto de bibliotecas de classes padres que
implementam a API (Application Programming Interface) Java. A mquina virtual e
a API tm que ser consistentes entre si e so, portanto, agrupadas em conjunto como
o famoso Java Runtime Environment- JRE.
A arquitetura de JVM permite um controle muito fino sobre as aes liberadas para
o cdigo que est rodando na VM. Isso permite a execuo de cdigo confivel de
fontes remotas, um modelo usado pelos applets. Osappletsrodam dentro de uma
VM incorporada ao browser do usurio, executando cdigo baixado de um servidorHTTPremoto. O cdigo remoto roda em umasandbox, que protege o usurio de
cdigos maliciosos. O autor doappletpode aplicar um certificado para assinar digitalmente o applet como seguro dando a ele permisso de sair dosandboxe acessar
,
livremente a mquina onde est rodando.
Os programas que rodam sobre uma JVM devem ser compilados em um formato
binrio portvel padronizado, que tipicamente vem na forma de arquivos .class. Um
programa pode ser composto de muitas classes em diferentes arquivos. Para facilitar
a distribuio de programas maiores, os diversos arquivos de classes podem ser empacotados juntos em um arquivo .jar (acrnimo para Java ARchive).

Entender o gerenciamento de memria e as divises feitas


neste espao reservado pela JVM um conhecimento interessante, pois permitido intervir na otimizao do ambiente, e
por que no dizer da aplicao, de uma forma pr-ativa e no
apenas corretiva.

No decorrer deste artigo, sero apresentadas as possibilidades de otimizao, as formas de otimizao de cada
sub-regio feita pela JVM e a melhor forma de escolher os
parmetros corretos no processo de otimizao da JVM.
Para demonstrar o estudo, foi utilizado o pacote JDK 1.5.0_14
juntamente com o Web Server Apache Tomcat na sua verso
6.0.18. O ambiente em que foi hospedado o Web Server um
equipamento Sun Netra 105, com processador Ultra Sparc
440mhz de 64bits com 512 de RAM. A aplicao utilizada

para administrao do Apache Tomcat e apresentao das


informaes da JVM pelo Tomcat foi a Lambda Probe na sua
verso 1.7b.
O exemplo utilizado no artigo bem simples, onde o intuito
demonstrar como podemos utilizar os recursos disponibilizados pela JVM para otimizar o recurso de memria voltil
do hardware. No decorrer do artigo ser descrito o exemplo
utilizado e das possibilidades de otimizao do gerenciamento
de memria.

Divises de memria pela JVM


A linguagem Java utiliza duas formas de alocao de recursos de memria: alocao dinmica e linear.
A alocao dinmica visa livre administrao do espao
de memria voltil pela JVM. A ordem de alocao e liberao dos recursos aleatria, e no existe um procedimento
formal.
A alocao linear reserva o espao de memria voltil em
forma de pilha. A alocao e liberao de recursos de memria
voltil so feitas seguindo os conceitos de Pilha (LIFO Last
in, First out o ltimo que entra o primeiro que sai).
A linguagem Java utiliza a alocao dinmica e a alocao
linear para regies diferentes de memria. Estas regies,
basicamente, so o Heap e a Pilha de Operandos utilizando,
respectivamente, alocao dinmica e alocao linear. Para
melhor entendermos estas regies de memria e suas subdivises, a Figura 1 descreve tais divises.

Figura 1. Heap e suas subdivises

Atravs da Figura 1 so apresentadas as subdivises feitas


pela JVM na memria. Para ficar mais claro, uma melhor
definio sobre a qual regio de memria pertence cada uma
dessas subdivises est apresentada na Tabela 1.
Macro regio da JVM
Heap
Pilha de Operandos
Gerao permanente

Subdivises
Gerao Jovem
Gerao Estvel
Quadros, representados na Figura 1 por q1, q2, q3 e q4.
No foram encontrados subdivises na literatura e fontes de consulta.

Tabela 1. Subdivises de memria pela JVM

Edio 23 - WebMobile Magazine

13

Para ficar mais claro, descrito abaixo a importncia e utilizao de cada regio de memria criada pela JVM.
Gerao Jovem
a regio de memria alocada dentro do Heap destinada a alocar
os objetos recentemente instanciados na memria pela JVM.
Est regio ainda subdividida em:
o den
Espao de memria onde so alocados os objetos recentemente instanciados pela JVM. Os objetos s permanecem nesta
regio at serem promovidos para as reas de troca (Origem e
Destino) e, conseqentemente, irem para Gerao Estvel.
o Origem e Destino
Esta a Regio de memria onde so alocados os objetos
que na passagem do Garbage Collection (coletor de lixo)
so trocados de Regio atravs de algoritmos de Cpia. A
combinao da Regio Origem e Destino forma a chamada
Regio dos Sobreviventes.
Gerao Estvel
Est regio armazena os objetos que sobreviveram a vrias
coletas na Gerao Jovem, por isso so chamadas de Gerao
Estvel. O algoritmo utilizado pela Garbage Collection fica responsvel por definir quando os objetos devem ser promovidos
a esta regio do Heap.
Gerao Permanente
Est regio responsvel por armazenar processos que no
estejam relacionados instncia de Objetos no Heap. A Gerao Permanente fica alocada fora do Heap (Gerao Jovem
+ Gerao Estvel), e destinada a armazenar o Class Loader
(responsvel por carregar as classes compiladas bytecodes
para a memria), cdigos compilados (chamada de rea de
mtodos) e por armazenar classes geradas dinamicamente,
como pginas JSP e Objetos JNI (Java Native Interface).
Pilha
A pilha mais uma regio criada pela JVM definida fora do
Heap. Esta regio responsvel por armazenar constantes,
valores de variveis locais; tambm tem a funo de preparar
parmetros a serem passados a mtodos e receber seus resultados. A forma de gerenciamento de memria utilizado pelo
JVM para esta regio a alocao Esttica.
Atravs da Figura 2 so ilustradas as divises da Pilha na
Memria
Para cada Thread em execuo criada uma Pilha respectivamente com seus quadros, e por sua vez os quadros com
seu array de variveis locais e sua pilha de operandos. Os
dados de um quadro e outro no so compartilhados entre
os Threads. Por este motivo que para cada Thread criada sua
prpria pilha.

14

WebMobile Magazine - Ajuste fino da JVM para aplicaes Web

Figura 2. Diviso interna da Pilha de Operandos

Desempenho de aplicaes Java


A JVM se comporta de forma diferente conforme o ambiente
o qual opera. Por default, a JVM inicializada como cliente, ou
seja, utiliza algoritmo de coleta serial pelo Garbage Collection, com
o Heap inicial mnimo de 4 MB podendo chegar at 64 MB.
Dependo do ambiente em que hospedada a aplicao, estes
valores no so suficientes e podem facilmente atingir seus
limites e a JVM lanar excees por falta de memria. As excees mais comuns lanadas por falta de memria so:
OutOfMemoryError: exceo lanada quando j no h mais
espao no Heap para instanciar novos objetos.
StackOverFlowError: exceo lanada quando os dados a
serem inseridos na pilha de operando so maiores que os permitidos pela JVM. Ocorre, geralmente, quando uma instruo
utiliza muitas variveis locais ou quando ocorrem chamadas
recursivas infinitas.
Para inibir este tipo de cenrio e evitar que a aplicao fique
indisponvel por falta de espao no Heap ou evitar a perda
de desempenho em aplicaes de vida longa, importante
conhecer os recursos disponibilizados na verso da JVM que
est sendo utilizada para prover aplicaes Java.
A JVM disponibiliza uma quantidade bastante grande de
parmetros para otimizar as regies de memria criadas, assim
como gerenciamento de Threads, escolha do algoritmo a ser
utilizado pelo Garbage Collection para cada regio, dentre outras
coisas. Escolher os parmetros mais adequados ao ambiente da
aplicao nem sempre uma tarefa fcil, mas conhecer a forma
de gerenciamento de memria e as ferramentas disponveis
para otimizar a JVM e conseqentemente a aplicao uma
tarefa bastante interessante e importante para a qualidade do
produto Java disponibilizado.
As aplicaes Java de vida longa hospedadas em ambiente
de grande porte so as mais sensveis na utilizao dos parmetros disponibilizados. Conhecer a aplicao e ambiente

Java W eb

fundamental para parametrizar de forma eficiente a instncia


da JVM responsvel por determinado tipo de aplicao. Os
mitos muitas vezes levantados sobre o desempenho do Java
podem ser afastados conhecendo estes recursos e saber como
aplic-los corretamente.

Analisando o desempenho de aplicaes Java utilizando


Apache Tomcat e a ferramenta Lambda Probe
A aplicao Lambda Probe foi escolhida, pois uma aplicao
que implementa anlises atravs de grficos das regies de
memria criadas pela JVM para cada aplicao que se encontra
em produo com o Apache Tomcat. O download da aplicao
Lamba Probe pode ser feito atravs do link
http://www.lambdaprobe.org/downloads/1.7/probe.1.7b.zip
Para utilizar a ferramenta Lambda Probe necessrio descompactar a aplicao e mover o arquivo probe.war para o diretrio
%CATALINA_HOME%\webapps.
Ainda antes de iniciar o Apache Tomcat necessrio editar o
arquivo tomcat-users.xml para adicionar um usurio fazendo parte
do grupo manager. Este arquivo pode ser encontrado dentro do
diretrio %CATALINA_HOME%\conf. Na Listagem 1 apresentado um exemplo de como este arquivo deve ser configurado.
Listagem 1. Configurando o arquivo tomcat-users.xml
<?xml version=1.0 encoding=utf-8?>
<tomcat-users>
<role rolename=manager/>
<user username=tomcat password=tomcat roles=manager/>
</tomcat-users>

Na Listagem 1, foi criado o usurio tomcat com senha tomcat


para acessar a interface administrativa disponibilizada pela
aplicao Lambda Probe.
Aps estes passos j possvel iniciar o Apache Tomcat. Para
acessar a aplicao Lambda Probe preciso acessar o endereo
http://localhost:8080/probe. Ao acessar, dever estar disponvel
uma interface perguntando sobre usurio e senha, onde devemos informar o que foi configurado na Listagem 1 (usurio
tomcat para e senha tomcat) e em seguida dever ser apresentada

a interface apresentada na Figura 3.


A aplicao Lamba Probe disponibiliza interfaces grficas
para analisar o desempenho e apresentar informaes do
ambiente como:
Sumrios das Aplicaes
DataSources criados
Monitoramento de memria e sua utilizao
Deploy de aplicaes
Informaes do Ambiente como Sistema Operacional, Paths etc
Dentre os recursos listados, o mais utilizado neste artigo ser o
Monitoramento de memria, para que seja possvel demonstrar
graficamente o comportamento da memria atravs do gerenciamento feito pela instncia da JVM para o WebServer.
Para demonstrar a utilizao de alguns parmetros utilizados no exemplo, ser criado o Shell script setenv.sh. Este
Shell script dever ser criado dentro do diretrio %CATALINA_HOME\bin. O Apache Tomcat durante o processo de
inicializao procura este arquivo para inicializar algumas
variveis de ambiente necessrias para carregar o Web
Server.
Para que seja possvel a aplicao Lambda Probe apresentar
os grficos referentes ao gerenciamento de memria, o parmetro Dcom.sun.management.jmxremote=true obrigatrio.
Este parmetro deve ser atribudo varivel de ambiente
do Apache Tomcat JAVA_OPTS. atravs desta varivel que
posteriormente podero ser aplicados outros parmetros de
tuning atribudos JVM utilizada pelo Apache Tomcat.
Na Listagem 2 apresentado um exemplo de configurao
do Shell script setenv.sh.
Listagem 2. Configurando o arquivo setenv.sh
#!/bin/bash
JAVA_OPTS= -Dcom.sun.management.jmxremote=true
EXPORT JAVA_OPTS

Para que as novas configuraes tenham valor necessrio


reiniciar o servio do Apache Tomcat (ver Nota 1).

Figura 3. Apresentado a aplicao Lambda Probe

Edio 23 - WebMobile Magazine

15

Nota 1. Observao
importante lembrar que os exemplos apresentados so para ambiente Solaris, Linux ou
similares, mas isso no que dizer que seja impeditivo implantar este ambiente em Windows.
Para que isso seja possvel, o Shell script setenv.sh deve ser substituindo em ambiente Windows
pelo Batch setenv.bat.
As variveis de ambiente utilizadas tanto em Windows quando em Solarios\Linux so as
mesmas, deve apenas ser levado em considerao a estrutura de formao e definio de
variveis de ambiente do Apache Tomcat para Windows.
Para maiores detalhes de como estruturar estes arquivos para ambiente Windows acesse:
http://tomcat.apache.org/tomcat-6.0-doc/index.html

Estudo de Caso
O exemplo criado para demonstrao dos parmetros
disponibilizados pela JVM simula um ambiente com alto
consumo de memria. Para simular este ambiente, foi desenvolvida uma aplicao que captura um ArrayList contendo
um milho de objetos Cliente serializados para dentro do
arquivo webmobile1.txt.
Quando a pgina index.jsp lida pelo servidor, este arquivo
JSP fica responsvel por ler o arquivo serializado webmobile1.
txt e inserir cada um dos objetos Cliente na sesso do servidor atravs do objeto implcito session do JSP.
O objeto Cliente um Bean, ou seja, uma classe que apenas possui atributos e mtodos gets e sets. Na Listagem 3
descrita a estrutura do Bean Cliente.
Listagem 3. Cdigo referente ao Bean Cliente

Listagem 4. Cdigo referente classe SerializaObjetos


public class SerializaObjetos {

private FileInputStream fis = null;
private List<Cliente> lista = null;
/**
* @author Augusto Marinho
* @param arquivo
* @throws IOException
* @throws ClassNotFoundException
*
* Mtodo responsvel em fazer a leitura do arquivo serializado
*/
@SuppressWarnings(unchecked)
public void getDadosSerializadosComArray(String arquivo) throws
IOException, ClassNotFoundException {

ista = new ArrayList<Cliente>();
l

is = new FileInputStream(arquivo);
f

bjectInputStream ois = new ObjectInputStream(fis);
O

ista = (ArrayList<Cliente>)ois.readObject();
l

or(Cliente c : lista) {
f

lista.add(c);


}
}

/**
* @author Augusto Marinho
* @return
*
* Mtodo responsvel em retornar o ArrayList contendo o
contedo
* dos dados do arquivo serializado
*/
public List<Cliente> getLista() {
eturn lista;
r
}
}

public class Cliente implements Serializable{


private String nome;
private int idade;
private String email;

public String getNome() {
eturn nome;
r
}
public void setNome(String nome) {
his.nome = nome;
t
}
public int getIdade() {
eturn idade;
r
}
public void setIdade(int idade) {
his.idade = idade;
t
}
public String getEmail() {
eturn email;
r
}
public void setEmail(String email) {
his.email = email;
t
}
}

A classe SerializaObjetos responsvel pela leitura do arquivo serializado webmobile1.txt, capturar o ArrayList de objetos
Cliente atravs do mtodo getDadosSerializadosComArray(). Para
ter acesso ao ArrayList capturado do arquivo, deve ser feito uso
do mtodo getLista().
Para melhor visualizar a estrutura da classe, na Listagem 4
apresentado o cdigo-fonte da classe SerializaObjetos.
Na Figura 4 apresentada a estrutura do projeto da aplicao
de exemplo no Eclipse.

16

WebMobile Magazine - Ajuste fino da JVM para aplicaes Web

Figura 4.Estrutura do Projeto de Exemplo

Depois de desenvolvido este exemplo, foi gerado o pacote


webmobile1.war e foi feito deploy deste arquivo no diretrio
%CATALINA_HOME%\webapps.
A seguir ser apresentado como foi estruturado o exemplo
e os testes no ambientes Sparc com Solaris para que possamos
perceber o comportamento da JVM.

Java W eb

Figura 5. Consumo de memria sem parametrizao

Figura 6. Erro ao executar a aplicao de teste pela primeira vez: OutOfMemoryError

Analisando e ajustando o desempenho do


Estudo de Caso
Antes de iniciarmos com o Deploy da aplicao de teste,
voltemos ao passo anterior para verificarmos a identificao
do ambiente pela JVM, apresentado atravs da aplicao
Lambda Probe conforme exibido na Figura 5.
Antes de adicionarmos quaisquer parmetros na inicializado da JVM do Tomcat no Shell script setenv.sh, importante
fazer alguns comentrios analisando a rea Memory Utilization descrita na Figura 5:
Mesmo o ambiente sendo uma mquina Sun Netra 105
com arquitetura Sparc com processador de 64bits e 512Mb
de RAM, a JVM identificou o ambiente como sendo um ambiente cliente, ou seja, a JVM foi inicializada com os valores
default de um ambiente cliente. Na Figura 5 identificamos
o valor mximo do Heap de 64MB (mais precisamente 63,81
Mb), que o valor default mximo para uma JVM cliente
sem parametrizao.
O valor total utilizado, sem deploy da aplicao de exemplo,
de 14,6MB. Este valor maior que o valor mnimo default
de 4MB definido pela JVM num ambiente cliente. Mas mesmo assim, estamos num ambiente cliente, pois a JVM pode
expandir o Heap at os 64MB.

Agora, no passo atual, consideremos que o Deploy da aplicao de exemplo webmobile1.war j est no ar, mas ainda no
foi executada por ningum.
Quando acessarmos pela primeira vez o contexto webmobile1
no endereo http://localhost:8080/webmobile1 perceba na Figura
6 a surpresa que teremos.
A aplicao est com erro! O que houve? O que programei
errado?
Estas devem ser umas das muitas indagaes quando nos
esquecemos de dimensionar o volume de informaes da nossa
aplicao com as possibilidades de gerenciamento da JVM no
ambiente de produo.
A exceo lanada foi um OutOfMemoryError (Heap Space). O
que podemos concluir com isso? Que a nossa aplicao uma
aplicao bomba?
No exatamente, o grande problema identificado pela JVM
foi a falta de espao no Heap para armazenar um milho de
objeto Cliente em uma JVM cliente default com 64MB de espao
definido com o mximo a ser utilizado. Com este volume de
informaes nunca ser possvel acessar a aplicao de exemplo
e apresentar o contedo to esperado.
Agora como podemos viabilizar o acesso a aplicao se a JVM
identificou o meu Sun Netra 105 como cliente? Mas eu queria

Edio 23 - WebMobile Magazine

17

que fosse um servidor fazendo o seu papel de Sparc.


Para que possamos viabilizar a execuo da aplicao, sero
passadas como parmetros para JVM, atravs do Shell script
setenv.sh as seguintes informaes:
-d64
Habilita a utilizao do processamento em 64bits pela JVM.
Ou seja, a JVM passa a enviar para o processador instrues de
64bits por vez, ao invs de 32bits que o default. Este parmetro
por si s no resolveria nosso problema de falta de espao no
Heap, mas se torna importante para oferecer maior velocidade
de processamento, aproveitando a arquitetura de hardware ao
qual a JVM encontra-se disponibilizada.
-server
A opo server, basicamente, maximiza o tempo de execuo da aplicao, definindo o algoritmo de coleta paralela
para o Garbage Collection. Este algoritmo se comporta melhor
em ambiente com um porte de hardware maior. Aplicaes
de vida longa tendem a ser tornarem mais rpidas com
esta opo.
Geralmente a JVM identifica automaticamente se est sendo
executado num ambiente cliente ou servidor. A JVM identifica automaticamente o ambiente como servidor se o hardware
o qual est sendo executada tiver mais de um processador ou
ncleo com mais de 2GB de RAM. No nosso caso especfico, a
opo server se torna possvel por estarmos num ambiente
com arquitetura de processamento Sparc de 64bits.
Este parmetro em si no resolveria o problema de falta de
espao no Heap, mas se torna importante motivado pela
longevidade da aplicao.
-Xms200m
Este parmetro muito importante para resoluo do nosso
problema de falta de espao no Heap. Atravs do parmetro
Xms podemos definir o tamanho inicial do Heap. Ou seja,
j na sua inicializao definimos um espao mnimo de
200 MB.
Estes 200MB sero divididos automaticamente pela JVM para
a gerao jovem e gerao estvel. Lembrando que a gerao
permanente no faz parte do Heap.
-Xmx200m
Este parmetro tambm muito importante para resoluo
do nosso problema de falta de espao no Heap. O parmetro
Xmx responsvel por definir o tamanho mximo do Heap,
ou seja, sua rea total de utilizao.
Este parmetro foi configurado igual ao parmetro Xms
para 200 MB, e isto tem uma razo de ser. Definir o tamanho mnimo e mximo do Heap com o mesmo valor uma
configurao importante, pois a cada passagem do Garbage
Collection no Heap, a JVM evita de calcular o valor mnimo
do Heap que a mesma dever assumir.
Fazendo esta configurao juntamente com o parmetro
server temos um ganho de processamento das informaes
bastante interessante para aplicaes de vida longa.

18

WebMobile Magazine - Ajuste fino da JVM para aplicaes Web

-Xss128k
A opo Xss define o tamanho que cada quadro da pilha
dever assumir como sendo 128 KB. A pilha com um tamanho de quadro maior evita que ocorra StackOverFlowError em
aplicaes de vida longa.
importante ter um certo cuidado com a configurao deste
parmetro, pois em um ambiente que a JVM trabalha com um
tamanho de quadro muito grande, a aplicao pode ter perda
de desempenho, e este no nosso objetivo.
-XX:PermSize=50m
O parmetro XX:PermSize define o valor mnimo reservado
para Gerao Permanente, que ser de 50 MB. Lembrando que
este espao no est alocado dentro do nosso Heap definido
com 200MB.
Em aplicaes de vida longa, importante configurar esta
regio, pois as coletas feitas pelo Garbage Collection nesta Regio
so mais raras.
Uma JVM configurada com uma Gerao Permanente muito
grande pode gerar perda de desempenho, e mais uma vez este
no nosso objetivo.
-XX:MaxPermSize=50m
O parmetro XX:MaxPermSize define o tamanho mximo
reservado na memria para a Gerao Permanente que tambm
ser de 50 MB. Mas uma vez, definimos o tamanho inicial
igual ao tamanho mximo. Isto se deve ao mesmo fato da
configurao do tamanho do Heap.
Com a passagem do Garbage Collection nesta regio de memria, a JVM evita ter o trabalho de recalcular o tamanho mnimo
que dever assumir aps a coleta.
-Dcom.sun.management.jmxremote=true
atravs deste parmetro que a aplicao Lambda Probe consegue obter informaes sobre a instncia da JVM responsvel
pelo Apache Tomcat. Este parmetro habilita a monitorao
remota da JVM por agentes JMX.
A Listagem 5 descreve como ficaria o cdigo do nosso arquivo Shell script setenv.sh.
Listagem 5. Cdigo resultante do Sheel script stenv.sh
#!/bin/bash
JAVA_OPTS=-d64 server Xms200m Xmx200m Xss128k
XX:PermSize=50m XX:MaxPermSize=50m
-Dcom.sun.management.jmxremote=true
Export JAVA_OPTS

Para que estas configuraes tenham efeito, necessrio que


o Apache Tomcat seja reiniciado.
Para verificarmos que as configuraes de fato foram feitas
conforme o esperado, via SSH no servidor Solaris sero executados os seguintes comandos:
ps ef | grep java
Com este comando possvel listar todos os processos Java que

Java W eb

Figura 7. Parmetros de Tuning da JVM

esto sendo executados. Visualmente, como um ambiente


de exemplo, fica fcil identificar.
pargs <PID_TOMCAT>
O comando pargs uma particularidade do Solaris. Atravs do PID passado como parmetro para o comando,
possvel listar os parmetros passados para o processo no
momento da sua inicializao.
Atravs da Figura 7 podemos constatar o sucesso da adio
dos parmetros JVM do Apache Tomcat.
Aps a adio destes parmetros na JVM responsvel pelo
Apache Tomcat j possvel acessar a aplicao de exemplo
webmobile1, conforme a Figura 8.
Vejamos na Figura 9 como a memria se comportou aps
a adio dos novos parmetros e aps o acesso aplicao
de exemplo.

Figura 8. Aplicao de Exemplo de alto consumo de memria

Diferentemente da Figura 5, j possvel perceber algumas


diferenas importantes sobre o Heap atravs da Figura 9.
Percebemos que dos 200MB (mnimo e mximo) definidos,
a aplicao conseguiu consumir 98,3% do Heap, deixando
disponvel apenas 3,41MB livres. Ou seja, nossas configuraes foram bem-sucedidas, conseguimos fazer a aplicao
ser executada, mas atingimos o limite de nossas configuraes. Mas como um exemplo, este limite foi definido
propositalmente.
evidente que estas configuraes no atenderiam a um
volume grande de requisies, at por que o Sun Netra
105 utilizado tambm chegaria aos limites de hardware.
Por mais eficiente que fossem nossas parametrizaes,
no podemos esquecer que, muitas das vezes, podemos
ser impedidos pelas limitaes de hardware; no existem
parmetros para contornar este limite!
A Figura 10 representa a utilizao de memria distribuda
pelas regies de memria controladas pela JVM. possvel
perceber claramente as regies de memria que fazem parte do
Heap e as que no fazem atravs da coluna GROUP (a ltima).
A Regio Survivor Space representa as regies dos sobreviventes, que por sua vez uma sub-regio da Gerao Jovem,
que faz parte do Heap, como pode ser visto atravs da ltima
coluna da tabela. A Regio dos sobreviventes, neste exemplo,
est praticamente vazia, pois a aplicao ainda no sofreu interferncia do Garbage Collection. Os dados presentes nesta Regio
so dados inseridos pela JVM para quebrar as informaes
entre as Regies que compem o Heap. A JVM inteligente o
suficiente para fazer este tipo de tarefa.
A Regio Perm Gen representa a Gerao Permanente, que

Edio 23 - WebMobile Magazine

19

Figura 9.Consumo de memria 1

Figura 10. Consumo de memria 2

foi configurada no nosso exemplo utilizando os parmetros


XX:PermSize e XX:MaxPermSize; tambm possvel identificar pela ltima coluna da tabela que esta Regio no faz
parte do Heap. A Regio Permanente armazena objetos que
sobreviveram a muitas coletas realizadas pela Garbage Collection. As coletas nesta Regio so mais raras, e quando acontecem so um pouco mais demoradas que as coletas feitas em
outras regies. A Regio Permanente tambm responsvel
por armazenar informaes do Class Loader, classes geradas
dinamicamente (como pginas JSP).
A Regio Tenured Gen representa a Gerao Estvel da JVM.
Como explicado anteriormente, essa a Regio que armazena
os objetos sobreviventes a algumas coletas realizadas na Gerao Jovem. Numa JVM em modo Server, em mdia, est Regio
dever representar 2:3 do valor definido para Heap total.
A Regio Eden Space representa o den que uma sub-regio
da Gerao Jovem. No exemplo apresentado, perceba que

20

WebMobile Magazine - Ajuste fino da JVM para aplicaes Web

esta regio ocupa todo seu espao, pois como a aplicao de


exemplo s foi executada uma nica vez, ainda no houveram
coletas realizadas pelo Garbage Collection.
Podemos definir o tamanho total da Gerao Jovem da JVM
analisada com o somatrio do Eden Space (62,75MB) com o
Survivor Space (1,94MB), que respectivamente so os valores
informados na coluna Maximun da tabela apresentada na
Figura 10. importante citar que com a JVM configurada
em modo Server, a proporo da Gerao Jovem com relao
ao espao total definido para o Heap de 1 para 3, ou seja, na
grande maioria da vezes representa 1/3 do Heap Total.
A regio Code Cache representa a rea de cache de objetos
pela JVM. Neste artigo esta regio no foi citada, pois tem uma
utilidade bastante particular, e perderamos o foco.
O cdigo completo referente aplicao criada e utilizada
ao longo deste artigo est disponvel no Portal da Revista
WebMobile. Voc pode obter este material acessando-o.

Java W eb

Concluses

Links

Existe uma infinidade de parmetros para configurar a JVM


e suas regies, assim como definir outros algoritmos a serem
utilizados na JVM para coleta de lixo. Escolher os melhores
parmetros de configurao para otimizao dos recursos de
memria utilizados pela JVM nem sempre uma tarefa fcil.
Definir o ambiente fruto de bastante conhecimento da tecnologia, do porte da aplicao e do ambiente de hardware em si.
importante dizer que estas configuraes no eliminam
as necessidades do desenvolver em saber utilizar os melhores
recursos disponibilizados pela verso do Java utilizada para
o desenvolvimento de aplicaes. A tarefa de otimizao da
JVM deve ser vista como uma tarefa complementar ao software
bem estruturado e desenvolvido, onde o desenvolver tem plena
conscincia dos procedimentos internos adotados para implementao em software de uma determinada necessidade.
cada vez mais importante que o profissional no apenas
fique focado na sua especialidade, no caso o desenvolvimento;
compartilhar o conhecimento e experincia com outras reas
de atuao no processo de desenvolvimento e operao do
software um diferencial competitivo importante para um
desenvolvedor Java.

Java Tuning Java Tuning White Paper


http://java.sun.com/performance/reference/whitepapers/tuning.html
HotSpot VM
http://java.sun.com/javase/technologies/hotspot/index.jsp
Tuning Garbage Collection
http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
Troubleshooting Java
http://java.sun.com/javase/6/webnotes/trouble/
JavaTM Virtual Machine Technology
http://java.sun.com/javase/6/docs/technotes/guides/vm/index.html

D seu feedback sobre esta edio!


A Web Mobile tem que ser feita ao seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/webmobile/feedback

Conhecimento faz diferena!


Capa ESM - Final .pdf

19.02.08

Faa um up grade em sua carreira.


Em um mercado cada vez mais focado
em qualidade ter conhecimentos aprofundados sobre requisitos, metodologia,
anlises, testes, entre outros, pode ser a
diferena entre conquistar ou no uma
boa posio profissional. Sabendo disso a
DevMedia lana para os desenvolvedores
brasileiros sua primeira revista digital
totalmente especializada em Engenharia
de Software. Todos os meses voc ir
encontrar artigos sobre Metodologias
Ageis; Metodologias tradicionais (document
driven); ALM (application lifecycle
management); SOA (aplicaes orientadas
a servicos); Analise de sistemas; modelagem;
Mtricas; orientao objetos; UML; testes
e muito mais. Assine j!

18:15:13

magazine

Engenharia de Software
Saiba seu significado e para que serve

Edio Especial

Entenda os principais conceitos sobre


Testes e Inspeo de Software
Verificao, Validao & Teste
Ferramentas Open Source e melhores
prticas na gesto de defeitos

Requisitos

Conhea os principais conceitos envolvidos


na Engenharia de Requisitos

Especial

Projeto

Entenda o conceito de Arquitetura de Software e


como trabalhar com os Estilos Arquiteturais

Mais de 60 mil downloads


na primeira edio!

Processos

Melhore seus processos atravs da


anlise de risco e conformidade

Veja como integrar conceitos de


Modelos Tradicionais e geis

Veja como integrar o Processo


Unificado ao desenvolvimento Web

Faa j sua assinatura digital! | www.devmedia.com.br/es

Edio 23 - WebMobile Magazine

21

Criando um aplicativo
LBS para consulta
de pontos tursticos
em cidades
Receba avisos ao se aproximar de
pontos tursticos atravs de um
aplicativo Java ME com acesso a dados
de geolocalizao
De que se trata o artigo
O artigo apresenta o desenvolvimento de um aplicativo LBS (Location Based
Service) direcionado para telefones celulares. Estes aparelhos acessam um servidor web com dados de pontos tursticos de uma cidade e, atravs destas informaes e da recuperao de dados de geolocalizao no dispositivo mvel, avisam
o usurio quando este se aproximar de um dos pontos cadastrados no banco de
dados do servidor web. A partir deste aviso, o usurio pode visualizar uma imagem
ou requisitar mais informaes sobre o referido ponto. No segundo artigo desta
srie, o usurio poder cadastrar pontos tursticos apenas capturando uma foto do
local e enviando ao servidor web.
Para que serve
Utilizar informaes de georeferenciamento atravs da Java Location API
em aplicativos Java ME. Alm disso, trata da utilizao de listeners que avisam o usurio da aproximao de um ponto conhecido, configurado pela sua
posio (latitude e longitude). O segundo artigo desta srie tambm mostrar informaes de mdia com a Mobile Media API.
Em que situao o tema til
Na utilizao de informao de georeferenciamento e na utilizao de listeners de aproximao de pontos geogrficos.

Ricardo Ogliari
rogliariping@gmail.com

Atua no desenvolvimento de aplicaes mveis com a plataforma Java ME a 5


anos. Bacharel em Cincia da Computao. Ministra cursos e oficinas, possuindo vrios artigos tcnicos sobre JME. Ministrou palestras em vrios eventos
pelo Brasil, como o JustJava e o Frum Internacional do Software Livre.

22

disseminao de aplicativos LBS (Location Based


Service) na sociedade cresce vertiginosamente,
principalmente no ramo automotivo, onde aparelhos que guiam os motoristas esto se tornando comum no
dia-a-dia. O uso deste tipo de aplicativo em dispositivos
mveis ainda um pouco limitado, devido a questes de
hardware e software, ou at mesmo da usabilidade de pequenos dispositivos. Um bom exemplo so os aplicativos
LBS em aparelhos celulares. Sua tela com pouca dimenso
dificulta a visualizao ampla de mapas. Porm, mesmo
com todos os empecilhos, as previses para este mercado
so animadoras em todos os setores.
Alm disso, embora a visualizao de um mapa em um
aparelho automotivo possa oferecer melhor visibilidade
e exatido, no estaremos sempre transitando sentados
confortavelmente no banco de um automvel. Existiro
situaes onde a nica ferramenta disponvel ser um dispositivo mvel, seja ele um aparelho celular, um smartphone
ou um PDA (Personal Digital Assistant). Nesse sentido, o
telefone celular possui mais pontos positivos, como a facilidade extrema de ser transportado, seu preo reduzido e a
existncia de planos cada vez mais atraentes das operadoras
de telefonia celular. Levando isso em conta, aplicativos LBS
mobile no devem ser desprezados.

WebMobile Magazine - Criando um aplicativo LBS para consulta de pontos tursticos em cidades

Java M obile

E relacionado ao Mobile Learning? O prprio termo pouco


difundido. Ele apenas compreende aplicativos direcionados
ao ambiente mvel que visam o aprendizado dos usurios.
Este tipo de ferramenta muito carente no dias de hoje.
Alguns museus utilizam aplicativos para que os visitantes
possam ter maiores informaes sobre as obras de arte ou
ainda para visitas virtuais. Isso poderia ser exemplificado
como um tipo de Mobile Learning.
O objetivo desta srie de dois artigos justamente a criao
de um aplicativo LBS que possa auxiliar no aprendizado da
histria de uma cidade, ou seja, um sistema Mobile Learning.
A idia o cadastro de pontos histricos em um servidor
web, informando o nome, descrio, uma imagem e as coordenadas deste ponto. Essas informaes so baixadas no
celular que, atravs da obteno de informaes de georeferenciamento, pode saber quando est se aproximando de
um determinado ponto, alertando o usurio. Alm disso,
a ferramenta permitir que os usurios cadastrem pontos
da sua cidade a partir de seu telefone celular. O cenrio
muito simples, o usurio precisa apenas capturar uma imagem, descrever o nome e uma descrio do ponto e enviar
para o servidor web. A posio geogrfica do local obtida
automaticamente pela aplicao, atravs da utilizao da
Java Location API.
Com isso, o leitor aprender vrias tecnologias no decorrer
deste trabalho: aplicativos LBS e a utilizao da Java Location API, utilizao de dados multimdia em aplicativos Java
ME e troca de dados entre celular e servidor.
Este primeiro artigo apresenta a criao do aplicativo servidor e do aplicativo cliente, somente com obteno dos pontos
e aviso de proximidade, sem a possibilidade de cadastro de
locais. O segundo artigo da srie completa o aplicativo.

Java Location API JSR 179


A JSR 179 fornece um pacote opcional que permite aos desenvolvedores Java ME criarem aplicativos LBS. Seus recursos esto todos no pacote javax.microedition.location. No total
so 11 classes: AddressInfo, Coordinates, QualifiedCoordinates,
Criteria, Landmark, LandmarkStore, Location, LocationProvider,
Orientation, LandmarkException e LocationException, sendo
as duas ltimas de exceo. As interfaces que representam
listeners so LocationListener e ProximityListener.
A API utiliza o sistema de coordenadas latitude-longitude-altitude. A altitude medida em relao linha do
Equador, podendo variar de 0 a 90 graus ao norte ou ao
sul. A longitude cortada pelo meridiano de Greenwich na
Inglaterra, e pode ir de 0 a 180 graus para leste ou oeste. J a
altitude medida em relao ao nvel do mar. Para melhor
compreenso, veja a Figura 1. As linhas que cortam o mapa
da terra verticalmente representam a latitude, sendo que a
linha identificada pela legenda 0 representa o marco 0 da
latitude (onde cruza a cidade de Greenwich na Inglaterra).
As linhas que cortam o globo horizontalmente representam
a longitude, sendo que a linha identificada pela legenda 0
representa o marco 0 da longitude (linha do Equador).

Figura 1. Representao visual de latitude e longitude.

Para recuperar a posio do terminal, que no nosso caso o


telefone principal, a API utiliza a classe LocationProvider. Seu
construtor recebe uma instncia da classe Criteria, que especifica parmetros para a busca da posio. Por exemplo, os
mtodos setHorizontalAccuracy e setVerticalAccuracy especificam
a exatido da posio no sentido horizontal e vertical. Existe
ainda o mtodo setSpeedAndCourseRequired que define se a
procura retornar o curso e velocidade do terminal ou no.
Com a instncia de LocationProvider possvel recuperar
uma instncia do objeto Location atravs de uma chamada ao
mtodo getLocation(), passando como parmetro o tempo de
timeout. A classe Location contm o mtodo getQualifiedCoordinates, que retorna uma instncia da classe Coordinates. Esta,
por sua vez, contm os mtodos necessrios para pegar todas
as informaes relevantes de que um sistema LBS necessita:
Altitude: getAltitude();
Latitude: getLatitude();
Longitude: getLongitude();
Para recuperar informaes de velocidade e curso do aparelho, basta chamar os mtodos getSpeed() e getCourse(), ambos
da classe Location.
Ter um aplicativo que exige que o usurio faa alguma ao
a cada vez que queira obter sua posio no muito sensato.
No seria melhor a API informar ao usurio automaticamente
quando a posio atualizada? Na minha opinio sim, e esse
propsito da classe LocationListener. Uma classe que implementa esta interface deve implementar de forma obrigatria
os mtodos: locationUpdated(LocationProvider provider, Location
location) e providerStateChanged(LocationProvider provider, int
newState). O primeiro chamado toda vez que a posio geogrfica do terminal for alterada, passando por parmetro a
instncia do LocationProvider que o listener est ouvindo e
a nova posio, especificada como uma instncia da classe
Location. O segundo mtodo chamado toda vez que a disponibilidade do LocationProvider alterada, podendo ficar disponvel, fora de servio ou indisponvel. A classe traz algumas
constantes que especificam cada um dos estados: AVAILABLE,
OUT_OF_SERVICE, TEMPORARILY_UNAVAILABLE.
O segundo Listener da API permite que eventos sejam lanados a cada vez que o terminal se aproximar de pontos prdefinidos. Por exemplo, um aplicativo Java ME pode marcar
os restaurantes que o usurio mais gosta. Posteriormente,

Edio 23 - WebMobile Magazine

23

quando o terminal passar a 300 metros do local entre as 11


e 13 horas, ele informa o usurio desta proximidade. Este
listener o ProximityListener, que obriga a implementao dos
mtodos proximityEvent(Coordinates coordinates, Location location)
e monitoringStateChanged(boolean flag) pela classe que a implementar. O primeiro mtodo chamado quando o terminal se
aproxima de um ponto pr-definido e o segundo chamado
quando o monitoramento das coordenadas passa de ativo para
inativo ou vice-versa.

Criando a Aplicao Servidor


Para a construo do aplicativo servidor, foi utilizado a
IDE NetBeans 6.1. Esta IDE traz acoplada o JavaDB (ver Nota
DevMan 1), tambm utilizado na construo do aplicativo
servidor. Nossa aplicao ser construda com fins de estudo,
por isso, ter pontos histricos somente da cidade de So
Paulo. O banco de dados contm uma nica tabela, chamada
PONTOHISTORICO. Seus campos so: cdigo, nome, imagem,
texto, latitude e longitude.

Nota do DevMan 1
JavaDB
Java DB uma distribuio da Sun para o banco de dados 100% de tecnologia Java
Apache Derby. Ele totalmente transacional, seguro, simples de usar, baseado em padres SQL, JDBC API e Java EE e pequeno, apenas 2MB. O projeto Apache Derby
possui uma comunidade forte e crescente que inclui desenvolvedores de grandes companhias tais como Sun Microsystems e IBM, assim como colaboradores individuais.

A tarefa a ser executada controlada por um parmetro chamado acao. Veja a Listagem 1 com o trecho de cdigo Java que
inserido na pgina JSP logo nas primeiras linhas.
Listagem 1. Parte da implementao do index.jsp
1. String acao = request.getParameter(acao);
2.
3.
Class.forName(org.apache.derby.jdbc.ClientDriver);
4.
Connection conn = DriverManager.
getConnection(jdbc:derby://localhost:1527/PONTOS);
5.
6.
Statement st = conn.createStatement();
7.
Statement stDeletar = conn.createStatement();
8.
Statement stSalvar = conn.createStatement();
9.
10.
if (acao != null && acao.equals(ver))
11. {
12. ResultSet rs = st.executeQuery(select * from
pontohistorico where codigo = +
13.
request.getParameter(codigo));
14.
rs.next();
15. %>
16.<table border=1>
17.<tr>
18.<td>Nome:</td>
19.<td><%=rs.getString(nome)%></td>
20.</tr>
21.<tr>
22.<td>Imagem:</td>
23.<td><%=rs.getString(imagem)%></td>
24.</tr>
25.<tr>
26.<td>Texto</td>
27.<td><%=rs.getString(texto)%></td>
28.</tr>
29.<tr>
30.<td>Latitude</td>
31.<td><%=rs.getString(latitude)%></td>
32.</tr>
33.<tr>
34.<td>Longitude</td>
35.<td><%=rs.getString(longitude)%></td>
36.</tr>
37.<tr>
38.<td></td>
39.</tr>
40.</table>
41.
<%
42. else if (acao != null && acao.equals(alterar))
43.
...
44.
else if (acao != null && acao.equals(inserir))
45. ...
46.
else
47.
...

A primeira linha recupera o parmetro passado para a pgina


JSP. A seqncia de linhas que vai da linha 3 at a linha 8 cria
a conexo com o banco de dados e as instncias de Statements
necessrias para as aes no JavaDB. A seguir, so feitos testes
com a varivel acao. Por exemplo, a linha 10 testa se esta varivel recebeu o valor ver, o que significa que a tarefa do JSP
apenas mostrar as informaes de um determinado ponto.
A linha 12 at a linha 40 cria uma tabela no HTML e mostra o
nome, imagem, descrio e posio geogrfica do ponto.

Criando a Aplicao Mobile

Figura 2. Interface principal do aplicativo servidor.

Existe apenas um arquivo JSP chamado index.jsp, que controla a interface principal da pgina (Figura 2) e todas as aes
relacionadas, como insero, alterao e remoo de registros.

24

Na aplicao mobile onde veremos a utilizao da Java Location API. A compreenso do projeto simples, so somente
duas classes: MostraLocalizacao e AcessoHTTP. A primeira
contm a interface e a lgica da aplicao. A segunda classe
foi criada para tratar especificamente das conexes HTTP. A
aplicao faz uso de dois arquivos .jsp: recuperaPonto e recuperaPosicoes. A primeira pgina traz as informaes de nome,
descrio e imagem para um ponto especfico, j a segunda,

WebMobile Magazine - Criando um aplicativo LBS para consulta de pontos tursticos em cidades

Java M obile

por sua vez, traz os cdigos e as coordenadas (latitude e longitude) de todos os pontos tursticos cadastrados no banco de
dados JavaDB.
A tela inicial do aplicativo, mostrada na Figura 3, traz dois
campos de texto que informam a latitude e longitude, e dois
comandos: o primeiro (Iniciar) instancia as classes necessrias para o correto funcionamento da JSR 179, alm de iniciar
o listener que responde aos eventos de mudana de posio
do terminal. O comando Baixar Pontos acessa a pgina
recuperaPosicoes, recebendo todas as coordenadas dos pontos
cadastrados no servidor. Com isso, so criados os listeners de
proximidade aos pontos.

3. Sua nica funo atualizar os textos da tela principal


do aplicativo.
Listagem 3. Cdigo de atualizao das coordenadas no aplicativo
1. public void locationUpdated(LocationProvider provider,
Location location) {
2. iLatitude.setText(+ location.getQualifiedCoordinates().
s
getLatitude());
3. iLongitude.setText(+ location.getQualifiedCoordinates().
s
getLongitude());
4. }

O comando BaixarPontos tem dupla tarefa: a primeira buscar


os pontos tursticos cadastrados nos servidor e a segunda inserir o listener de proximidade em cada um deles. A Listagem
4 mostra a resposta da interao do usurio com o comando. A
linha 3 acessa o mtodo buscaPontos da classe AcessoHTTP. Depois que esta classe faz a requisio HTTP e analisa sua resposta,
os dados so guardados em instncias da classe Vector, que so
enviados ao mtodo recebePontos mostrado na Listagem 5.
Listagem 4. Resposta do commandAction ao Command cmPontos
1. else if (c == cmPontos)
2. {
3.
acessoHttp.buscaPontos( http://localhost:8084/
PontosHistoricos/recuperaPosicoes.jsp);
4. }

Figura 3. Tela principal do aplicativo mobile

Depois de fornecer uma viso geral do aplicativo, vamos


codificao. Ao escolher o comando Iniciar, iniciado uma
thread que chama o mtodo run apresentado na Listagem 2.
Listagem 2. Cdigo de inicializao dos componentes da JSR 179
1. public void run() {
2. try {
3. Criteria cr = new Criteria();
4. cr.setHorizontalAccuracy(200);
5. lp = LocationProvider.getInstance(cr);
6. lp.setLocationListener(this, -1, -1, -1);
7. } catch (LocationException ex) {
8. fmMain.append(No achou posio LE: +ex);
9. }
10. }

A linha 3 instancia um objeto Criteria, a linha seguinte


define a exatido horizontal das informaes especificadas
em 200 metros. A linha 5 instancia o objeto LocationProvider,
que como vimos anteriormente pode ser lembrada como
o corao da Java Location API. A seguir, adicionamos o
LocationListener sua instncia, fazendo com que a cada
atualizao de posio do terminal o mtodo locationUpdated
seja chamado. Sua implementao mostrada na Listagem

O mtodo recebePontos primeiramente armazena os trs vetores em variveis de instncia da sua classe (linhas 2, 3 e 4).
Posteriormente, analisa se a instncia de LocationProvider j foi
criada (linha 6), caso contrrio, inicia a thread que chama o
mtodo run mostrado na Listagem 2. A partir disso possvel
adicionar os listeners de proximidade. Para isso, necessrio chamar o mtodo addProximityListener, passando como
parmetro a instncia de uma classe que herde diretamente
de ProximityListener, uma instncia da classe Coordinates, que
recebe trs valores double, representando a latitude, longitude e
altitude do ponto a ser monitorado e, por fim, um valor float que
indica o raio que o listener deve considerar como aproximao.
No nosso exemplo, construamos uma cerca de 150 metros
de dimetro. Tudo isso feito na linha 15 da Listagem 4.
Listagem 5. Cdigo para procura de sensores
1. public void recebePontos(Vector vetCodigos, Vector
vetLatitudes, Vector vetLongitudes) {
2. his.vetCodigos = vetCodigos;
t
3. his.vetLatitudes = vetLatitudes;
t
4. his.vetLongitudes = vetLongitudes;
t
5.
6. f (lp == null)
i
7.
{
8. Thread t = new Thread(this);
9. t.start();
10. }
11.
12. for (int i = 0; i < vetLatitudes.size(); i++)
13. {
14. try {
15. lp.addProximityListener(this, new Coordinates(Double.
parseDouble(vetLatitudes.elementAt(i).toString()),
Double.parseDouble(vetLongitudes.elementAt(i).
toString()), 0), 150);
16. } catch (LocationException ex) {
17. fmMain.append(+ex);
18. break;
19. }
20. }
21. }

Edio 23 - WebMobile Magazine

25

Logicamente, no poderamos testar a captura de dados de


geolocalizao em um PC sem um receptor GPS ou alguma
outra tecnologia. Porm, a Sun Wireless Toolkit ou a Java ME
Platform SDK 3.0, ambas ferramentas da Sun Microsystems, permitem a emulao de dados geogrficos. A Figura 4 apresenta
a ferramenta External Event Generator, que pode ser acessado
da seguinte maneira:
Sun Wireless Toolkit: acessando o menu MIDlet External
events no aparelho celular emulado.
Java ME Platform SDK 3.0: acessando o menu View External
Events Generator no aparelho celular emulado.

Listagem 6. Arquivo XML de configurao de rota


1.
2.

<waypoints>

<waypoint time=1500 latitude=-23.532268 longitude=46.632334 altitude=310 />
3. . . .
4. waypoint time=1500 latitude=-23.535098 longitude=<
46.634624 altitude=310 />
5. </waypoints>

de 150 metros). Sendo assim, nosso aplicativo deve acusar esta


proximidade no final da rota.
Depois de baixar os pontos e executar o External Event Generator,
o aplicativo ir mostrar a tela ilustrada na Figura 5 no final da
rota. O alerta informa ao usurio que ele se aproxima de um ponto
histrico e verifica se o mesmo deseja obter mais informaes
sobre este ponto. Esta tela mostrada depois que o listener verifica
a proximidade e chama o mtodo proximityEvent (Listagem 7).

Figura 4. Simulando um trajeto com coordenadas de georeferenciamento


Figura 5. Tela de aviso de proximidade de ponto histrico

No External Event Generator, h duas possibilidades de utilizao: a primeira colocar os dados de latitude, longitude
e altitude diretamente nos campos, o que pode se tornar
maante se quisermos simular uma caminhada contendo
vrios pontos. A segunda maneira criando um arquivo
XML que define uma seqncia de pontos, que seguida
pela ferramenta. Este XML deve seguir o padro apresentado na Listagem 6. O tag root sempre ser waypoints, cada
coordenada deve ser especificada com a tag waypont. Na
Listagem 6 existem apenas duas coordenadas, porm, no
arquivo XML criado foram inseridas 14 pontos geogrficos.
Para utilizar este arquivo, basta clicar no boto Browse...
e selecionar o .xml criado. Depois disso, apenas clique no
boto de play e a rota comea a ser emulada.
Para conseguir criar um ambiente de testes para nosso
aplicativo, foi criado um arquivo .xml que gera uma rota comeando nas proximidades da estao da Luz, na cidade de
So Paulo. Suas ltimas coordenadas especificadas apontam
para posies geogrficas prximas estao da Luz (menos

26

O mtodo proximityEvent, por sua vez, recebe as coordenadas


do ponto que estava sendo monitorado e a localizao de onde
o terminal est. Sendo assim, o mtodo faz um lao entre todos
os elementos do vetLatitudes, verificando qual latitude confere
com a latitude da coordenada recebida. Quando encontrada,
significa que o ndice do vetLatitudes pode ser usado no vetCodigos para saber qual o cdigo do ponto turstico encontrado
(linha 6). A linha 7 mostra o alerta ao usurio.
Listagem 7. Detalhamento do mtodo proximityEvent
1. public void proximityEvent(Coordinates coordinates, Location
location){
2. for (int i = 0; i < vetLatitudes.size(); i++)
3.
{
4. if (vetLatitudes.elementAt(i).toString().equals(
+coordinates.getLatitude()))
5. {
6.
this.codigoEnc = vetCodigos.elementAt(i).toString();
7.
display.setCurrent(alAproximacao);
8. }
9.
}
10.}

WebMobile Magazine - Criando um aplicativo LBS para consulta de pontos tursticos em cidades

Java M obile

Perceba que na tela de aviso existem duas opes: Sim


e No. Ao escolher Sim, o usurio simplesmente direcionado para a tela principal do aplicativo, onde o aplicativo
chama o mtodo buscaInformacoes, como mostra a Listagem 8
nas primeiras quatro linhas.
Listagem 8. Cdigo que exibe as informaes de um ponto turstico no
display do aparelho celular
1.
2.
3.
4.
5.
6.
7.

else if (c == cmSim)
{
acessoHttp.buscaInformacoes(codigoEnc);
}

...
public void mostraDadosPonto(String nome, String texto,
byte[] img) {
8. iNome.setText(nome);
s
9. iDescricao.setText(texto);
s
10. imgPonto = Image.createImage(img, 0, img.length);
11.
12. fmDados.deleteAll();
13. fmDados.append(siNome);
14. fmDados.append(siDescricao);
15. fmDados.append(imgPonto);
16.
17. display.setCurrent(fmDados);
18. }

Depois que o mtodo busca as informaes no HTTP, a classe


AcessoHTTP chama o mtodo mostraDadosPonto (linha 7). O mtodo apenas configura os StringItems (linhas 8 e 9) e a ImageItem
(linha 10) da tela, em seguida, mostra o formulrio ao usurio,
na linha 17. O resultado pode ser visualizado na Figura 6.
Com isso conclumos a primeira etapa, onde foram apresentados o aplicativo do servidor e o aplicativo do dispositivo
mvel que possibilita a consulta de um ponto histrico cadastrado no servidor ao se aproximar fisicamente dele.

Concluso
Neste artigo foi possvel verificar como simples utilizar
a Java Location API. Porm, apesar de sua facilidade, seu
poder imenso. Assim como criamos um aplicativo Mobile
Learning para mostrar a aproximao de pontos histricos,
poderamos ter criado um aplicativo para mostrar pontos de
interesse para o usurio, seguindo a mesma idia e a mesma
estrutura utilizada neste artigo.
Alm disso, o uso de sistemas LBS est crescendo e as projees so de que este crescimento s aumente no decorrer
dos prximos anos. A requisio de aplicativos desse porte

Figura 6. Tela que apresenta as informaes do ponto turstico

acompanhar este fluxo, cabendo a voc, desenvolvedor,


suprir as necessidades que sero criadas no mercado.
O prximo artigo desta srie adicionar a funcionalidade de captura de pontos tursticos atravs do telefone celular, enriquecendo
o aplicativo e o conhecimento que o leitor ir adquirir.

Links
Documentao da Java Location API
http://jcp.org/en/jsr/detail?id=179
Tutoriais, artigos e vdeo aulas sobre JME
www.devmedia.com.br

D seu feedback sobre esta edio!


A Web Mobile tem que ser feita ao seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/webmobile/feedback

Edio 23 - WebMobile Magazine

27

28

WebMobile Magazine - Criando um aplicativo LBS para consulta de pontos tursticos em cidades

Java M obile

Edio 23 - WebMobile Magazine

29

Conferindo o tempo
com Android

De que se trata o artigo


Comunicao com web services fazendo uso da plataforma aberta Android.
Para que serve
Desenvolver aplicaes Android para sistemas distribudos, aproveitandose da caracterstica de interoperabilidade de web services de forma a economizar banda e processamento.
Em que situao o tema til
Quando se deseja integrar uma aplicao Android a um servio web j existente. Mais especificamente neste artigo, servios web RESTful que utilizam
JSON como formato de troca de informaes.

Cezar Augustus Signori


cezarsignori@gmail.com

desenvolvedor de solues de alta tecnologia na Tibox Innovations e Ekolivre


TI. Bacharelando em Cincias da Computao na UFSC. Fundador e administrador da comunidade Android brasileira, android-br.mobi. Mantm um blog
em http://cezarsignori.wordpress.com.

30

WebMobile Magazine - Conferindo o tempo com Android

eb services tem sido a maneira mais adotada na


indstria para integrar suas aplicaes com novos
partners, fornecer servios poderosos aos consumidores e garantir interoperabilidade entre seus sistemas
distribudos ao mesmo tempo em que novas funcionalidades
so liberadas.
Neste artigo voc vai descobrir como acessar e utilizar estes
servios com Android.

Por onde comear?


A primeira deciso a ser tomada escolher um estilo de arquitetura de software, ou seja, um conjunto de regras de design
que identificam os tipos de componentes a serem utilizados
para compor nosso sistema.
Visto que estamos trabalhando com web services e no podemos esquecer que nosso client ser um dispositivo mvel com
limitaes de memria, processamento e energia, escolhemos o
uso de web services RESTful (REpresentational State Transfer)
- um design que abraa uma arquitetura cliente-servidor sem
estado, em que os servios web so encarados como recursos
e podem ser identificados por suas URLs (ler Nota DevMan
1). Os clientes deste servio devem acessar uma representao
particular do recurso que desejam, transferindo o contedo de
um conjunto de mtodos remotos definidos globalmente, que
descrevem uma ao a ser realizada sobre o recurso.
A nossa principal vantagem no ponto de vista de cliente do
servio que o uso de RESTful implica num menor uso de
banda, pois o uso de um protocolo SOAP exigiria um custo
muito alto devido ao seus headers, camadas adicionais de

ANDROID

elementos SOAP e a interpretao do XML.


Ento, por motivos de processamento e banda, escolhemos
JSON (JavaScript Object Notation) como nosso formato de troca
de mensagens - alm da leveza, JSON nos oferece a interpretao instantnea da mensagem como cdigo javascript pelo
browser, caso este seja utilizado (ler Nota DevMan 2).

Definindo um objetivo
Visto que nosso objetivo efetuar a comunicao com um web
service, nada melhor do que utilizar um existente ao invs de
criarmos uma aplicao ponta-a-ponta, afinal no queremos
perder o foco.
A sugesto desenvolver um aplicativo a ser chamado de
ClimaTempo, capaz de nos informar como est o tempo em
uma dada localidade.
Felizmente existe um servio no GeoCities que torna disponvel estas informaes, atravs de uma srie de centrais de
observao do tempo e clima dispostos pelo mundo, bastando
informar a latitude e longetude (as quais podem ser obtidas
atravs do GPS do Android, ou Google Maps) ou ainda o
cdigo internacional dos aeroportos (ICAO Internacional
Civil Aviation Organization). Este ltimo servio (que faz
uso do ICAO) nos retorna informaes como temperatura,
velocidade e direo do vento, horrio da observao e nome
da central, e por bvio est limitado cidades que possuem
um aeroporto.
Vamos comear pelo caso mais simples, onde definimos uma
cidade padro, fazemos a chamada ao servio web - enviando
o ICAO - e tratamos a resposta para exibir convenientemente
ao usurio.

Nota do DevMan 1
JSON
JSON (JavaScript Object Notation) um formato leve de troca de dados. Um formato de texto completamente independente de linguagem que faz uso de convenes
familiares aos programadores de linguagens da famlia C (C, C++, Java, Javascript..).

Nota do DevMan 2
REST
REST uma descrio analtica de arquiteturas web existentes, e assim, a interrelao entre o estilo e protocolo HTTP subjacente aparece de forma transparente.

Alm do acesso a internet, nossa aplicao possuir uma nica tela onde o usurio poder verificar a temperatura, o tipo de
nvens no cu (com direito a imagem), a velocidade do vento, a
data e hora da observao de tais informaes no observatrio
escolhido. Esta tela pode ser visualizada na Figura 1.

Desenvolvendo o ClimaTempo
Uma boa forma de se iniciar um projeto pequeno definir e
delimitar suas funcionalidades.
J sabido que estaremos trabalhando com um servio web.
Por este motivo, precisamos de permisso de acesso internet,
o que no Android feito via AndroidManifest. A Listagem 1
nos apresenta na linha 6 uma forma de especificar o uso desta
permisso. O restante do arquivo como um AndroidManifest
qualquer, que define sua nica atividade nas linhas 7 15.
Listagem 1. AndroidManifest.xml
01.<?xml version=1.0 encoding=utf-8?>
02.<manifest xmlns:android=http://schemas.android.com/apk/res/
android
03.
package=webmobile.android.climatempo
04.
android:versionCode=1
05.
android:versionName=1.0.0>
06.
<uses-permission android:name=android.permission.INTERNET />
07.
<application android:icon=@drawable/icon
08.
android:label=@string/app_name>
09.
<activity android:name=.ClimaTempo
10.
android:label=@string/app_name>
11.
<intent-filter>
12.
<action android:name=android.intent.action.
MAIN />
13.
<category android:name=android.intent.
category.LAUNCHER />
14.
</intent-filter>
15.
</activity>
16.
</application>
17.</manifest>

Figura 1. Atividade ClimaTempo, exibindo informaes do tempo

H pouco foi comentado que deve ser escolhida uma cidade


para a verificao do tempo, afinal precisamos coletar dados
de um observatrio bem definido, visto que no temos uma
base de dados por trs da aplicao para armazenar os cdigos
ICAO dos aeroportos. Define-se ento para fins de execuo
do projeto, a cidade de Florianpolis. Caso voc prefira testar
a aplicao verificando o clima da sua cidade, basta procurar
pelo cdigo ICAO do aeroporto mais prximo. Esta informao
pode ser encontrada na Wikipdia.
Com a imagem da Figura 1 em mente, podemos iniciar o
desenvolvimento da interface. Nota-se pela figura que no se
faz necessrio nenhum componente visual que no seja um
TextView ou um ImageSwitcher. A Listagem 2 define a distribuio destes componentes em tela. Note que nem todos os
componentes especificados sero necessariamente utilizados
pela aplicao, muitos esto presentes apenas para obtermos
um visual inteligvel.

Edio 23 - WebMobile Magazine

31

Listagem 2. main.xml
01. <?xml version=1.0 encoding=utf-8?>
02.
<AbsoluteLayout
03.
android:id=@+id/widget0
04.
android:layout_width=fill_parent
05.
android:layout_height=fill_parent
06.
xmlns:android=http://schemas.android.com/apk/res/android>
07. TextView
<
08.
android:id=@+id/lblTemperatura

09. ndroid:layout_width=66px
a
10. ndroid:layout_height=59px
a
11. ndroid:text=19
a
12. ndroid:textSize=40sp
a
13. ndroid:typeface=serif
a
14. ndroid:layout_x=170px
a
15. ndroid:layout_y=2px/>
a
16. TextView
<
17. ndroid:id=@+id/lblData
a
18. ndroid:layout_width=138px
a
19. ndroid:layout_height=27px
a
20. ndroid:text=05/10/2008
a
21. ndroid:layout_x=176px
a
22. ndroid:layout_y=120px/>
a
23. TextView
<
24. ndroid:id=@+id/txtGrau
a
25. ndroid:layout_width=wrap_content
a
26. ndroid:layout_height=wrap_content
a
27. ndroid:text=o
a
28. ndroid:layout_x=236px
a
29. ndroid:layout_y=5px/>
a
30. TextView
<
31. ndroid:id=@+id/lblNuvens
a

32. ndroid:layout_width=wrap_content
a
33. ndroid:layout_height=wrap_content
a
34. ndroid:text=Nvens Esparsas
a
35. ndroid:layout_x=175px
a
36. ndroid:layout_y=65px/>
a
37. ImageSwitcher
<
38. ndroid:id=@+id/imgTempo
a
39. ndroid:layout_width=153px
a
40. ndroid:layout_height=127px
a
41. ndroid:layout_x=6px
a
42. ndroid:layout_y=7px/>
a
43. TextView
<
44. ndroid:id=@+id/lblVento
a
45. ndroid:layout_width=wrap_content
a
46. ndroid:layout_height=wrap_content
a
47. ndroid:text=Vento: 150km/h
a
48. ndroid:layout_x=176px
a
49. ndroid:layout_y=93px/>
a
50. TextView
<
51. ndroid:id=@+id/txtCelsius
a
52. ndroid:layout_width=wrap_content
a
53. ndroid:layout_height=42px
a
54. ndroid:text=C
a
55. ndroid:textSize=24sp
a
56. ndroid:textStyle=bold
a
57. ndroid:layout_x=249px
a
58. ndroid:layout_y=7px/>
a
59. /TextView>
<
60.</AbsoluteLayout>

Listagem 3. ClimaTempo.java
01. public class ClimaTempo extends Activity {
02. rivate ImageSwitcher imgTempo;
p
03. rivate TextView lblTemperatura;
p
04. rivate TextView lblData;
p
05. rivate TextView lblVento;
p
06. rivate TextView lblNuvens;
p
07.
08.
/** Called when the activity is first created. */
09.
@Override
10.
public void onCreate(Bundle savedInstanceState) {
11.
super.onCreate(savedInstanceState);
12.
setContentView(R.layout.main);
13.
14.
imgTempo = (ImageSwitcher) findViewById(R.id.imgTempo);
15.
lblTemperatura = (TextView) findViewById(R.id.lblTemperatura);
16.
lblData
= (TextView) findViewById(R.id.lblData);
17.
lblVento = (TextView) findViewById(R.id.lblVento);
18.
lblNuvens = (TextView) findViewById(R.id.lblNuvens);
19.
20.
atualizar();

Uma vez definida a tela principal, pode-se iniciar o desenvolvimento da atividade que a compreende. Vamos comear a
editar a classe ClimaTempo de forma a dar vida aplicao.
A Listagem 3 define tal atividade realizando a vinculao
dos campos de texto onde sero exibidas as informaes de
temperatura, velocidade do vento, tipo de nvens, data e hora.
Alm do ImageSwitcher que estar ilustrando o tempo, com
base no tipo de nvem. Toda essa vinculao pode ser visualizada nas linhas 14 18. Logo em seguida, nas linhas 23 38,
instanciamos uma Estao, a qual nos fornece uma Observao do tempo. Esta Observao utilizada para alimentar os
componentes em tela, atualizando a interface.
Uma Observao no ClimaTempo no passa de um POJO
(Plain Old Java Object), ou seja um objeto Java comum, com
as propriedades e acessores utilizados pela Listagem 3. J a
Estao, uma classe que vale a pena ser abordada, pois ela
responsvel pela conexo com o web service e tratamento da
resposta. Por bvio, estas responsabilidades sero distribudas
entre duas outras classes, para melhor compreenso do que se
passa no processo de comunicao com o servio web.

32

WebMobile Magazine - Conferindo o tempo com Android

21.
}
22.
23.
public void atualizar(){
24.
Observacao tempo;
25.
try {
26.
tempo = new Estacao(SBFL).getTempo();
27.
lblTemperatura.setText(tempo.getTemperatura());
28.
lblData.setText(tempo.getHorario());
29.
lblVento.setText(Vento: + tempo.getVelocidadeDoVento()
30.

+ km/h);
31.
imgTempo.setBackgroundResource(

32.

ImagensDeNuvem.getImagem(tempo.getNuvens()));
33.
lblNuvens.setText(tempo.getNuvens());
34. } catch (InformacoesIndisponiveis e) {
35. TODO Auto-generated catch block
//
36.
e.printStackTrace();
37. }
38.
}
39. }

A Listagem 4 define a classe Estacao. importante notar como


est sendo utilizada a URL do servio e como ela est sendo
montada. Tambm perceptvel a facilidade desta etapa, onde
no h segredo algum, apenas se concatena a URL do servio
ao parmetro fornecido no construtor (ICAO). Esta nova URL
fornecida a um objeto da classe Proxy, que trata da conexo
e recebimento da resposta, enquanto um objeto TratadorJSON
cuida da interpretao da mesma, alimentando o objeto Observacao que foi utilizado pela atividade ClimaTempo. Em caso de
erro no processo por indisponibilidade do servio, por exemplo,
jogada uma exceo de InformacoesIndisponiveis.
Chegou o momento de discutir sobre o servio e sua resposta,
para ento continuarmos o desenvolvimento da aplicao sem
esbarrar em possveis dvidas.
Na qualidade de um servio RESTful, para se obter a resposta
esperada basta realizar uma requisio HTTP GET, enviando
os parmetros necessrios neste caso apenas o ICAO e
tratar a resposta.
No Android, este tipo de requisio pode ser realizado atravs da API HTTP da Apache disponvel sobre o pacote org.

ANDROID

Listagem 4. Estacao.java
01. public class Estacao{
02. private String icao;
03.
04. public Estacao(String icao){
05. this.icao = icao;
06. }
07.
08. public Observacao getTempo() throws InformacoesIndisponiveis{
09. Observacao tempo = null;
10. Proxy proxy = null;
11. try {
12. proxy = new Proxy(http://ws.geonames.org/weatherIcaoJSON?
13.
+ ICAO= + this.icao);
14. tempo = new TratadorJSON().tratar(proxy.conectar());
15. } catch (Exception e) {
16. throw new InformacoesIndisponiveis();
17. } finally {
18. proxy.encerrar();
19. proxy = null;

20. }
21. return tempo;
22. }
23.}

apache.http a qual compreende as interfaces e classes core de


componentes HTTP. Estes lidam com os aspectos fundamentais
requeridos para o uso do protocolo HTTP, como a representao
da mensagem, incluindo seus headers e possveis entidades, alm
das conexes sobre as quais estas mensagens so enviadas. Para
preparar as mensagens antes do envio ou depois do recebimento,
esta API fornece interceptadores para requisies e repostas.
Portanto, a comunicao com o web service no passa de
uma abertura de conexo, a execuo de uma requisio GET
e da obteno da resposta, que para ns a entidade HTTP da
mensagem. Tudo isto feito utilizando-se da API da Apache
e algumas implementaes do Android. Mas antes de tratar
deste assunto, conveniente fazer alguns comentrios sobre
esta entidade, afinal ela quem ser interpretada para a obteno dos dados pertinentes.
Esta entidade uma entidade HTTP definida pela interface org.apache.http.HttpEntity - , que pode ser recebida ou
enviada numa mensagem HTTP. Em alguns lugares, o JavaDoc
distingue estas entidades em trs tipos, dependendo de onde
seu contedo se origina. Caso o contedo seja recebido de um
stream ou gerado on-the-fly, classificada como Streamed. Em
particular, esta categoria inclui entidades recebidas de uma
conexo, ou seja, o caso do ClimaTempo.
Mas estas entidades ainda podem ser Self-Contained, ou
seja, o contedo est disponvel na memria ou foi obtido de
forma independente de uma conexo ou de outra entidade.
Esta classificao abre espao para uma terceira, aquelas que
se originam de outra entidade, as entidades de Wrapping.
Toda esta distino importante para o gerenciamento de
conexo com entidades envolvidas. Para aquelas criadas pela
aplicao e somente enviadas via o framework de componentes
HTTP da Apache, a diferena entre entidades Streamed e SelfContained de pouca importncia. Neste caso, sugerido considerar entidades que no possam produzir seu contedo mais de
uma vez, como Streamed e as demais como Self-Contained.
Felizmente todo este trabalho feito pela API, de forma que
se torna transparente o manejo da conexo e da resposta.
A Listagem 5 especifica a classe Proxy, que abre a conexo,

realiza a requisio e retorna quando solicitada a to discutida


entidade HTTP. importante notar que no seriam muitas as
modificaes nesta classe para a utilizao de servios SOAP,
bastando apenas modificar o mtodo da requisio para POST
e enviar junto a esta o envelope XML com o cdigo ICAO.
Listagem 5. Proxy.java
01. public class Proxy {

02. private HttpClient client;
03. private HttpGet get;
04.
05. public Proxy(String url){

06. this.client = new DefaultHttpClient();
07. this.get = new HttpGet(url);
08. }
09.
10. public HttpEntity conectar() throws ClientProtocolException,
11.
IOException{
12. return client.execute(get).getEntity();

13. }
14.
15. public void encerrar(){
16. this.get.abort();

17. }
18. }

Tratando a resposta
A parte importante da resposta recebida pelo proxy a
entidade HTTP. Esta entidade possui um valor no formato
JSON que pode ser encarado como uma String e exatamente
o que faremos para obter um objeto de consulta.
A Listagem 6 contm um exemplo de retorno proveniente
do servio, obtido atravs de uma requisio direta de um navegador web qualquer. Antes de mais nada vamos analis-lo.
primeira vista, nota-se que a resposta possui uma rea til,
descrita por uma propriedade chamada weatherObservation.
Esta propriedade poderia ser encarada como um objeto cujas
propriedades so as informaes que desejamos exibir ao
usurio sim, temos muito mais informao disponvel do
que o ClimaTempo atualmente utiliza.
Embora seja extremamente fcil desenvolver um interpretador para mensagens como esta, vamos utilizar a API JSON
(disponvel para download no SourceForge), a qual foi criada
para este fim e desempenha seu papel muito bem.
Uma das formas de se criar um objeto JSON fornecer
uma String ao seu construtor, da a API se encarregar de
interpretar a mensagem (String da entidade) e montar uma
estrutura equivalente de objetos JSON, de forma a facilitar o
acesso aos dados da mesma.
Na Listagem 7 est definido um tratador JSON, que ao
receber uma entidade HTTP obtm seu valor no formato de
texto JSON, convertendo esta mensagem num JSONObject.
Este objeto por sua vez - representa o que seria o envelope na
arquitetura SOAP -, possui uma nica propriedade chamada
weatherObservation, de onde obtemos as demais informaes
utilizando mtodos prticos da API para construir o objeto
Observacao, a ser retornado at a atividade ClimaTempo,
fechando o clico de vida da nossa aplicao.
Note o uso de Strategy Pattern nesta classe. O motivo para isto,
num exemplo to simples, que bastaria modificar o contedo do
mtodo tratar para interpretar XML (utilizando SAX, por exemplo)
ao invs de texto JSON, para atender a um servio SOAP.

Edio 23 - WebMobile Magazine

33

Listagem 6. WeatherIcaoJSON
01. {
02. weatherObservation:{
03. clouds:scattered clouds,
04. weatherCondition:n/a,
05. observation:SBFL 011700Z 35015KT 9999 SCT030 BKN045
23/15 Q1017,
06. windDirection:350,
07. ICAO:SBFL,
08. elevation:5,
09. countryCode:BR,
10. lng:-48.5333333333333,
11. temperature:23,
12. dewPoint:15,
13. windSpeed:15,
14. humidity:60,
15. stationName:Florianopolis Aeroporto ,
16. datetime:2008-11-01 17:00:00,
17. lat:-27.6666666666667,
18. hectoPascAltimeter:1017
19. }
20.}

Listagem 7. TratadorJSON
01. public class TratadorJSON implements TratadorResposta<Observacao> {
02.
03. public Observacao tratar(HttpEntity resposta) throws Exception {
04. JSONObject envelope = new JSONObject(
05. EntityUtils.toString(resposta));
06.
07. JSONObject observacao = envelope
08. .getJSONObject(weatherObservation);
09.
10. Observacao tempo = new Observacao();
11. tempo.setNuvens(observacao.getString(clouds));
12. tempo.setTemperatura(observacao.getString(temperature));
13. tempo.setHorario(observacao.getString(datetime));
14. tempo.setVelocidadeDoVento(observacao.getString(windSpeed));
15.
16. return tempo;
17. }
18.}

Tambm explicamos que tipo de arquitetura geralmente


adotada no mundo mobile, devido s questes de banda e de
processamento, e que embora o Android tenha atributos de
hardware notveis, devemos utilizar tcnicas de otimizao
de banda e processamento para liberar recursos para outras
atividades mais complexas.

O que vem depois?


Todos os pontos aqui abordados esto em discusso nas
comunidades brasileiras e internacionais. Qualquer dvida
relativa plataforma Android, bem como ao desenvolvimento de aplicaes distribudas sobre a plataforma, podem ser
encontradas nestas comunidades. Alm das resolues, elas
ainda dispem da documentao necessria para desenvolver
de aplicaes Android. Os endereos destas comunidades esto
dispostos no quadro Referncias.
Referncias
http://android-br.mobi
Comunidade lusfona (em portugus) dedicada ao sistema operacional mvel Android. Conta
com fruns direcionados ao desenvolvimento, segurana, questes da plataforma, discusses e
notcias, alm de grupos especializados, blogs de usurios e compartilhamento de vdeos.
http://groups.google.com/group/android-developers
Android Developers Group o grupo oficial da Google para discusso sobre o desenvolvimento
de aplicaes Android (em ingls).

Concluses

D seu feedback sobre esta edio!

O uso de web services uma prtica constante no mundo


empresarial, por possibilitar fcil integrao entre sistemas
novos ou j existentes. Vimos que a comunicao com estes
servios na plataforma Android so de fcil desenvolvimento
e de alto desempenho.

A Web Mobile tem que ser feita ao seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!

34

WebMobile Magazine - Conferindo o tempo com Android

D seu voto sobre este artigo, atravs do link:


www.devmedia.com.br/webmobile/feedback

Utilizando Web Services


no Google Android

De que se trata o artigo


Utilizao de um Web Service para consulta de CEPs na plataforma Android e integrao com Google Maps para dar mais expressividade grfica a aplicaes mashups.
Para que serve
Por meio da aplicao exemplo utilizada, demonstrar passo a passo como consumir Web Services em Android usando bibliotecas adicionais, como o caso do KSOAP2, aproveitando a vantagem de se utilizar mapas para mostrar a localizao.
Em que situao o tema til
Consultar as informaes referentes ao CEP informado (por exemplo, endereo, cidade, estado, etc), tendo a facilidade de visualizar esta localizao no
mapa por meio da API de Mapas em Android e do componente ItemizedOverlay, para construes de novas camadas para sobrepor MapViews.

Ramon Ribeiro Rabello


ramon.rabello@gmail.com

graduado em Cincia da Computao pela Universidade da Amaznia (UNAMA). Trabalha com a tecnologia Java desde 2005. Possui experincia nas trs
especificaes: JSE, JEE e JME. Trabalhou com desenvolvimento de aplicaes
mveis comerciais (M-Commerce / M-Payment). um dos evangelistas de
Android no Brasil, promovendo o uso da plataforma em cursos e palestras.
Atualmente mestrando da Universidade Federal de Pernambuco (UFPE)
na rea de Engenharia de Software, mais especificamente em Model-Driven
Architecture (Arquitetura Dirigida a Modelos) e um dos membros do projeto
ORCAS (www.orcas.eu).

muito que os Web Services vm sendo utilizados


em aplicaes comerciais para resolver acima de
tudo o problema da Babel dos sistemas, permitindo que vrios sistemas escritos em linguagens distintas se
comuniquem por meio de servios (mtodos) que so expostos
para que outros mdulos ou sistemas possam acess-los. Para
isso, a tecnologia XML associada ao protocolo SOAP so os
protagonistas deste cenrio. Ela utilizada como canal comum
de comunicao e juntos constituem a arquitetura SOA (Service
Oriented Architecture Arquitetura Orientada Servio).
Provado o sucesso destes no universo das tecnologias do
lado do servidor (como PHP, JSP, JSF, etc), to logo a tecnologia
tornou-se disponvel para o mundo ubquo por meio de implementao do protocolo SOAP para as vrias linguagens de
programao mvel (dentre elas, a plataforma Android).
Porm, a tecnologia teve que ser enxugada devido a caractersticas intrnsecas aos Web Services. Por exemplo, permitir
trabalhar com estruturas de dados mais complexas, manipular
vrias linhas retornadas no XML de resposta a um servio,
carregar uma hierarquia de rvore era quase invivel devido
s capacidades restritas dos dispositivos mveis referentes capacidade de processamento e espao de memria reduzido.
Este artigo demonstrar passo a passo como se acessar um
Web Service utilizando a biblioteca KSOAP2 em Android.
Para isso, ser criada uma aplicao que acessa um Web
Service pblico disponvel em www.maniezo.com.br que ser
utilizado para consultar o CEP de determinada localidade e
retorna informaes adicionais, mostrando tambm a localizao correspondente deste CEP no mapa usando o Google
Android Maps.
Na poca da escrita deste artigo, foram utilizados a IDE
Eclipse 3.4 (codinome Ganymede, disponvel em www.eclipse.
org/ganymede/) juntamente com o plug-in para desenvolvimento
de Android no Eclipse chamado ADT (Android Development
Tools) e a verso 1.0 Release 2 (r2) do SDK para Windows (http://

Edio 23 - WebMobile Magazine

35

code.google.com/android/download.html). Ateno: muito cuidado


para baixar a verso do SDK compatvel com a verso do plugin ADT, caso contrrio poder gerar erros indesejveis em sua
aplicao (ler Nota DevMan 1)!

Construindo a GUI da aplicao


Nossa aplicao ser utilizada para buscar informaes de
determinada localidade de acordo com o CEP informado,
sendo que essa busca ser feita por meio do acesso a um Web
Service. Ela ser muito til para sabermos mais informaes
das mais variadas localidades do Brasil (por enquanto, ficamos apenas com a implementao via emulador e esperamos
ansiosamente para que o G1 atualmente algum dispositivo
com a plataforma Android chegue logo no Brasil!). A aplicao
ainda mostra a localidade especfica deste CEP no mapa de
acordo com sua latitude/longitude.
Como ponto de partida para qualquer desenvolvimento de
uma aplicao, criaremos um novo projeto Android. A Figura
1 mostra as configuraes (nome do projeto, da Activity, etc)
que foram utilizadas para este projeto.
A aplicao bem simples e composta essencialmente de
TextViews para visualizar textos, um EditText para entrada de texto (no nosso caso o CEP), um ImageButton para disparar eventos
de cliques; e um MapView, que representa o mapa renderizado
pelo Google Maps que exibir a localizao exata deste CEP.
LinearLayout o layout padro utilizado por todos os widgets. Dentro do primeiro layout percebemos a utilizao de
um ViewFlipper, que uma das novidades na plataforma que
une o conceito de animao (um outro tipo de recurso em
Android) para ser aplicada s Views. Este componente ser
utilizado para animar os TextViews que informam como se
utilizar nosso buscador, como numa espcie de letreiro digital
que ficar sendo exibido continuamente no topo e no centro
da tela do dispositivo, com o efeito de aparecimento (fade in,
referente ao atributo android:fromAlpha=0.0 que significa
totalmente opaco) e desaparecimento (fade out, referente
ao atributo android:toAlpha=1.0 que significa totalmente
transparente), com durao da animao de 100 milisegundos
(android:duration=100), utilizando o efeito de acelerao
(atributo android:interpolator), referenciado por meio de @
anim:accelerate_interpolator em fade.xml (Listagem 1), que
est em res/anim, diretrio padro para Android carregar recursos de animao. Ainda na tag <ViewFlipper>, encontramos
o atributo android:flipInterval=2000 informando que cada
View ter a durao de 2 segundos (2000 milisegundos) para
ser exibido na tela. O atributo android:padding diz respeito ao
espaamento entre o filho e o pai que, nesse caso, vai ser 10 pixels
igualmente em todos os lados: cima, baixo, esquerda e direita.
Seguindo, temos um outro LinearLayout na direo horizontal que contm um TextView com o texto CEP: (referenciado
por @string/cep_desc), o EditText para entrada do CEP (@+id/
etCEP) e um ImageButton (@+id/imgBtnPesquisar) que possui
as mesmas funcionalidades do Button, exceto que em vez de um
texto, uma imagem mostrada (no nosso caso uma imagem de
uma lupa por meio da referncia @drawable/search).

36

WebMobile Magazine - Utilizando Web Services no Google Android

Nota do DevMan 1
Compatibilidade entre verses do SDK
Um dos maiores problemas que estamos enfrentamos durante o desenvolvimento
de uma aplicao em Android talvez seja este bombardeio de verses de releases
do SDK que a plataforma tem sofrido durante este perodo de amadurecimento do
Google Android, o que implicou severamente na parcial incompatibilidade entre as
aplicaes desenvolvidas em verses diferentes. Elas eram desenvolvidas em uma
verso e quase sempre sofriam ajustes (renomeaes de APIs, remoo de classes,
etc) para que fosse possvel rod-la na verso mais recente.
Alm disso, existe uma correspondncia entre a verso de um SDK e a verso do
plug-in ADT. Por exemplo, o SDK 1.0 Release 2 (verso mais atual disponvel durante
a escrita deste artigo) requer a verso 0.8.0 do plug-in Eclipse ADT para que o desenvolvimento de aplicaes funcione corretamente.
Sendo assim, tenha em mente esta caracterstica quando estiver desenvolvendo,
adaptando ou migrando aplicaes em Android que foram construdas utilizando
verses de SDKs diferentes. Para baixar a ltima verso do SDK acesse http://code.
google.com/intl/pt-BR/android/download.html. Para mais informaes de como
instalar/atualizar o plug-in Eclipse ADT acesse http://code.google.com/intl/pt-BR/
android/intro/installing.html#installingplugin.

Listagem 1. fade.xml
<?xml version=1.0 encoding=utf-8?>
<alpha xmlns:android=http://schemas.android.com/apk/res/android
android:interpolator=@android:anim/accelerate_interpolator
android:fromAlpha=0.0 android:toAlpha=1.0
android:duration=100 />

Logo abaixo, temos tambm um LinearLayout que contm os


TextViews que mostraro as informaes da localidade do CEP
informado. Essas informaes sero preenchidas no momento
que a busca for realizada com sucesso. Essas informaes so
respectivamente: o Estado (@+id/tvEstado), a Cidade (@+id/
tvCidade), o Bairro (@+id/tvBairro), o tipo do logradouro
(@+id/tvTipoLogradouro), o Logradouro (@+id/tvLogradouro)
e Complemento (@+id/tvComplemento). A Listagem 2 mostra
o arquivo main.xml que representa a GUI da aplicao.
Logo abaixo temos um RelativeLayout que contm um
MapView que exibir a localizao exata (latitude/longitude)
de acordo com o CEP fornecido; e um LinearLayout que ser
utilizado para adicionarmos um controle de zoom em nosso
mapa. Um detalhe muito importante: a partir da verso 0.9 do
SDK da plataforma, para que possamos utilizar MapViews
obrigatrio assinarmos, por meio de uma chave privada, a
aplicao e adicionarmos umas tags especficas no AndroidManifest.xml, caso contrrio sua aplicao ir abortar quando
estiver prestes a ser executada.

Incrementando a Activity
Aqui vai um lembrete essencial: pelo fato de mostrarmos um
mapa em nossa Activity, devemos em vez de estender simplesmente Activity (criado por padro), alteramos para WSCepActivity herdar de MapActivity (ler Nota DevMan 2), haja vista
que este tipo de Activity j possui funcionalidades (threads)

ANDROID

Listagem 2.main.xml
<?xml version=1.0 encoding=utf-8?>
<LinearLayout xmlns:android=http://schemas.android.com/apk/res/android
a
ndroid:orientation=vertical android:layout_width=wrap_content
a
ndroid:layout_height=wrap_content android:id=@+id/rootLayout>

<ViewFlipper android:id=@+id/flipper

android:layout_width=fill_parent android:layout_

height=wrap_content
android:flipInterval=2000 android:padding=10px>

<TextView android:layout_width=fill_parent

a
ndroid:layout_height=wrap_content
android:gravity=center_horizontal
a
ndroid:textSize=16px android:text=Entre com o CEP, />

<TextView android:layout_width=fill_parent

a
ndroid:layout_height=wrap_content
android:gravity=center_horizontal
android:textSize=16px android:text=clique na lupa
ao lado ou />

<TextView android:layout_width=fill_parent

a
ndroid:layout_height=wrap_content
android:gravity=center_horizontal

a
ndroid:textSize=16px android:text=pressione ENTER />
</ViewFlipper>

<LinearLayout android:orientation=horizontal

android:layout_width=wrap_content android:layout_

height=wrap_content>
<TextView android:id=@+id/tvCepDesc android:layout_
width=wrap_content
android:layout_height=wrap_content android:text=@

string/cep_desc />
<EditText android:id=@+id/etCEP android:layout_

width=240px
a
ndroid:hint=Digite o CEP android:layout_height=wrap_
content />
<ImageButton android:id=@+id/imgBtnPesquisar

android:layout_width=wrap_content android:layout_

height=wrap_content
android:src=@drawable/search />

</LinearLayout>

<LinearLayout android:orientation=vertical

android:layout_width=fill_parent android:layout_

height=wrap_content>
<
TextView android:id=@+id/tvEstado android:layout_
width=wrap_content

implementadas para trabalhar com mapas, implementar um


cache de nveis dos mapas, acessar arquivos em disco, etc.
Comeando o desenvolvimento de nossa MapActivity (ver
Listagem 3), temos inicialmente o mtodo onCreate() que
chamado no momento da criao de qualquer Activity. Dentro
dele, chamamos o mtodo onCreate() da superclasse e o mtodo
setContentView() carrega toda a GUI definida em main.xml
por meio da referncia R.layout.main. Depois, recuperamos
em forma de classes os widgets definidos em main.xml por
meio do mtodo findViewById() passando o inteiro que cada
um representa na classe de recursos R.java.
Depois, utilizamos a classe utilitria AnimationUtils e o mtodo
loadAnimation() para carregar os efeitos j pr-definidos em Android, que no nosso caso ser de aparecimento (android.R.anim.
fade_in) e desaparecimento (disponvel em android.R.anim.
fade_out) dos TextViews que sero manipulados por <ViewFlipper> (varivel flipper). Configuramos o efeito de aparecimento
em setInAnimation() e desaparecimento em setOutAnimation(),
passando respectivamente os objetos Animations (variveis in e
out), retornados pelo mtodo loadAnimation(). Por fim, chamamos flipper.startFlipping() para iniciarmos a animao.

android:textSize=12px android:layout_height=wrap_

content

android:text=@string/estado />

<TextView android:id=@+id/tvCidade android:layout_
width=wrap_content

android:textSize=12px android:layout_height=wrap_content

android:text=@string/cidade />

<TextView android:id=@+id/tvBairro android:layout_
width=wrap_content

android:textSize=12px android:layout_height=wrap_content

android:text=@string/bairro />

<TextView android:id=@+id/tvTipoLogradouro

android:layout_width=wrap_content
android:textSize=12px

android:layout_height=wrap_content android:text=@
string/tipo_logradouro />

<TextView android:id=@+id/tvLogradouro

android:layout_width=wrap_content
android:textSize=12px

android:layout_height=wrap_content android:text=@
string/logradouro />

<TextView android:id=@+id/tvComplemento

android:layout_width=wrap_content
android:textSize=12px

android:layout_height=wrap_content android:text=@
string/complemento />
<
/LinearLayout>
<
RelativeLayout xmlns:android=http://schemas.android.com/apk/res/
android

android:layout_width=fill_parent android:layout_
height=fill_parent>

<com.google.android.maps.MapView

android:id=@+id/map android:layout_width=fill_parent

android:layout_height=fill_parent android:apiKey={api_
key_gerada}

android:clickable=true />
<LinearLayout android:id=@+id/map_zoom

android:layout_width=wrap_content android:layout_
height=wrap_content

android:layout_alignParentBottom=true

android:layout_centerHorizontal=true />
<
/RelativeLayout>
</LinearLayout>

Agora, para adicionarmos os controles de zoom no MapView,


obtemos o LinearLayout por meio da referncia R.id.map_zoom
passado para findViewById(). Chamamos o mtodo addView()
e passamos como parmetro um objeto ZoomControls, retornado por mapView.getZoomControls(), e configuramos a altura
e largura deste objeto como LayoutParams.WRAP_CONTENT,
informando que ambas devem ser ajustadas de acordo com o
contedo do componente.
Queremos que a busca do CEP ocorra de acordo com dois
eventos: ou clicando no ImageButton ou pressionando a tecla
ENTER. Para isso, devemos permitir que tanto ImageButton
quanto EditText sejam registrados para escutar eventos de clique por meio da interface View.OnClickListener e mtodo onClick() - ou de pressionamento de teclas, implementando View.
OnKeyListener e o mtodo onKey(). Finalmente, registramos o
ImageButton (varivel imgBtnPesquisar) para escutar eventos
de clique por meio do mtodo setOnClickLister() e para o EditText (varivel etCEP), chamamos o mtodo setOnKeyListener()
para capturar eventos de pressionamento de teclas. Ambos os
mtodos recebem como parmetro a referncia this informando que a nossa prpria Activity que implementar as

Edio 23 - WebMobile Magazine

37

Listagem 3. WSCepActivty.java
/* package & imports */
public class WSCepActivity extends MapActivity implements View.
OnClickListener, View.OnKeyListener {
/* declarao de variveis*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
flipper = (ViewFlipper) findViewById(R.id.flipper);
Animation in = AnimationUtils.loadAnimation(this,
android.R.anim.fade_in);
Animation out = AnimationUtils.loadAnimation(this,
android.R.anim.fade_out);
flipper.setInAnimation(in);
flipper.setOutAnimation(out);
flipper.startFlipping();
/* inicializando widgets */
etCEP = (EditText) findViewById(R.id.etCEP);
tvEstado = (TextView) findViewById(R.id.tvEstado);
tvCidade = (TextView) findViewById(R.id.tvCidade);
tvBairro = (TextView) findViewById(R.id.tvBairro);
tvTipoLograd = (TextView) findViewById(R.id.tvTipoLogradouro);
tvLograd = (TextView) findViewById(R.id.tvLogradouro);
tvComplemento = (TextView) findViewById(R.id.tvComplemento);
imgBtnPesquisar = (ImageButton) findViewById(R.id.imgBtnPesquisar);
mapView = (MapView) findViewById(R.id.map);

Figura 1. Configuraes iniciais do projeto.

interfaces de tratamento de eventos.


Para dar mais riqueza aplicao, adicionamos um menu
que permite mudar a modalidade do mapa (trfego ou satlite).
Para isso, sobrescrevemos o mtodo onCreateOptionsMenu() e
onOptionsItemSelected(). O primeiro mtodo inicializa o menu de
opes da Activity. Nele, criamos um SubMenu que retornado
quando chamamos addSubMenu(), que recebe por parmetro
quatro objetos que representam, respectivamente, o id do grupo,
id do item, a ordem desse item no menu e o titulo. Logo em seguida, chamamos setIcon() para alterarmos o cone (referenciado por
android.R.drawable.ic_menu_mapmode) desse SubMenu. Logo
abaixo, adicionamos neste SubMenu os MenuItems que representaro os modos de visualizao do mapa: trfego e satlite. Para
capturarmos os cliques nestes itens de menu e alterarmos o modo
do mapa, codificamos a lgica dentro de onOptionsItemSelected()
que recebe como parmetro o item (MenuItem) selecionado.
Finalmente nessa parte inicial, temos o mtodo sobrescrito
isRouteDisplayed() que retorna um booleano para informar
se algum tipo de rota est sendo visualizada. A Listagem 3
apresenta nossa MapActivity com as devidas alteraes.
A Listagem 4 exibe o arquivo AndroidManifest.xml, j
configurado com as tag <uses-library> que faz referncia
biblioteca com.google.android.maps e as de permisso
<uses-permission> necessrias para acesso internet (android.permission.INTERNET) e para ter acesso a outros
tipos de protocolos mais granulados, como Wi-Fi, CellID, etc
(android.permission.ACCESS_COARSE_LOCATION), sendo
que esta segundo requerida no momento de obteno da
latitude/longitude da localidade. A Listagem 5 mostra o
arquivo strings.xml que representa as Strings estticas utilizadas na aplicao; e a Figura 2 exibe nossa aplicao em
seu estgio inicial.

Entendendo o funcionamento do Web Service de CEP


Antes de codificarmos a lgica de consumo do WS de busca
de CEPs (tambm possui a funo de clculo de frete, mas como
o prprio site informa, s existe implementao para busca de

38

WebMobile Magazine - Utilizando Web Services no Google Android

LinearLayout zoomLayout = (LinearLayout) findViewById(R.


id.map_zoom);
zoomLayout.addView(mapView.getZoomControls(), new ViewGroup.
LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

imgBtnPesquisar.setOnClickListener(this);
etCEP.setOnKeyListener(this);

@Override
protected boolean isRouteDisplayed() {
return false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
SubMenu subMenu = menu.addSubMenu(0,1,2,Modo de Mapa).
setIcon(android.R.drawable.ic_menu_mapmode);
subMenu.add(0,2,1,Trfego);
subMenu.add(0,3,2,Satlite);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()){
case 2:
mapView.setTraffic(true);
mapView.setSatellite(false);
break;
case 3:
mapView.setTraffic(false);
mapView.setSatellite(true);
break;
}
return true;

CEPs), devemos realizar um cadastro no site www.maniezo.com.


br (na parte direita da tela numa rea com o ttulo Webservice
e clicando em leia mais), pois para o acesso ser necessrio
informar o nome de usurio e a senha como parmetros para o
WS. Feito o cadastro, na mesma tela ser apresentada a URL de
acesso WSDL - http://www.maniezo.com.br/webservice/soap-server.
php?wsdl - que contm os servios e a descrio completa do formato das mensagens de envio e resposta e um pequeno exemplo
da utilizao do acesso a este em PHP.
O parmetro de consulta deste Web Service possui um formato
que deve ser seguido. Para isso, deve-se passar como parmetro o
seguinte esquema: CEP#login#senha#. Estes campos, inclusive

ANDROID

Listagem 4. AndroidManifest.xml
<?xml version=1.0 encoding=utf-8?>
<manifest xmlns:android=http://schemas.android.com/apk/res/
android
package=android.webmobile.ws.cep android:versionCode=1
a
ndroid:versionName=1.0.0>
<uses-permission android:name=android.permission.INTERNET />
<uses-permission android:name=android.permission.ACCESS_
COARSE_LOCATION />

o caractere especial #, devem ser passados exatamente nesta


ordem. Se tudo ocorrer em perfeita ordem, o resultado obtido
deve ser uma String no formato: TipoLogradouro#Logradouro#
Complemento#Bairro#Cidade#Estado#. Como uma forma de um
guia de consulta, a Tabela 2 mostra os dados retornados pelo Web
Service em forma de um array (indicado por resultado[i]), onde
cada informao est contida em uma posio.

<application android:icon=@drawable/icon android:label=@


string/app_name>

Listagem 5. strings.xml
uses-library android:name=com.google.android.maps />
<
activity android:name=WSCepActivity android:label=@string/
<
app_name>
<intent-filter>
action android:name=android.intent.action.MAIN />
<
category android:name=android.intent.category.LAUNCHER />
<
</intent-filter>
/activity>
<
</application>
</manifest>

<?xml version=1.0 encoding=utf-8?>


<resources>
<string name=app_name>Buscador de CEPs</string>
<string name=cep_desc>CEP:</string>
<string name=estado>Estado:</string>
<string name=cidade>Cidade:</string>
<string name=bairro>Bairro:</string>
<string name=tipo_logradouro>Tipo Logradouro:</string>
<string name=logradouro>Logradouro:</string>
<string name=complemento>Complemento:</string>
</resources>

Nota do DevMan 2
Obtendo uma API Key para ativar o uso de MapViews
A partir da verso 0.9 do SDK, os MapViews e as aplicaes para poderem rodar
nos dispositivos em Android devem ser assinados obrigatoriamente. Isto se torna necessrio, pois eles permitem acesso aos dados do Google Maps. Sendo assim, preciso
se registrar no servio do Google Maps e aceitar aos Termos de Servios para que seu
MapView possa obter qualquer tipo de dado retornado pelo Google Maps. E isso se
aplica tanto durante o desenvolvimento das aplicaes no emulador quanto para uma
aplicao que ir rodar normalmente em um dispositivo que rode Android (como o HTC
G1 T-Mobile, atualmente o nico dispositivo mvel disponvel comercialmente rodando
a plataforma do Google).
Registrar um MapView a fim de se obter uma chave privada vlida comumente chamada de API Key simples, de graa e pode ser seguido basicamente em dois passos:
1 - Registrar o fingerprint (impresso digital) MD5 do certificado que voc utilizar
para assinar a sua aplicao. Depois, deixe que o prprio servio de registro do Google
Maps fornea a chave gerada para ser utilizada nas aplicaes que foram assinadas com
o certificado que voc utilizou.
2 - Adicionar em cada MapView utilizado, uma referncia para a API Key gerada (via
XML ou via cdigo), desde que esta chave tenha sido a que foi gerada pelo fingerprint
que voc utilizou durante o processo de registro.
possvel que voc crie seu prprio certificado (da mesma maneira que utilizvamos para assinatura de Applets nos tempos ureos de Java...) utilizando a
ferramenta keytool que vem integrada em qualquer SDK de Java. Em termos de
desenvolvimento, Android j disponibiliza um certificado um arquivo chamado
debug.keystore (conhecido tambm como Debug Certificate) - que fica armazenado num diretrio especfico que varia de plataforma para plataforma. A Tabela 1
mostra o diretrio em que o arquivo debug.keystore est armazenado de acordo
com a plataforma. Porm, para deploy das aplicaes em dispositivos, necessrio
que outro certificado seja utilizado. Mas se voc estiver usando o Eclipse/ADT para
desenvolvimento, o local deste arquivo pode ser obtido indo em Windows > Preferences > Android > Build.

Como estamos desenvolvendo no emulador e no iremos fazer o deploy de uma


aplicao em nenhum dispositivo (por enquanto) real, utilizaremos o prprio Debug Certificate para gerarmos a API Key para utilizarmos no nosso MapView.
Sendo assim, para obtermos um fingerprint MD5 para nosso certificado, executamos o seguinte comando em um prompt de comando:
keytool -list -alias androiddebugkey keystore <caminho_para_debug_keystore>.keystore storepass android keypass android
Depois disso, copiamos o fingerprint MD5 e acessamos o site de registro da Android Maps API, que est disponvel em http://code.google.com/intl/pt-BR/android/
maps-api-signup.html. Leia o termo de servio, aceite e cole no nico campo de texto
o fingerprint MD5 obtido. Depois disso, voc ser redirecionado para outro site que
mostra a chave que voc deve utilizar nos seus MapViews. Simples, no? Agora voc
escolhe: adicionar a chave via XML ou via cdigo, passando para o construtor de MapView a chave gerada. Para a nossa aplicao, iremos adicionar a chave por meio do
atributo android:apiKey - via XML. O site que contm a chave gerada j disponibiliza
um exemplo de como seria a utilizao de um MapView via XML. Se voc preferir, pode
copiar e colar o exemplo. A Listagem 2 j utiliza o MapView via XML, somente deve ser
alterado o valor de android:apiKey para a chave que foi gerada anteriormente. Para
mais detalhes de como gerar o seu prprio certificado, assinar a sua aplicao e outras
informaes necessrias para o deploy de aplicaes em Android, acess3 http://code.
google.com/intl/pt-BR/android/devel/sign-publish.html.
Plataforma

Diretrio

Windows Vista

C:\Users\<user>\AppData\Local\Android\debug.keystore

Windows XP

C:\Documents and Settings\<user>\Local Settings\ApplicationData\


Android\debug.keystore
~/.android/debug.keystore

OS X e Linux

Tabela 1. Correspondncia entre a plataforma e o diretrio de debug.


keystore.

Edio 23 - WebMobile Magazine

39

Posio no Array

Descrio

resultado[0]

Tipo do Logradouro (Ex: Rua, Avenida)

resultado[1]

Logradouro (Endereo)

resultado[2]

Complemento

resultado[3]

Bairro

resultado[4]

Cidade

resultado[5]

Estado no formato de siglas (Ex: PA)

Tabela 2. Guia de consulta do formato de retorno do Web Service.

Figura 2. Aplicao rodando em seu estgio inicial.

Configurando KSOAP2 em Android


Aqui iremos configurar o nosso projeto para utilizar a biblioteca
KSOAP2, muito conhecida em Java ME para consumo de aplicaes. Porm, antes vale ressaltar uma caracterstica relevante
da plataforma: como Android j vem integrado no mnimo com
o Tiger (codinome do Java 5.0), conseguimos facilmente rodar
bibliotecas que j funcionam para Java SE, como o caso do
KSOAP2.
Acessando o site da biblioteca http://sourceforge.net/projects/
ksoap2/, percebemos que a plataforma possui trs tipos de releases:
ksoap2-j2me-core-<verso>.jar, ksoap2-j2me-extras-<verso>.jar,
ksoap2-j2me-nodeps-<verso>.jar e ksoap2-j2se-full-<verso>.jar.
As primeiras verso, como podemos observar, para Java ME, o
que no ir funcionar em Android devido s determinadas APIs
de Java ME estarem ausentes, o que gerar um RuntimeException no momento que o Web Service estiver sendo consumido.
Sendo assim, iremos escolher a verso completa para Java SE que
funciona perfeitamente em Android (na poca da escrita deste
artigo, a verso disponvel para KSOAP2 era a 2.1.2).
Depois de termos baixado a biblioteca, iremos integr-la em
nossa aplicao para que possamos acessar as suas APIs de
acesso a Web Services. Para isto, basta a adicionarmos no Build
Path do projeto. Seguiremos os seguintes passos no Eclipse
(para desenvolvedores mais avanados, favor seguir para a
prxima seo):
Clicar com o boto direito em cima do nome do projeto
Apontar para Build Path > Configure Build Path
Clicar no boto Add JARs se a biblioteca estiver no classpath
do projeto ou Add External JARs..., se a sua aplicao estiver em
um outro local no disco
Selecionar o JAR e clicar em Abrir
Pronto. Agora j podemos ter acesso a toda API do KSOAP2.

Consumindo Web Services com KSOAP2


Agora criaremos em nosso projeto uma outra classe WSConnection,Java (Listagem 6) - que ser responsvel por
conter a regra de negcio necessria para o consumo do Web
Service, bem como realizar a pesquisa de CEP, tratar o resultado

40

WebMobile Magazine - Utilizando Web Services no Google Android

obtido, etc.
Comeamos declarando trs variveis pblicas finais estticas
que representam, respectivamente, a URL do WebService (URL) o
nome da operao responsvel por buscar o CEP (OPERATION),
o namespace do WS (NAMESPACE), o nome de usurio (USERNAME) e a senha (PASSWORD).
Seguindo, declaramos o mtodo esttico pesquisarCEP(),
passando como parmetro uma String que representar o CEP
informado pelo usurio. Depois, comeamos a utilizar a primeira
das principais classes da biblioteca SoapObject (varivel request)
- que representar o encapsulamento da requisio que ser feita
ao Web Service, ou seja, o que vai dentro do envelope. Ela recebe
como parmetro uma String representando o namespace referente ao WS e o nome da operao, que no nosso caso traz_cep.
Em seguida, criamos um objeto SoapSerializationEnvelope
(varivel envelope) que a abstrao de um envelope SOAP e
passamos como parmetro a verso do protocolo SOAP que
iremos utilizar (SoapEnvelope.VER11). Chamamos envelope.
setOutputSoapObject(request) para encapsularmos request
como corpo do envelope SOAP a ser enviado.
Agora criamos um StringBuffer que ir formatar o parmetro
no esquema correto aceito pelo WS. Adicionamos - por meio
do mtodo addProperty() - a String dados_cep que ser uma
espcie de chave para seu valor - o parmetro formatado. Instanciamos um objeto HttpTransportSE (SE uma referncia para
Standard Edition de Java uma vez que estamos usando a verso
de KSOAP2 para JSE) e passamos como parmetro a URL para
acessar o Web Service. Finalmente, chamamos o mtodo call()
de HttpTransportSE (varivel httpTransport), passando uma
string em branco (no precisaremos de nenhuma SoapAction) e o
envelope que construmos anteriormente e esperamos a resposta
do servidor. Assim que a resposta retornada, o valor obtido
recuperado pela chamada envelope.getResponse().
O resultado pode vir em dois formatos: uma String com os
valores da localidade, todos concatenados (mais informaes
do formato retornado, revisitar a seo Entendendo o funcionamento do Web Service de CEP) caso o CEP seja vlido
ou a String ##### (na verdade como se o campo de cada
informao de localidade estivesse vazio) caso o CEP no seja
encontrado. Por fim, instanciamos o objeto CepBean (Listagem
7) para encapsularmos os dados retornados da consulta.

Views, Threads e Handlers em Android


Voltando para WSCepActivity (Listagem 8), criamos o mtodo
pesquisarCep() que recebe como parmetro uma String que

ANDROID

o CEP a ser pesquisado e retorna um Object, que no nosso caso


ser o bean CepBean. Para maior conforto para o usurio, queremos exibir uma mensagem enquanto os dados da localidade
no forem obtidos. Para isso, utilizamos a classe ProgressDialog. Chamamos ProgressDialog.show() para mostrarmos esta
mensagem e atribumos varivel progressDialog. Esse mtodo
recebe quatro parmetros: o ttulo, a mensagem, um booleano
para indicar se este ProgressDialog indeterminado (no ir
mostrar uma barra crescente informando o status do progresso) e outro booleano informando se este componente pode ser
interrompido (clicando no boto voltar, por exemplo) ou no.
uma boa prtica de programao enviarmos para threads
separadas partes de cdigo que possa demorar um tempo significativo para a completude do processamento. Dessa forma,
assim que o mtodo pesquisarCep() for chamado, instanciamos
uma nova thread passando para seu construtor a referncia
this pois a nossa Activity ir implementar Runnable e o
mtodo run() que ser chamado por start().
O mtodo run() possui o cerne da lgica da aplicao de busca
de CEPs. Comeamos validando a entrada do CEP, criticando caso
o campo de CEP esteja em branco, caso contrrio, a busca do CEP
deve ser realizada chamando WSConnection.pesquisarCEP().
Uma regra geral: para toda e qualquer mensagem que deva
ser mostrada por meio do componente AlertDialog, criamos
um objeto Bundle (uma espcie de mapeamento chave/valor)
e configuramos o ttulo e a mensagem do dilogo que ser
mostrado. Depois obtemos uma Message chamando Message.
obtain(), passamos o objeto Bundle (varivel bundle) para
setData() de Message e chamamos o mtodo sendMessage()
de um handler, passando o objeto Message que encapsula os
dados presentes em bundle. Para que tudo isso? Pois Android,
por questo de segurana e arquitetura, no permite que
Views e Viewgroups sejam manipulados (instanciados ou
seus mtodos sejam chamados) fora de sua thread de criao
(lembrem-se que estamos dentro de run() ). Sendo assim, devemos utilizar Handlers, que so objetos que permitem enviar
e processar Messages e Runnables associados com threads
de uma MessageQueue (cada nova thread criada possui um
MessageQueue).
Basicamente, Handlers so utilizados por dois motivos: escalonar Messages ou Runnables para serem executados em algum
momento futuramente ou enfileirar uma ao para ser realizada em uma Thread diferente da sua (que criou o objeto que
est sendo utilizado). No nosso caso, temos dois handlers, um
para alterar os textos (handler) dos TextViews com as informaes da localidade e outro para mostrar os alertas de dilogos
(varivel handleError). Estes handlers so instanciados assim
que ou sendEmptyMessage() ou sendMessage() chamado. E
por fim, o mtodo handleMessage() um callback chamado
por estes para alterarem os Views. Resumindo: Handlers so
uma forma eficiente de implementarmos aes que devam ser
executadas por Threads diferentes da qual a classe foi criada.
Para mais detalhes sobre Handlers, ler a API deste componente
disponvel em http://code.google.com/intl/pt-BR/android/reference/
android/os/Handler.html.

Listagem 6. WSConnection.java
package android.webmobile.ws.cep;
/* imports */
public class WSConnection {
private static final String URL = http://www.maniezo.com.br/
webservice/soap-server.php;
private static final String OPERATION = traz_cep;
private static final String NAMESPACE = http://www.maniezo.
com.br/soap-server.php;
private static final String USERNAME = ramonrabello;
private static final String PASSWORD = trip22;
public static Object pesquisarCEP(String cep) {
SoapObject request = new SoapObject(NAMESPACE, OPERATION);
SoapSerializationEnvelope envelope = new
SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
StringBuffer params = new StringBuffer();
params.append(cep.concat(#));
params.append(USERNAME.concat(#));
params.append(PASSWORD.concat(#));
request.addProperty(dados_cep, params.toString());
HttpTransportSE httpTransport = new HttpTransportSE(URL);
try {
httpTransport.call(, envelope);
String response = (String) envelope.getResponse();
if (response.equals(#####))
return null;
else {
String[] dadosCep = response.split(#);
CepBean cepBean = new CepBean();
cepBean.setTipoLogradouro(dadosCep[0]);
cepBean.setLogradouro(dadosCep[1]);
cepBean.setComplemento(dadosCep[2]);
cepBean.setBairro(dadosCep[3]);
cepBean.setCidade(dadosCep[4]);
cepBean.setUf(dadosCep[5]);
cepBean.setCep(cep);
return cepBean;
}

}
catch (IOException ioex) {
return null;

}
catch (XmlPullParserException e) {
return null;
}

Listagem 7. CepBean.java
package android.webmobile.ws.cep;
public class CepBean {
private
private
private
private
private
private
private
}

String
String
String
String
String
String
String

cep;
uf;
cidade;
logradouro;
complemento;
tipoLogradouro;
bairro;

/* gets & sets */

Retornando dados geogrficos com Geocoder


A partir do momento que obtemos os dados referentes ao
CEP (logradouro, cidade, estado, etc) desejado, podemos agora
saber a exata localizao deste CEP para mostrarmos no mapa.
Para isso, utilizaremos o componente android.location.Geocoder (um dos principais componentes da API de Localizao)
que o responsvel por retornar informaes geogrficas
(latitude/longitude, por exemplo) de acordo com determinada

Edio 23 - WebMobile Magazine

41

Listagem 8. WSCepActivity.java
/* package e imports */
public class WSCepActivity extends MapActivity implements View.
OnClickListener,
View.OnKeyListener, Runnable
{

Bundle bundle = new Bundle();


bundle.putString(titulo, Erro Geral);
bundle.putString(msg, Ocorreu um erro geral. Mensagem:
+ ex.getMessage());
Message m = Message.obtain();
m.setData(bundle);
handlerError.sendMessage(m);

/* declarao de variveis */
/* restante do cdigo */
private void pesquisarCep() {
progressDialog = ProgressDialog.show(this, Buscando CEP,
Por favor, Aguarde..., true, false);
Thread t = new Thread(this);
t.start();
}
public void run() {
if (etCEP.getText().toString().equals()) {
Bundle bundle = new Bundle();
bundle.putString(titulo, CEP em branco);
bundle.putString(msg, Por favor, informe o CEP);
Message m = Message.obtain();
m.setData(bundle);
handlerError.sendMessage(m);
}
else {
cepBean = (CepBean) WSConnection.pesquisarCEP(etCEP.
getText().toString().trim());
if (cepBean != null) {
try {
Geocoder geocoder = new Geocoder(this);
String local = cepBean.getTipoLogradouro() + +
cepBean.getLogradouro() + , + cepBean.getCidade();
Address localidade = geocoder.getFromLocationName(local,
1).get(0);
if (localidade != null) {
latitude = localidade.getLatitude() * 1E6;
longitude = localidade.getLongitude() * 1E6;
geoPoint = new GeoPoint(latitude.intValue(),
longitude.intValue());
mapController = mapView.getController();
mapController.setZoom(17);
mapController.animateTo(geoPoint);
marker = getResources().getDrawable(R.drawable.pin);
if (mapView.getOverlays().size() > 0)
mapView.getOverlays().clear();
mapView.getOverlays().add(new
LocationCepOverlay(marker));
handler.sendEmptyMessage(0);
}
else {
Bundle bundle = new Bundle();
bundle.putString(titulo, Localidade no encontrada);
bundle.putString(msg,No foi possvel encontrar uma
localidade no mapa para este cep.);
Message m = Message.obtain();
m.setData(bundle);
handlerError.sendMessage(m);
}

}
catch (IOException ex) {
Bundle bundle = new Bundle();
bundle.putString(titulo, Erro de IO);
bundle.putString(msg, Erro ao obter localidade.
Mensagem: + ex.getMessage());
Message m = Message.obtain();
m.setData(bundle);
handlerError.sendMessage(m);
} catch (Exception ex) {

descrio de localizao (este processo comumente chamado


de geocoding ou geocodificao) ou vice-versa (chamado
de reverse geocoding ou geocodificao reversa).
No nosso exemplo, na Listagem 9, usamos o conceito de
geocodificao no momento que chamamos o mtodo getF
romLocationName(locationName,maxResults) que retorna
uma lista de endereos (List<Address>) de acordo com o filtro
passado, onde . locationName representa a(s) localizao(es)

42

WebMobile Magazine - Utilizando Web Services no Google Android

}
}
else {
Bundle bundle = new Bundle();
bundle.putString(titulo, CEP no encontrado);
bundle.putString(msg,Desculpe, o CEP no pde ser
encontrado. Tente novamente.);
Message m = Message.obtain();
m.setData(bundle);
handlerError.sendMessage(m);
}

//Handler para atualizar os dados da localidade do cep


private Handler handler = new Handler() {
public void handleMessage(Message msg) {
tvEstado.setText(getString(R.string.estado) + cepBean.getUf());
tvCidade.setText(getString(R.string.cidade) + cepBean.
getCidade());
tvBairro.setText(getString(R.string.bairro) + cepBean.
getBairro());
tvTipoLograd.setText(getString(R.string.tipo_logradouro)
+ cepBean.getTipoLogradouro());
tvLograd.setText(getString(R.string.logradouro) + cepBean.
getLogradouro());
tvComplemento.setText(getString(R.string.complemento) +
cepBean.getComplemento());
}

progressDialog.dismiss();

};
// Handler para mostrar mensagens de erro
private Handler handlerError = new Handler() {
public void handleMessage(Message msg) {
if (progressDialog.isShowing()) progressDialog.dismiss();
tvEstado.setText(getString(R.string.estado));
tvCidade.setText(getString(R.string.cidade));
tvBairro.setText(getString(R.string.bairro));
tvTipoLograd.setText(getString(R.string.tipo_logradouro));
tvLograd.setText(getString(R.string.logradouro));
tvComplemento.setText(getString(R.string.complemento));
String titulo = msg.getData().getString(titulo);
String mensagem = msg.getData().getString(msg);
alertDialog = new AlertDialog.Builder(WSCepActivity.this).
create();
alertDialog.setButton(OK, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
}
});

}
};

alertDialog.setTitle(titulo);
alertDialog.setMessage(mensagem);
alertDialog.setIcon(android.R.drawable.ic_dialog_alert);
alertDialog.show();

que queremos pesquisar; e o inteiro maxResults utilizado para


limitar o nmero mximo de ocorrncias encontradas. Como
um CEP especfico para somente uma localidade, passamos
1 como valor para maxResults.
Depois, obtemos a latitude (varivel latitude) e longitude (varivel longitude) do ponto representado pelo CEP. No esquecendo
que multiplicar pela constante 1E6 (um milho), pois os mtodos
getLatitude() e getLongitude() de Address (ambos com valor de

ANDROID

retorno do tipo double) - so retornados em graus, o que influencia


drasticamente na preciso do ponto geogrfico a ser mostrado no
mapa. Agora iremos encapsular os valores da latitude e longitude
por meio da classe GeoPoint, porm seus dois parmetros devem
ser convertidos para inteiros por meio do mtodo intValue(). Depois, obtemos o objeto MapController (varivel mapController)
responsvel por manipular MapViews (zoom, animar em determinada posio do mapa, etc) chamando mapView.getController().
Aps, configuramos o nvel de zoom para 17 (o nvel varia de 1 a
21, inclusive) por meio da chamada mapController.setZoom(17)
e fazemos com que o MapView seja animado de acordo com a
localizao que obtivemos deste cep, passando para o mtodo
animateTo() de mapController o objeto GeoPoint.

Mostrando a localizao do CEP com ItemizedOverlay


Agora s est faltando mostrarmos a localizao deste
CEP no mapa. Para isso iremos utilizar o componente ItemizedOverlay (subclasse da antiga classe Overlay) que permite
visualizar listas de OverlayItems que so os objetos que sero
renderizados no mapa. Ele possui as mesmas funcionalidades
do componente Overlay, porm com as seguintes vantagens e
facilidades para se trabalhar com aplicaes com mapas:
tratar aspectos de direo de desenho (por exemplo, se este
deve ser desenhado de norte-a-sul no mapa);
definir limites de desenho do item (qual a rea que ser
ocupada por um item);
utilizar uma objeto grfico (qualquer Drawable) para marcar
cada ponto no mapa;
gerenciar evento de foco nos itens;
disparar eventos de toque e mudana de foco de itens por
meio de listeners.
Voltando para o nosso exemplo, criamos uma classe privada LocationCepOverlay que estende ItemizedOverlay<OverlayItem>
para configurarmos o que e onde ser mostrado o marcador (ver
Listagem 10), que no nosso caso vai ser uma imagem de um
alfinete de mapa - que est na pasta res/drawable - e ser visualizado nas coordenadas especficas da localidade do CEP.
Continuando, declaramos uma List (varivel overlayItems)
que conter todos os OverlayItems e nos ser til para outros
mtodos sobrescritos. No mtodo construtor, chamamos o
construtor da superclasse que recebe tambm um Drawable
que ser o marcador padro que ser utilizado. Instanciamos
um OverlayItem e passamos como parmetro, respectivamente, o ponto geogrfico (representado pela varivel geoPoint) que
foi obtido durante a geocodificao, uma String para o ttulo
e outra para a descrio deste elemento. Depois, adicionamos
este item em overlayItems e chamamos o mtodo populate().
Esse mtodo serve como um utilitrio para ItemizedOverlays
(e suas subclasses) e recomenda-se cham-lo assim que algum
dado (OverlayItem) estiver disponvel. O mtodo createItem()
recebe como parmetro um inteiro que corresponde ao ndice
do OverlayItem na lista e retorna um OverlayItem na posio
i. Ele intimamente ligado a populate(), uma vez que somente
createItem() chamado por ele para popular os OverlayItems
a fim de serem visualizados no mapa.

Listagem 9. WSCepActivity.java
/* package & imports */
public class WSCepActivity extends MapActivity implements View.
OnClickListener,
View.OnKeyListener, Runnable
{
/* cdigo omitido */
public void run() {
if (etCEP.getText().toString().equals()) {
/* cdigo omitido */
}
else {
cepBean = (CepBean) WSConnection.pesquisarCEP(etCEP.
getText().toString().trim());
if (cepBean != null) {
try {
Geocoder geocoder = new Geocoder(this);
String local = cepBean.getTipoLogradouro() +
+ cepBean.getLogradouro() + , +
cepBean.getCidade();
Address localidade = geocoder.
getFromLocationName(local, 1).get(0);
if (localidade != null) {
latitude = localidade.getLatitude() * 1E6;
longitude = localidade.getLongitude() * 1E6;
geoPoint = new GeoPoint(latitude.intValue(),
longitude.intValue());
mapController = mapView.getController();
mapController.setZoom(17);
mapController.animateTo(geoPoint);
}
else {
/* cdigo omitido */
}
}
catch (IOException ex) {
/* cdigo omitido */
} catch (Exception ex) {
/* cdigo omitido */
}
}
else {
/* cdigo omitido */
}
}
}
}

Seguindo, sobrescrevemos o mtodo draw(), definido em


Overlay que utilizado para desenhar os objetos grficos na
tela (utilizando Canvas) e recebe como parmetro trs objetos:
um Canvas, representando a tela que ser desenhada com os
objetos grficos (imagens, formas, etc), o nosso MapView que ir
ser sobreposto por este Overlay; e um booleano informando se
este Overlay deve projetar sombras. Depois, chamamos o mtodo draw() da superclasse e boundCenterBottom() que recebe
como parmetro um Drawable (marker). Este mtodo til para
centrarmos o centro da imagem no pixel(0,0) e ele especfico
para ser utilizado por aplicaes que mostram a localizao no
mapa por meio de itens com aspectos de alfinete (conhecidas
como pin-based applications em Ingls).
Sobrescrevemos por fim o mtodo size() para retornarmos a
quantidade de OverlayItems na lista pois populate() tambm
chama este mtodo. Para retornarmos nossa imagem como um
Drawable, chamamos getResources().getDrawable() e passamos
para o segundo mtodo o inteiro com o identificador de nossa
imagem na classe utilitria de recursos R.java (R.drawable.
pin) e atribumos para marker, que um Drawable. Testamos
se existe algum OverlayItem na lista e a limpamos chamando
mapView.getOverlays().clear() para garantir que s haver um

Edio 23 - WebMobile Magazine

43

Listagem 10. WSCepActivity.java


/* package & imports */
public class WSCepActivity extends MapActivity implements View.
OnClickListener,
View.OnKeyListener, Runnable
{

/* restante do cdigo */
private class LocationCepOverlay extends ItemizedOverlay<OverlayItem> {
List<OverlayItem> overlayItems = new ArrayList<OverlayItem>();

/* declarao de variveis */

public LocationCepOverlay(Drawable defaultMarker) {


super(defaultMarker);
OverlayItem item = new OverlayItem(geoPoint, Dados da
Localidade, cepBean.getLogradouro());
overlayItems.add(item);
populate();
}

/* cdigo omitido */
public void run() {
try {
localidade = geocoder.getFromLocationName(cepBean.
getTipoLogradouro() + + cepBean.getLogradouro() +
, + cepBean.getCidade(), 1).get(0);

@Override
protected OverlayItem createItem(int i) {
return overlayItems.get(i);
}

if (localidade != null) {
/* cdigo omitido */
marker = getResources().getDrawable(R.drawable.pin);
mapView.getOverlays().add(new
LocationCepOverlay(marker));
handler.sendEmptyMessage(0);
}
else {
/* cdigo omitido */
}

}
catch (IOException ex) {
/* cdigo omitido */
} catch (Exception ex) {
/* cdigo omitido */

@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
boundCenterBottom(marker);
}

@Override
public int size() {
return overlayItems.size();
}

precoce (1 ano e alguns meses na poca deste artigo), tem


provado que a cada release do SDK, as funcionalidades que
foram apresentadas no dia do seu anncio ao pblico mundial
tornam-se realidade tanto para ns desenvolvedores quanto
para os usurios finais do dispositivo.
Links
Eclipse Ganymede
http://www.eclipse.org/ganymede/
Site do SDK do Android
http://code.google.com/android/
Figura 3. Aplicao mostrando a imagem na exata posio do CEP (modo
mapa).

OverlayItem sendo mostrado no mapa, que ser a localidade do


CEP. Porm, para que possamos visualizar o alfinete no mapa,
precisamos adicionar LocationCepOverlay ou nosso MapView,
realizamos o comando mapView.getOverlays().add() e passamos para add() uma instncia de nosso ItemizedOverlay para
podermos visualizar o alfinete na exata posio geogrfica. A
Listagem 10 mostra o cdigo referente ao nosso ItemizedOverlay
e as alteraes necessrias para visualizao do item no mapa.
A Figura 3 mostra um exemplo da nossa aplicao em execuo
utilizando o ItemizedOverlay que criamos.

Obtendo chave privada (API Key) para MapViews


http://code.google.com/intl/pt-BR/android/toolbox/apis/mapkey.html
Registrando uma API Key para MapView
http://code.google.com/android/maps-api-signup.html
Web Service de Busca de CEP
http://www.maniezo.com.br
API do componente Handler
http://code.google.com/intl/pt-BR/android/reference/android/os/Handler.html
API do componente Geocoder
http://code.google.com/intl/pt-BR/android/reference/android/location/Geocoder.html
API do componente ItemizedOverlay
http://code.google.com/android/reference/com/google/android/maps/ItemizedOverlay.html

Concluses
Como voc pde perceber, Android ainda no possui uma
API que j venha embutida que trate especificamente de Web
Services. Sendo assim, para ser possvel trabalharmos com
WS, Android possui a capacidade de integrar as mesmas
bibliotecas de Java SE, como vimos com a verso de KSOAP2,
em aplicaes comerciais reais.
A plataforma Android, por mais que ainda esteja muito

44

WebMobile Magazine - Utilizando Web Services no Google Android

D seu feedback sobre esta edio!


A Web Mobile tem que ser feita ao seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/webmobile/feedback

Introduo ao
desenvolvimento de
aplicaes para o iPhone
com o iPhone SDK

De que se trata o artigo


Desenvolvimento de aplicaes para o iPhone com o iPhone SDK.
Para que serve
Para informar sobre o desenvolvimento do iPhone usando iPhone SDK,
abordando a instalao do mesmo e a criao de uma aplicao simples.
Em que situao o tema til
Desenvolvimento e debug de aplicaes para o iPhone.

Rogrio Arajo
rogerio.araujo@gmail.com

desenvolvedor especialista em tecnologias WEB, Mobile e Desktop. Atualmente trabalha na empresa Druid Search com solues de buscas corporativas
para grandes empresas.

obilidade tem sido a palavra mais abordada nos


dias de hoje. Os dispositivos mveis tem ganhado
uma enorme importncia no nosso dia a dia. Quem
atualmente consegue viver sem um celular no bolso?
O celular tem se apresentado como pea fundamental em
nossas vidas, facilitando a comunicao com o mundo ao
nosso redor e nos ltimos anos ele simplesmente deixou de ser
um mero meio de comunicao e passou a ser um verdadeiro
canivete suo moderno com inmeras funcionalidades,
transformando-se em um verdadeiro computador de bolso,
capaz de nos divertir, informar e orientar nossos caminhos.
Entre inmeros celulares disponveis no mercado, surgiu um
com caractersticas singulares, o iPhone. Este celular inovou
o conceito de telefonia mvel, apresentando funcionalidades
que at ento no haviam sido adicionadas a um celular. Neste
artigo, falaremos brevemente sobre a histria do iPhone, o que
o torna este celular to interessante, quais as funcionalidade
que o mesmo possui e ento abordaremos como voc pode
ampliar essa gama de funcionalidades ao criar novas aplicaes
usando o iPhone SDK.

Edio 23 - WebMobile Magazine

45

Histria do iPhone
O iPhone o primeiro celular produzido pela fabricante de
computadores Apple. Ele revolucionou o mercado de celulares
ao apresentar uma gama de funcionalidades inditas neste tipo
de dispositivo, onde a principal delas seu teclado virtual que
pode ser utilizando bastando somente tocar na tela, chamado
de touch screen (ver Figura 1).

Figura 1. Tela inicial do iPhone

A primeira verso comercial do iPhone foi lanada em 9 de


janeiro de 2007. Esta verso inclua suporte para cmera, voice
mail, media player, mensagens SMS, navegao na internet e
conexo Wi-Fi.
A segunda verso do iPhone, mais conhecida como iPhone
3G, veio com suporte s tecnologias de redes 3G HSDPA e
UMTS alm de um GPS integrado.
Porm, o grande desafio que surgiu a partir da foi: como
viabilizar o desenvolvimento global de novas aplicaes para
rodarem no iPhone. A seguir, conheceremos um pouco sobre
este novo ramo que surgiu.

Desenvolvimento de Aplicaes para o iPhone. O que


o iPhone SDK?
No dia 6 de maro de 2008 foi lanado o iPhone SDK, que
um kit completo para o desenvolvimento de aplicaes para
o iPhone contendo a IDE Xcode, a ferramenta Interface Builder,
o iPhone Simulator, o compilador GCC, a ferramenta de debug
GDB, dentre vrios outros utilitrios de desenvolvimento.
A IDE Xcode um dos softwares fundamentais do SDK.
Com o Xcode possvel iniciar rapidamente a criao de uma
aplicao para o iPhone a partir de um assistente/wizard. Ela

46

Nota do DevMan 1
XIB
O XIB um formato de arquivo usado para descrever de forma declarativa a
estrutura de uma tela de uma aplicao para o iPhone, contendo informaes
como tamanho, posicionamento, componentes presentes na tela, caractersticas
e comportamentos dos mesmos.

possui suporte para complemento de cdigo, integrao com


sistemas de controle de verso de cdigo como o CVS e SVN,
integrao com o Interface Builder e com o iPhone Simulator.
Para criao da interface de aplicaes, o SDK dispe do Interface Builder. Com esta ferramenta possvel criar interfaces
para as aplicaes para o iPhone bastando apenas arrastar
e soltar os componentes de interface disponveis em uma
paleta de componentes na tela que est sendo desenhada.
possvel, ainda, gravar as telas em um formato chamado
XIB (ver Nota DevMan 1) que descrito em XML. Esses
arquivos podem ser carregados a partir do cdigo de nossa
aplicao, que ento vai processar este arquivo e apresentar
a tela ao usurio.
Para compilar as aplicaes, pode ser usado o GCC, que
um compilador opensource capaz de compilar cdigo nas
linguagens C, C++ e Objective C. O Xcode utiliza-se do GCC
para compilar o cdigo das aplicaes para o iPhone.
Alm do GCC, o iPhone SDK tambm faz uso do GDB, que
um projeto opensource utilizado para depurar aplicaes
desenvolvidas em C, C++ e tambm Objective C. O Xcode
possui excelente integrao com o GDB, facilitando no processo
de depurao de suas aplicaes.

Preparando o Ambiente de Desenvolvimento de uma


Aplicao para o iPhone
O desenvolvimento de aplicaes para o iPhone requer no
somente ferramentas especficas, mas tambm requer um
hardware e sistema operacional adequado para isto. Para
que o desenvolvimento de tais aplicaes seja possvel, ser
necessrio ter disposio um computador Apple: Mac Mini,
Mac Book, Mac Book Pro ou iMac com o Mac OSX 10.5.5
instalado.
Se voc j possui um computador Apple com o MacOS X
devidamente atualizado para a verso 10.5.5, basta agora
simplesmente realizar o download e instalao do iPhone
SDK, que se encontra disponvel no endereo http://developer.apple.com/iphone. Para isso, voc deve se registrar
para s ento realizar o download da imagem de disco do
instalador que se encontra no link chamado iPhone SDK for
iPhone OS 2.2.
Uma vez concludo o download, basta ir na pasta onde se
encontra a imagem de disco do instalador e d dois clique no
mesmo para abri-lo, conforme na Figura 2.
Surgir a tela exibindo o contedo da imagem de disco do
instalador conforme na Figura 3.

WebMobile Magazine - Introduo ao desenvolvimento de aplicaes para o iPhone com o iPhone SDK

M OBILE

Figura 5. Tela inicial do instalador

Figura 2. Abrindo a imagem de disco

Figura 6. Licena de uso do XCODE

Figura 3. Contedo da imagem de disco

Em seguida, d dois cliques no cone iPhone SDK para iniciar


o instalador. Surgir a tela de confirmao da instalao apresentada na Figura 4, onde voc deve clicar em Continuar.

a licena e clique no boto Continuar.


Se voc concorda com os termos da licena clique no boto
Concordar, caso contrrio clique em Discordar e a instalao
ser interrompida.
Caso voc tenha concordado, ser exibida mais uma tela,
desta vez com os termos da licena de uso do iPhone SDK
(Figura 7). Leia a mesma cuidadosamente e clique no boto
Continuar.

Figura 7. Licena de uso do iPhone SDK


Figura 4. Confirmao para executar o instalador.

Ao confirmar, ser apresentada a tela de boas vindas ao instalador do iPhone SDK (Figura 5). Clique no boto Continuar.
Ao continuar a instalao voc ser conduzido a uma tela
contendo os termos da licena de uso da IDE Xcode (Figura 6),
que a IDE usada para criar as aplicaes para o iPhone. Leia

Novamente voc ser questionado se aceita os termos da


licena. Para aceitar, clique em Agree.
Na tela seguinte, podermos personalizar a instalao do
iPhone SDK (Figura 8), podendo indicar quais pacotes sero
instalados. Mantenha a configurao inalterada para simplificar o processo e clique no boto Continuar.

Edio 23 - WebMobile Magazine

47

Com isso, temos o ambiente preparado para desenvolvimento


de uma aplicao para o iPhone. A seguir veremos como utilizar a IDE que nos apoiar na construo de uma aplicao
para iPhone.

Preparando a execuo do Xcode

Figura 8. Personalizando a instalao do iPhone SDK

Agora poderemos confirmar o local onde o SDK ser instalado (atravs do boto Alterar Localizao da Instalao...).
Manteremos a instalao no local padro. Ento, para iniciar a
instalao dos pacotes clique no boto Instalar (Figura 9).

Para iniciar o desenvolvimento de nossa aplicao, vamos


precisar em primeiro lugar criar um atalho na nossa rea de
trabalho para o Xcode que a IDE criada pela Apple para
facilitar no desenvolvimento de aplicaes para a plataforma
MacOS X e agora tambm para o iPhone.
Para isso, clique na sua rea de trabalho, em seguida aparecer no menu do sistema na parte superior da tela o menu
do utilitrio Finder. Ento, clique na opo Ir Computador,
conforme exibido na Figura 11.

Figura 11. Acessando contedo do computador atravs do utilitrio Finder.

Figura 9. Confirmao do local de instalao do SDK

Antes dos pacotes comearem a ser instalador, ser solicitado


um usurio e senha com permisso para instalar softwares
neste computador. Informe estes dados e clique no boto OK
(Figura 10).

Feito isso, ser iniciado o utilitrio Finder exibindo o contedo


da raiz do HD do seu computador Apple. A partir disso entre
na pasta Developer/Applications, clique no cone do Xcode com
o boto direito do mouse e selecione a opo Criar Atalho
conforme a Figura 12.

Figura 10. Informando usurio e senha com permisso para instalar o SDK

Por fim, ser exibido ento a tela detalhando a instalao


dos pacotes do SDK.
Ao final da fase, ser exibida uma tela informando que a instalao foi concluda com sucesso. Clique ento no boto Fechar.

48

Figura 12. Criando atalho para o Xcode.

WebMobile Magazine - Introduo ao desenvolvimento de aplicaes para o iPhone com o iPhone SDK

M OBILE

Ser criado ento o atalho do Xcode conforme exibido na


Figura 13.

Figura 15. Criando um novo projeto a partir do menu do Xcode.

Figura 13. Atalho do Xcode criado dentro do Finder.

Copie o atalho criado na janela da Figura 13 para a rea de


trabalho, prximo ao cone do Machintosh HD conforme
exibido na Figura 14.

Figura 16. Selecionando o template a ser usado no projeto.

Aps isso, selecione o template do projeto, clique no boto


Choose. Ento ser apresentada uma caixa de dilogo solicitando a gravao do projeto em disco, onde chamaremos o projeto
de Conversor. Por fim, clqique no boto Save (Figura 17).
Figura 14. Atalho do Xcode na rea de trabalho.

A partir de agora, iremos desenvolver uma aplicao para


demonstrar como realizar a construo de aplicaes para a
plataforma do iPhone. Iremos construir uma simples aplicao,
responsvel pela converso de medidas entre diferentes unidades, tais como: metro, centmetro, kilmetros e milhas.

Criando a sua primeira aplicao usando o iPhone SDK


Vamos agora executar o Xcode. Para isso, clique no cone do
mesmo na rea de trabalho, e ento surgir o menu principal
do Xcode e ento clique na opo de menu FileNew Project
conforme a Figura 15.
Surgir a janela abaixo apresentando um conjunto de
templates de projetos para o iPhone. Selecione o template
View-Based Application (Figura 16). Este template possui
o mnimo necessrio para criar uma aplicao de janela pro
iPhone. Nele teremos basicamente a janela e uma View. A
View a poro da janela que gerencia os componentes que
a mesma contm.

Figura 17. Gravando o projeto em disco.

Um esqueleto do projeto ser gerado a partir do template


selecionado. Logo em seguida, o Xcode abrir o projeto e
apresentar o contedo do mesmo na janela principal da IDE
conforme a Figura 18.

Edio 23 - WebMobile Magazine

49

3. UIPickerView: Componente tridimensional para selecionar


dados. Em nossa aplicao, ser atravs deste componente
que podemos selecionar as medidas de centmetro, metro,
kilmetro e milhas como medida des de origem e/ou destino
para converso.
4. UIButton: Componente que apresenta um boto. Teremos
este componente na tela da aplicao para que o usurio ao
clic-lo, o sistema dispare a execuo de um evento realizando
o clculo da converso de medidas.

Figura 18. Tela principal do Xcode com apresentando os fontes do projeto.

Agora que temos a estrutur bsica de nossa aplicao disponvel, ns vamos partir para a construo da interface da
aplicao em primeiro lugar. Para isso, selecione o arquivo
ConversorViewController.xib na janela da Figura 18, d dois
cliques sobre o mesmo para abr-lo em modo de edio no
Interface Builder conforme podemos ver na Figura 19.

Figura 20. Adicionando componentes na view da janela.

Aps adicionar os componentes na tela, voc pode modificar tambm seus atributos. Para isso, basta clicar em um dos
componentes que voc adicionou na View e ento editar seus
atributos na janela do Attribute Inspector conforme podemos
ver na Figura 21.
Figura 19. Tela principal do Interface Builder (1 Document Window; 2
Attributes, Connections, Identity and Size Inspectors Window; 3 Library)

Na Figura 20 ns temos a interface de nossa aplicao parcialmente definida, todos os componentes presentes na paleta de
componentes na janela da direita (Library) podem ser arrastados
e soltados na janela da esquerda, que a janela de nossa aplicao
(View). Observe na Figura 20 a correspondncia entre os componentes da paleta com os componentes adicionados na janela:
1. UILabel: Componente que apresenta um texto. A funo
deste componente ser exibir o rtulo do tipo de dado que
dever ser associado aos outros componentes da tela, como o
UITextField ou o UIPickerView.
2. UITextField: Componente de entrada de dados. Teremos este
componente na janela da nossa aplicao para que digitemos o
dado que ser utilizado no clculo da converso de medidas.

50

Figura 21. Modificando propriedades de um label.

WebMobile Magazine - Introduo ao desenvolvimento de aplicaes para o iPhone com o iPhone SDK

M OBILE

Podemos notar na Figura 21 que estamos modificando o texto


a ser exibido no label indicado pela seta. Podemos customizar
vrios outros atributos deste e de outros componentes atravs
do Attribute Inspector.
Agora que voc inseriu todos os componentes que a aplicao
requer na janela, ser necessrio identific-los apropriadamente. No Document Window selecione o item Files Owner, que
representa a classe ConversorViewController do nosso projeto
(Figura 22). Logo em seguida v na opo ToolsIdentity Inspector do menu principal do Interface Builder. Ser apresentada
uma janela conforme a Figura 23.

responsvel por processar essa ao, que como o nome diz


ser responsvel por processar o pressionamento de um
boto na janela da aplicao.
Alm de definir as aes existentes na interface, precisamos tambm definir variveis (outlets) que guardam
referncia para os componentes visuais presentes na
mesma. atravs de uma outlet que podemos enxergar
o componente presente na janela construda com o auxlio
do interface builder.
Para adicionar uma outlet, v na opo Class Outlets e
clique no boto de adicionar uma outlet conforme indicado
na Figura 23, informe na coluna Outlet o nome do outlet,
pressione [TAB] e digite na coluna Type o nome do tipo
do componente.

Figura 22. Selecionando o recurso que ser mapeado pelo Interface Builder.

Figura 24. Conectando outlet ao componente.

Figura 23. Identificando componentes no Identity Inspector.

Na opo Class Actions ns vamos adicionar uma nova


ao que iremos chamar de btnConverter_clicked. Ser
criado na nossa classe um mtodo de mesmo nome que ser

Aps definir os outlets, ser necessrio conect-los


aos componentes existentes na janela. Para tanto, v na
opo ToolsConnections Inspector no menu principal do
Interface Builder, onde ser ento apresentado a aba do
Connections Inspector conforme podemos ver na janela do
lado esquerdo presente na Figura 24. Para conectar um
outlet a um componente, basta clicar na bolinha ao lado
do nome da outlet, arrastar e soltar em cima do componente presente na janela da aplicao como apresentado
na Figura 24. Tambm ser necessrio indicar como a
ao btnConverter_clicked dever ser acionada. Para tanto,
devemos conectar esta ao a um evento no boto btnConverter presente na tela. Isso pode ser feito da forma como
est sendo apresentado na Figura 25. O usurio dever
selecionar o boto btnConverter e ento no Connections
Inspector devemos clicar na esferada do lado direito do
evento Touch Down e arrastar o ponteiro do mouse at o
item Files Owner presente dentro do Document Window. Assim, estaremos gerando na classe ConversorViewController
o cdigo da ao btnConverter_clicked que responder ao
evento de toque no boto.

Edio 23 - WebMobile Magazine

51

FileWrite Class Files... presente no menu principal do Interface


Builder conforme apresentado na Figura 27.

Figura 27. Escrevendo arquivos de classes manipuladas pelo Interface Builder.

Feito isso, surgir a seguinte tela exibida na Figura 28 solicitando


o nome do arquivo a ser gerado. Informe o nome da classe, a linguagem utilizada para implementar a classe e se ser gerado o arquivo
de cabealho (com a extensao .h) contendo a declarao da classe.
Aps isso, clique no boto Save para confirmar a operao.
Figura 25. Conectando evento classe controladora.

Na Figura 26 temos uma viso geral de todas as conexes dos


outlets definidos para a janela da aplicao. Tambm temos
uma listagem de todas as aes que esto associadas eventos
especficos de componentes da janela.

Figura 28. Confirmando a gravao dos arquivos.

Figura 26. Todos os outlets conectados aos componentes da janela.

Agora que temos a janela de nossa aplicao devidamente


estruturada com todos os seus componentes, outlets e aes
definidos, ns vamos agora gerar o cdigo desta janela, ou seja,
vamos gerar o cdigo da classe responsvel por coordenar o
funcionamento da janela da aplicao. Para isso, acesse a opo

52

Ao clicar no boto Save, surgir a tela apresentada na Figura


29. Esta tela informa que o arquivo do cdigo de nossa classe
j existe e ento questiona sobre qual o mtodo que vamos
utilizar para sobrescrever o arquivo existente: temos a opo
Merge que nos permite adicionar o cdigo gerado ao cdigo
que j existe no arquivo da classe e tambm temos a opo
Replace que nos permite substituir o arquivo existente por
um novo. No caso desta nossa aplicao de exemplo, ns vamos
escolher a opo Replace, uma vez sendo que no existia ainda
nenhum cdigo de interface nesta classe anteriormente.
Os arquivos ConversorViewController.m e ConversorViewControler.h
sero substitudos por verses geradas pelo Interface Builder.
O contedo de cada um destes arquivos ser apresentado nas
Listagens 1 e 2.
Na Listagem 1 temos a definio da classe associada janela
de nossa aplicao. Podemos perceber nas linha 1 e 2 que dois
arquivos de cabealho esto sendo importados, o primeiro

WebMobile Magazine - Introduo ao desenvolvimento de aplicaes para o iPhone com o iPhone SDK

M OBILE

Listagem 3. Evoluo da classe ConversorViewControler.h

Figura 29. Confirmando a gerao do cdigo.


Listagem 1. Declarao da classe ConversorViewControler.h
1. import <UIKit/UIKit.h>
#
2. import <Foundation/Foundation.h>
#
3. interface ConversorViewController : UIViewController<UIPicker
@
ViewDelegate>{
4.
IBOutlet UIButton
*btnConverter;
5.
IBOutlet UILabel
*lblQuantidade;
6.
IBOutlet UILabel
*lblResultadoConversao;
7.
IBOutlet UILabel
*lblTipoConversao;
8.
IBOutlet UIPickerView *pkvTipoConversao;
9.
IBOutlet UITextField *txtQuantidade;
10. }
11. (IBAction)btnConverter_clicked;
12. @end

Listagem 2. Implementao da classe ConversorViewControler.m


1. import ConversorViewController.h
#
2. implementation ConversorViewController
@
3. (IBAction)btnConverter_clicked {
4.
}
5. end
@

contm a definio de todos os componentes visuais do iPhone (UILabel, UITextField e etc) e o segundo arquivo contm a
definio de classes base do iPhone.
Nas linhas 3 a 12 temos a definio de nossa classe controladora
(ConversorViewController). Na linha 3 estamos declarando a nossa
classe e de quem ela herda. Podemos observar tambm que essa
classe utiliza-se do protocolo UIPickerViewDelegate, que adiciona a
esta classe a capacidade de processar eventos do UIPickerView (que
consiste em um protocolo no Objective-C que o que chamamos
de interface na linguagem Java),especificando mtodos que uma
classe deve implementar. Neste caso, estamos nos referindo a
mtodos que correspondem a eventos de um UIPickerView. Nas
linhas 5 a 10 estamos declarando as variveis dos outlets presentes
na janela da nossa aplicao, indicando tambm a qual componente cada outlet est fazendo referncia. Por ltimo, na linha 11
ns temos a declarao de um mtodo presente nesta classe.
A Listagem 2 contm a implementao da classe que acabamos de declarar.
Na primeira linha estamos importando o arquivo de cabealho que comtm a definio de nossa classe. Nas linhas 2 a
5 onde temos a implementao de nossa classe, sendo que
temos o corpo do mtodo btnConverter_clicked presente nas
linhas 3 a 4.
De posse do cdigo da classe de nossa janela devidamente gerado, ns precisamos agora dar vida nossa aplicao. Para isso,
precisamos fazer algumas modificaes nos cdigo apresentados nas Listagens 1 e 2, conforme descrito na Listagem 3.
Note que diferente do que temos na Listagem 1, a Listagem 3
contm a declarao de trs novas variveis: tiposDeConverso (um

1. import <UIKit/UIKit.h>
#
2. import <Foundation/Foundation.h>
#
3. interface ConversorViewController :
@
UIViewController<UIPickerViewDelegate>{
4.
IBOutlet UIButton
*btnConverter;
5.
IBOutlet UILabel
*lblQuantidade;
6.
IBOutlet UILabel
*lblResultadoConversao;
7.
IBOutlet UILabel
*lblTipoConversao;
8.
IBOutlet UIPickerView *pkvTipoConversao;
9.
IBOutlet UITextField
*txtQuantidade;
10.
NSArray
*tiposDeConversao;
11.
NSInteger
medidaOrigemSelecionada;
12.
NSInteger
medidaDestinoSelecionada;
13. }
14. - (IBAction)btnConverter_clicked;
15. @end

array), medidadeOrigemSelecionada e medidaDestinoSelecionada que


so inteiros. O array contm uma sequncia de strings dos nome
das medidas. O contedo desse array ser exibido no PicketView
para que o usurio selecione uma medida (centmetro, metro,
kilmetro e milha). Ao selecionar uma medida, o nmero da linha
desta medida selecionada no PickerView armazenado na varivel
medidadeOrigemSelecionada ou medidaDestinoSelecionada, dependendo de qual medida est sendo seleciona, de origem ou destino.
Logo abaixo na Listagem 4 temos a implementao completa da classe ConversorViewControler contendo toda lgica
necessria para a seleo das medidas, tal como o cdigo para
clculo da converso.
A primeira linha importa o arquivo de cabealho contendo
a declarao da nossa classe. Na linha 2 comeamos a implementao da classe propriamente dita. Nas linhas 3 a 29 temos
a implementao da ao btnConverter_clicked que responde ao
evento de pressionamento do boto Converter presente na tela
da aplicao. Na linha 3 inicializado uma instncia da classe
NSNumberFormatter. Atravs desta classe possvel converter a
string (NSString) da quantidade informada no UITextField para
um nmero NSNumber conforme ocorre na linha 4. Na linha 5
declaramos uma varivel para guardar o resultado do clculo da
converso. Nas linhas 6 a 23 avaliada qual unidade de origem
e destino o usurio selecionou para realizar o clculo da formula
de converso mais apropriada. Na linha 24 ns recuperamos o
nome da medida de destino selecionada. Nas linhas 25 a 27 ns
ajustamos a forma como o numberFormatter vai formatar o resultado da converso. Por fim, na linha 28 ns estamos convertendo
e formatando o resultado do clculo da converso da medida,
concatenando com um pequeno espao em branco, seguido do
nome da unidade de medida de destino selecionada.
Nas linhas 30 a 37 temos o cdigo do evento que disparado
quando esta tela da aplicao exibida ao usurio. Na linha 33
estamos indicando qual classe contm a implementao dos
eventos relacionados ao PickerView. Esses eventos so utilizados para ajustar a exibio do PickerView na janela. Na linha 34
estamos adicionando o PickerView na janela. E concluindo, na
linha 35 estamos inicializando o array tiposDeConversao, que
contm o nome das unidades de medida. Ele ser utilizado
para gerar o contedo a ser apresentado no PickerView para
que o usurio possa selecionar as medidas de origem e destino
indispensveis para o clculo da converso.
Da linha 38 em diante temos a implementao dos eventos do

Edio 23 - WebMobile Magazine

53

Listagem 4. Cdigo evoludo da classe ConversorViewControler.m


1. import ConversorViewController.h
#
2. implementation ConversorViewController - (IBAction)
@
btnConverter_clicked {
3. SNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
N
4. SNumber *quantidade = [numberFormatter numberFromString:
N
txtQuantidade.text];
5. SNumber *resultado = [NSNumber numberWithFloat: 0.0];
N
6. witch (medidaOrigemSelecionada) {
s
7. ase 0:
c
8. switch (medidaDestinoSelecionada) {
9.
case 0:
10. resultado = quantidade;
11. break;
12.
case 1:
13. resultado =
14.
[NSNumber numberWithFloat:
15.
[quantidade floatValue] * 0.01];
16. break;
17.
default:
18. break;
19. }
20. break;

PickerView, eventos que definem a quantidade de componentes


no PickerView, a quantidade de linhas em cada componente,
o contedo de cada linha de um componente do PickerView,
a largura de um componente do PickerView e a altura de uma
linha dentro de um componente no PickerView. Neste cenrio,
um componente pode tambm ser entendido como uma coluna
dentro do PickerView.
Como o cdigo das outras classes do projeto foram geradas
pelo prprio Xcode, procuramos dar preferncia ao cdigo que
contm a parte mais significativa da aplicao. Caso seja de
interesse, os fontes de todo o projeto encontram-se no portal
da Revista WebMobile.

21. efault:
d
22.
break;
23. }
24. SString *siglaMedidaDestino = [tiposDeConversao objectAtIndex:
N
medidaDestinoSelecionada];
25. numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[
26. [numberFormatter setDecimalSeparator:@,];
27. [numberFormatter setFormat:@0.00000;0.00000;-0.00000];
28. blResultadoConversao.text = [[[numberFormatter
l
stringFromNumber:resultado] stringByAppendingString:@ ]
stringByAppendingString:siglaMedidaDestino];
29.
}
30. (void)viewDidLoad
31.
{
32. self = [super init];
33. pkvTipoConversao.delegate = self;
34. [self.view addSubview:pkvTipoConversao];
35. tiposDeConversao = [[NSArray arrayWithObjects:
36. Cm, @Metros, @Km, @Milhas, nil] retain];
@
37.
}
38. / Eventos do PickerView...
/
39. end
@

selecione a unidade de origem e logo em seguida selecione a


unidade de destino. Por fim, clique no boto Converter para
realizar o clculo da converso.

Compilando a aplicao
Na tela principal do Xcode (Figura 18), clique no boto Build,
conforme apresentado na Figura 30.

Figura 30. Boto para compilar projeto.

Caso ocorra algum erro na compilao do projeto as mensagens de erro sero exibidas na parte de baixo da janela.

Testando nossa aplicao


Na tela principal do Xcode (Figura 18), clique no boto Build
and Go, conforme apresentado na Figura 31.

Figura 32. Aplicao rodando no iPhone Simulator.

Concluses
Neste artigo pudemos perceber que o iPhone possui um SDK
bastante completo. A IDE Xcode em conjunto com o Interface Builder torna o desenvolvimento de aplicaes para o iPhone em algo
bastante intuitivo e simples. Acreditamos que tambm foi possvel
perceber que a linguagem Objective-C bastante extica e requer
algum tempo para aprendizado. Sendo assim, basta agora voc ter a
sua idia e transformar ela em uma aplicao para este celular, pois
as ferramentas voc sabe onde as encontrar e como us-las.
D seu feedback sobre esta edio!

Figura 31. Boto para compilar e executar o projeto.

Caso no ocorra nenhum erro na compilao do projeto, o


iPhone Simulator ser iniciado e a aplicao carregada dentro
do mesmo conforme podemos ver na Figura 32. Para testar,
informe no campo quantidade o valor a ser convertido, ento

54

A Web Mobile tem que ser feita ao seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/webmobile/feedback

WebMobile Magazine - Introduo ao desenvolvimento de aplicaes para o iPhone com o iPhone SDK

Crie seu mini YouTube


Exibindo vdeos em Windows
Presentation Foundation

Resumo do DevMan

De que se trata o artigo


Como criar um projeto XBAP;
Noes bsicas de XAML;
Utilizar os controles do tipo Layout Control;
Data Binding;
MediaElement;
Upload de Arquivos.
Para que serve
A finalidade deste artigo dar ao leitor um breve entendimento de utilizar
os controles de WPF para a reproduo de udio e vdeo.
Em que situao o tema til
Aplicaes multimdia.

J pensou em como o YouTube foi desenvolvido? Neste artigo vamos utilizar recursos do WPF para criar um site semelhante a ele, que permita a incluso de vdeos e
sua visualizao. O WPF traz para o .NET Framework recursos que simplicam a criao de aplicaes que exigem contedo multimdia. Veremos tambm como utilizar
o Linq To Entities para manter a base de dados de vdeos.

WPF, Windows Presentation Foundation foi introduzido


a partir da verso .NET Framework 3.0. Ele representa
a iniciativa da Microsoft para o desenvolvimento de
aplicaes Windows com interfaces ricas, ou seja, aplicaes
que possuam um visual mais aprimorado e que melhore a
experincia do usurio. Alm de ser utilizado para esse fim,
tambm possvel utiliz-lo atravs da WEB. Essa variante
chamada de XBAP, WPF Browser Application.
Uma aplicao XBAP pode ser executada atravs do navegador do cliente como se estivesse instalada localmente. Essa
vantagem possui um custo, exige que na mquina do cliente
esteja instalado o runtime do .NET Framework.
Vamos criar um aplicativo XBAP que funcionar de forma
semelhante ao conhecido You Tube, exibir udio e vdeo. Nele
vamos aplicar alguns recursos especficos do WPF que sero
abordados a seguir.

Download e instalao das ferramentas


Claudio Silva
claudiomsilva2008@hotmail.com

desenvolvedor .Net desde 2005. Cursa Sistemas de Informao na Faculdade


UMC - Villa Lobos. Atualmente trabalha como programador C# Pleno na empresa Computeasy. MCP - Windows Presentation Foundation.

Para que possamos desenvolver nosso exemplo Mini YouTube, precisamos de algumas ferramentas instaladas em nosso
ambiente de desenvolvimento. Basicamente o que precisamos
para desenvolver utilizando o XBAP, :
Microsoft Visual Studio 2008 Service Pack 1: O Microsoft Visual
Studio 2008 Service Pack 1 pode ser encontrado no link msdn.
microsoft.com/pt-br/vstudio/default.aspx. importante lembrar

Edio 23 - WebMobile Magazine

55

Nota do DevMan
A Microsoft no esforo de permitir a seus desenvolvedores a criao de aplicaes com
interfaces ricas, incluiu o WPF em seu .NET Framework. Uma das novidades trazidas a
introduo de scripts em XML para definio das caractersticas da interface. Esse formato
XML envolvido sofreu algumas personalizaes por parte da Microsoft e foi renomeado para
XAML (leia-se zmel). O XAML oferece um forma independente de linguagem de programao de construo de interfaces, permitindo realmente que designers que nunca programaram possam criar uma tima experincia visual sem interferir no cdigo do programa.

que o Visual Studio 2008 em sua verso Express no implementa


o recurso XBAP. No link informado, clique em Experimente o
Visual Studio localizado a esquerda do Web Site. Na tela seguinte
apenas clique em Download it now para ser direcionado a uma
nova tela. Selecione Brasil (Portugus) em ambos ComboBox
para que possamos iniciar o download. Agora clique no boto
Download Trial Software e escolha qual verso baixar. Para esse
artigo ser necessrio clicar em um dos links a direita do site,
ou seja, no grupo Download Visual Studio 2008 SP1. Voc ser
redirecionado a uma pgina, que na verdade uma espcie
de gerenciador de downloads da Microsoft. O download deve
demorar algumas horas, j que o arquivo de instalao do Visual Studio bem razovel em termos de tamanho. Feito isso,
apenas instale seguindo as instrues do setup;
Microsoft SQL Server 2005 Express Edition: Como j sabemos
esse o banco de dados da Microsoft. perfeitamente possvel utilizar essa verso, que gratuita, para escrever nossa
aplicao. Baixe-o e instale. Novamente devo salientar que a
instalao muito simples e rpida. Caso ainda tenha dvidas
sobre a instalao instale-o apenas utilizando as mensagens
padro que aparecero no browser;
Microsoft SQL Server Management Studio: Assim como precisamos do banco de dados, necessitamos tambm de um gerenciador para que possamos fazer as manutenes no BD criado. O
Microsoft SQL Server Management Studio usado para administrar o banco de dado caso no saiba. Ele pode ser encontrado
tambm no link www.microsoft.com/express. No se preocupe,
muito fcil fazer a instalao dele. Apenas siga os passos do
assistente e ter o programa disponvel no seu computador;
.Net Framework 3.5 Service Pack 1: Realmente muito importante ter o Service Pack instalado, pois grande parte do sistema
ser focado em cima disso. O .net Framework 3.5 contm todos
os controles necessrios para fazer o desenvolvimento do
sistema. Ao instalar a verso 2008 do Visual Studio, ele j
automaticamente instalado.

Nota
Todas as ferramentas Express da Microsoft podem ser encontradas no link www.microsoft.com/
express.Voc pode baixar o banco de dados Microsoft SQL Server 2008 Express Edition para utilizar
no exemplo, porm no possvel utilizar a verso Express do Visual Studio 2008 porque nela no
est disponvel o recurso de XBAP. Contudo, pode-se baixar a verso Trial do Visual Studio 2008.

informaes sobre os vdeos existentes. Acesse o menu


Iniciar>Programas>Microsoft SQL Server 2005> SQL Server
Management Studio, uma janela como na Figura 1 ser mostrada ao entrar no gerenciador.

Figura 1. Tela de login do gerenciador

Em Server name digite o nome do servidor, que normalmente


obedece ao formato NOME DA MQUINA\SQLEXPRESS. Em
seguida selecione SQL Server Authentication em SQL Server
Authentication. Digite o login padro, SA, e informe a senha
definida na instalao do SQL Server Express. Feito isso o Microsoft SQL Server Management Studio Express ser aberto com
uma aparncia semelhante Figura 2.

Todos esses arquivos podem ser facilmente encontrados no


site da Microsoft.

Criando o Banco de Dados


Antes de iniciarmos nosso projeto vamos criar a base
de dados que o mesmo ir utilizar. Ser um banco de
dados simples com apenas uma tabela que armazenar

56

WebMobile Magazine - Crie seu mini YouTube

Figura 2. Management Studio Express

ASP. NET

Para criar um novo banco de dados, expanda o item DataBases e em seguida clique com o direito nele. Escolha a opo
New DataBase e d o nome de MyVideosShare. Para criarmos
a tabela basta expandirmos o nosso banco de dados criado
e clicar com o direito em Tables selecionando New Table. Em
seguida uma janela ser aberta e agora precisaremos apenas
incluir os campos e seus atributos necessrios. Vamos criar
junto tabela de Vdeos.
Nas propriedades da tabela, em Name, digite o nome da
tabela, Videos, como pode ser visto na Figura 3.

XBAP - WPF Browser Application: que um projeto para se


executado atravs do navegador do cliente, bastando que o
mesmo tenha instalado em sua mquina um plug-in necessrio.
Esse plug-in est disponvel atualmente para o Internet Explorer
6 ou posterior e para o Firefox 2.

Figura 4. Criando uma tabela no MS SQL Server 2005 EX

Figura 3. Nomeando a tabela

Em seguida criaremos os seguintes campos:


VideoId, que deve ser do tipo Int, no permitir nulo, no se
esquea de marcar o campo como Indentity e tambm como
chave primria da tabela;
TituloVideo, do tipo VarChar de 50 posies e no deve permitir nulo;
PostadoPor, do tipo VarChar de 50 posis e no deve permitir nulo;
DataPost, do tipo DateTime e no deve permitir nulo;
CaminhoVideo, do tipo VarChar de 100 posies e no deve
permitir nulo;
Visualizacoes, do tipo Int, no deve permitir nulo e tendo o
valor padro de 0.
Por fim salve todas as alteraes que realizamos. Nossa tabela
dever se parecer com a Figura 4.

Criando um projeto XBAP


Antes de iniciarmos nossa aplicao, devemos entender o que
exatamente WPF Windows Presentation Foundation e XBAP.
Em WPF existem 3 tipos de projetos que so:
Em WPF existem 3 tipos de projetos que so:
Windows Application: igual a um projeto Windows Forms e sua
instalao feita no lado cliente;
Navigation Application: semelhante a um projeto Windows
Application, ou seja, tambm fica instalado na mquina do
cliente, porm este tipo de projeto no trabalha com janelas e
sim com navegao como na Web;

Se procurarmos no site da Microsoft sobre XBAP, XAML


e WPF, obteremos vrias informaes e definies sobre as
tecnologias citadas. Veja uma delas.
Aplicativos de navegador XAML (XBAPs) combinam recursos de aplicativos de cliente rico e aplicativos da Web. Como
os aplicativos da Web, os XBAPs podem ser publicados em
um servidor Web e iniciados a partir do Internet Explorer.
Como aplicativos de cliente, XBAPs podem aproveitar os
recursos do WPF.
No Visual Studio 2008 utilize o menu File>New Project>Visual
C#>Windows>WPF Browser Application. O name e o solution
name de nossa aplicao ser MyVideosShare, conforme
Figura 5.
Ao clicar no boto OK o Visual Studio cria ento nossa
aplicao. Veja Figura 6.
Conforme podemos ver na Figura 6, so exibidos dois
arquivos, Page1.xaml e Page1.xaml.cs Fazendo uma comparao a um projeto ASP.NET, podemos dizer que enquanto o
arquivo .xaml representa a interface, o arquivo .cs representa
o code-behind.Tambm, de forma semelhana possvel trabalhar em modo visual ou codificar diretamente no .xaml. No
cdigo a seguir temos o contedo inicial do arquivo page1.
xaml, vamos entender um pouco a seu respeito.

Nota do DevMan
Um dos principais mtodos de desenvolvimento de aplicaes Web garantindo uma
total interao com o ambiente atual e visualmente mais parecido com janelas Windows foi o: Windows Forms. H diversos programadores que gostam ou ainda preferem usar-se dessa tecnologia.
A bem da verdade o Windows Forms no chamou muito a ateno do pblico por
isso tem sido deixado de lado h anos. Basicamente, Windows Forms so janelas bem
semelhantes as do prprio Windows. Podemos fazer exatamente todo tipo de aplicao utilizando esse conceito.

Edio 23 - WebMobile Magazine

57

Nota do DevMan
O XAML (pronuncia-se zemel) a nova linguagem de marcao usada para criar
interfaces de usurio de forma simples e rpida. equivalente, porm muito mais poderosa que sua antecessora o HTML.
,
O XAML no uma linguagem em si. Ela exatamente como o XML, que no contm
nenhuma tag especfica, mas apenas as regras para crias suas prprias tags. O XAML
tambm a forma de marcao para acessar o modelo de objetos do novo Windows
Presentation Foundation e voc pode ainda criar seus prprios objetos e acess-los
atravs do XAML.

<Page x:Class=MyVideosShare.Page1
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
Title=Page1>
<Grid>
</Grid>
</Page>

Como j foi mencionado um arquivo .xaml um formato


variante do XML, logo temos tags e uma estrutura em hierarquia representando uma pgina e seus controles visuais.
Observe que o cdigo se inicia com a tag <Page>. Essa a
tag que referencia de que tipo este arquivo, que em nosso
caso uma pgina. Caso estivssemos trabalhando com um
projeto do tipo de Windows Application ela seria <Window>.
A seguir estamos indicando que o formato do arquivo o
xaml/presentation e importando referncia s bibliotecas
padro da Microsoft.
Logo em seguida temos a declarao de um controle de
Layout, o Grid. Veja que ele declarado dentro da tag Page,
indicando que ele faz parte da pgina.

Figura 6. Primeira janela do projeto

58

WebMobile Magazine - Crie seu mini YouTube

Figura 5. Criao do projeto WPF/XBAP

Criando a interface do usurio


Vamos ento criar as telas onde os usurios podero navegar. Nosso projeto ter 3 interfaces que so: a tela inicial, onde
o usurio poder visualizar o vdeo selecionado, vdeos mais
assistidos onde o usurio ir ver o ranking dos vdeos ordenado
pelo quantidade de visualizao e upload, para que o usurio
possa adicionar um novo vdeo.
Para iniciarmos a construo do layout teremos que alterar
o tamanho da nossa pgina para 800x600 e como vimos anteriormente por padro j temos na tela um objeto do tipo Grid.
Esta ser a base do nosso layout.
Vamos dividir o Grid em trs, sendo que na primeira linha
iremos colocar o ttulo da pgina, na segunda o corpo, ou seja,
todo o nosso contedo e na terceira parte vamos colocar uma
barra de status para exibir algumas mensagens do sistema.

ASP. NET

Nota do DevMan
O Windows Presentation Foundation (ou WPF), anteriormente sob o nome de cdigo
Avalon, um subsistema grfico .net Framework 3.0 (anteriormente chamada WinFX),
e est diretamente relacionado ao XAML. WPF est includo com o Windows Vista e
Windows Server 2008, e tambm est disponvel para Windows XP Service Pack 2 ou
superior, e Windows Server 2003. Ele oferece um modelo de programao coerente para
a construo de aplicaes e fornece uma clara separao entre a interface do usurio e
da lgica comercial (regras de negcios).
A WPF pode ser implantado na rea de trabalho ou hospedado em um navegador Web.
Por outro lado, permite controlar o desenvolvimento dos aspectos visuais de programas do
Windows. Ela visa unificar uma srie de servios de aplicao: interface de usurio, desenho
2D e 3D, documentos, tipografia avanada, grficos vetoriais, udio e vdeo. Embora Windows Forms continuar a ser largamente utilizada, e a Microsoft criou apenas algumas aplicaes WPF, a empresa promove WPF para a linha de aplicativos corporativos.

Para definirmos isso em Xaml temos que utilizar a tag Grid.


RowsDefinitions, caso fosse colunas utilizaramos Grid.ColumnsDefinitions. Edite o arquivo Page1.xaml e acrescente na tag
Grid o cdigo a seguir.
<Grid>

<Grid>

<Grid.RowDefinitions>
<RowDefinition Height=112 />
<RowDefinition Height=* />
<RowDefinition Height=30 />
</Grid.RowDefinitions>

Note que dentro de <Grid.RowDefinitions> estamos criando


as trs linhas necessrias e j especificando o seu tamanho.
Para a primeira linha utilizamos a medida de 112 e na terceira
a medida ser de 30, na segunda vamos utilizar o caractere
asterisco, *, para definir que est parte dever ocupar todo
o espao restante.Agora vamos adicionar os elementos que
vamos precisar exibir as finromaes necessrias.
Na primeira linha vamos utilizar um Label para escrever
o nome da pgina, na segunda linha vamos adicionar um
objeto do tipo TabControl e na nossa ltima linha colacaremos
um objeto do tipo StatusBar, teremos ento o seguinte cdigo
XAML conforme Listagem 1:
Listagem 1. Pgina inicial
01 <Grid>
02
<Grid.RowDefinitions>
03
<RowDefinition Height=112 />
04
<RowDefinition Height=* />
05
<RowDefinition Height=30 />
06
</Grid.RowDefinitions>
07
<Label Grid.RowSpan=0 Margin=10 Name=label1
08
HorizontalContentAlignment=Center
09
VerticalContentAlignment=Center BorderThickness=0
10
HorizontalAlignment=Stretch>My Videos Share</Label>
11
12
<TabControl Grid.Row=1 Margin=10 Name=tabGuias >
13
</TabControl>
14
<StatusBar Grid.Row=1 Height=30 Margin=2,0,2,2 Name=sBar
15
VerticalAlignment=Bottom Grid.RowSpan=2>
16
</StatusBar>
17 </Grid>

Veja que estamos definindo controles e suas propriedades


de forma declarativa, no utilizamos aqui cdigo c# para isso.

Nota
Antes de comear a codificao da tela temos que entender que o WPF no se utiliza uma
medida especfica de tamanho como por exemplo, o pixel. Utiliza-se uma medida varivel
que depende da densidade de pixels na tela, ou seja, vamos supor que deixemos o nosso
monitor configurado para 800x600 e definimos um boto de 100x100, este boto ir ocupar
certa proporo da tela. Ento aumentamos a nossa resoluo para 1024x768. Veremos o
mesmo boto ocupando 100x100 de forma proporcional. Se nossa medida de tamanho
fosse em pixels, no importaria a resoluo, o boto teria sempre o mesmo tamanho, porm
como nossa medida em relao a densidade de pixels, vamos perceber que este boto ir
aumentar ou diminuir dependendo da resoluo, ocupando proporcionalmente sempre o
mesmo espao na tela.

Uma propriedade que merece destaque aqui a Grid.RowSpan


que indica em qual linha do Grid o controle ser adicionado. As
linhas de um Grid so indexadas em base 0, ou seja, a primeira
linha possui ndice 0, a segunda 1 e assim por diante. Observe
tambm que os controles so adicionados dentro da tag <Grid>,
indicando a hierarquia, que eles pertencem ao Grid.

Criando a tela de adicionar vdeos


Esta ser uma tela simples contendo poucos campos, mas
ser uma das mais importantes para o nosso sistema, pois ser
a partir desta que os usurios iro adicionar os seus vdeos.
Vamos criar a seguinte estrutura de campos: um campo para
adicionar o caminho para o vdeo, outro para que usurio coloque um ttulo para este vdeo e mais um para que usurio possa
informar um nome para quem est adicionando o vdeo.
Para a criao desta tela no utilizaremos nenhum componente de layout, vamos utilizar a propriedade Margin. Essa
propriedade cria uma distncia entre os controles e a borda da
pgina. Cada controle possui sua propriedade Margin.
Outra coisa extremamente importante que devemos ressaltar
que como iremos trabalhar com abas todos os nossos objetos
estaro em uma pgina s.
Vamos adicionar um novo item em nosso tabControl, que ser
do tipo TabItem. Dentro deste TabItem vamos adicionar um
objeto do tipo Grid e ento vamos adicionar nossos objetos, e
chegaremos ento ao seguinte cdigo XAML da Listagem 2.
Espero que vocs estejam percebendo a flexibilidade e facilidade em se organizar uma tela em WPF. Assim como organizamos
os controles hierarquicamente, assim ser o seu visual final.

Criando a tela de mais assistidos


Est ser a tela mais simples de todo o projeto pois consiste
apenas em um objeto ListBox. Para isso vamos realizar o procedimento parecido com o que fizemos para a tela anterior. Adicionamos mais um objeto TabItem em nosso TabControl. Neste caso
como vamos adicionar somente um objeto dentro deste TabItem
no necessrio a utilizao de nenhum objeto para controlar o
layout, ento basta apenas adicionar o objeto ListBox.
<TabItem Header=Mais Assistidos Name=tabMaisAssitidos>
<ListBox Height=Auto Margin=10
Name=lstMaisAssistidos VerticalAlignment=Stretch />
</TabItem>

Edio 23 - WebMobile Magazine

59

Listagem 2. Tela para adio de vdeos


01 <TabItem Header=Adicionar Video Name=tabAdd>
02
<Grid>
03
<Label Height=28 Margin=125.752,35.725,0,0
Name=label2
04
VerticalAlignment=Top HorizontalAlignment=Left
05
Width=120.234>Caminho do Vdeo:</Label>
06
<TextBox Height=23 Margin=251.504,37.154,204.347,0
07
Name=txtCaminho VerticalAlignment=Top />
08
<Button Height=23 HorizontalAlignment=Right
09
Margin=0,37.154,111.462,0 Name=btnProcurar
10
VerticalAlignment=Top Width=75 >Procurar</
Button>
11
<Label Margin=125.752,81.453,0,0 Name=label3
Height=28.81
12
HorizontalAlignment=Left VerticalAlignment=Top
13
Width=120.234>Ttulo do Vdeo:</Label>
14
<TextBox Height=23 Margin=251.504,82.882,204.347,0
15
Name=txtTitulo VerticalAlignment=Top />
16
<Label Height=28.81 HorizontalAlignment=Left
17
Margin=125.752,130.039,0,0 Name=label4
18
VerticalAlignment=Top Width=120.234>Postado
por:</Label>
19
<TextBox Height=23 Margin=251.504,131.468,204.347,0
20
Name=txtPostadoPor VerticalAlignment=Top />
21
<Button Margin=0,179,205,0 Name=btnAdicionar
22
HorizontalAlignment=Right Width=118.805
Height=50.015
23
VerticalAlignment=Top>Adicionar Vdeo</Button>
24
</Grid>
25 </TabItem>

Criando a tela de visualizao


Esta ser a tela onde os usurios iro assistir aos vdeos que
estiverem no nosso site. Nela vamos utilizar um objeto chamado MediaElement, que o objeto do WPF para a reproduo
de udio e vdeo. Este objeto utiliza-se de recursos do Media
Player 10, ento para que a mquina cliente possa visualizar
os vdeos necessrio que tenha instalado a ltima verso do
Media Player 10 no Windows XP, ou para aqueles que utilizam
o Windows Vista, o Media Player 11.
Vamos agora descrever como ser a nossa tela. Ela ser separada
em duas colunas sendo a primeira onde iremos adicionar o objeto
MediaElement e na segunda parte vamos colocar uma ListBox para
que o usurio possa selecionar o vdeo que deseja assistir.
Mais uma vez repetindo o procedimento das telas anteriores,
vamos adicionar um TabItem ao TabControl. Neste caso como

teremos mais de um objeto dentro do TabItem ser necessrio


a utilizao do objeto Grid para organizar a tela.
Vamos dividi-lo em duas colunas, como mostra a Listagem 3.
Listagem 3. Dividindo o grid ao meio
01 <TabItem Header=Inicio Name=tabInicio>
02
<Grid>
03
<Grid.ColumnDefinitions>
04
<ColumnDefinition Width=* />
05
<ColumnDefinition Width=* />
06
</Grid.ColumnDefinitions>
07
</Grid>
08 </TabItem>

Veja que na definio da largura das colunas no foi especificado nenhum tamanho, apenas informamos o asterisco. Ao
executar a aplicao o Framework quando se deparar com esse
cdigo ir entender que para dividir a largura das colunas
em partes iguais.
Agora vamos adicionar o objeto MediaElement, dando a ele o
nome de mePlayer e ajustando sua margem para 10. Tambm
vamos adicionar um ListBox que ficar localizado na segunda
coluna do grid e vamos definir seu nome como lstVideos.O
cdigo de tudo isso est na Listagem 4.
Listagem 4. Dividindo o grid ao meio
01 <TabItem Header=Inicio Name=tabInicio>
02
<Grid>
03
<Grid.ColumnDefinitions>
04
<ColumnDefinition Width=* />
05
<ColumnDefinition Width=* />
06
</Grid.ColumnDefinitions>
07
<MediaElement Margin=10 Name=mePlayer />
08
<ListBox Grid.Column=1 HorizontalAlignment=Stretch
09
Margin=10 Name=lstVideos Width=Auto />
10
</Grid>
11 </TabItem>

Ao acessarmos o modo de design podemos ver o resultado,


como na Figura 7.

Nota do DevMan
O WPF por ser uma evoluo no desenvolvimento de interfaces, favorece o uso de controles layouts para a organizao e disposio de qualquer controle a ser inserido em uma
janela ou pgina. A vantagem em se utilizar esses controles est no fato de garantirem a
boa esttica da interface por no estarem presos posies fixas em pixels.Dessa forma no
importa com qual resoluo o monitor do cliente vai estar, o visual da sua aplicao sempre
estar organizado. Existem os seguintes controles:
DockPanel Permite ancorar os controles inseridos nele;
StackPanel Ao inserir controles em um StackPanel, os mesmos so empilhados, seja na
vertical ou horizontal;
WrapPanel Realiza uma quebra automtica do controles de acordo com o tamanho disponvel do WrapPanel onde esto inseridos, podendo organiz-los de forma automtica;
Grid Disponibiliza uma organizao de layout no formato tabular, linhas e colunas;
Canvas Utiliza posies fixas, em pixels, para o posicionamento dos controles, similar ao
que existe no windowsforms.

60

WebMobile Magazine - Crie seu mini YouTube

Figura 7. Tela Inicial do site

Trabalhando com Linq To Entities


O Linq To Entities uma evoluo do Linq To SQL, onde o
usurio poderia somente mapear as tabelas do banco de dados
. No Linq To Entities j temos alguns recursos melhorados, um

ASP. NET

exemplo que nele j possvel utilizar o conceito de Herana. Ento para que possamos trabalhar com o Linq To Entities
vamos adicionar ao nosso projeto um arquivo .edmx que o
arquivo de mapeamento da nossa base de dados para o Linq,
Clique com o boto direito do mouse sobre o projeto e selecione
a opo Add>New Item, conforme Figura 8.

nossa string de conexo para o nosso banco de dados. Para


isso clique no boto New Connection e ser mostrada uma
tela como na Figura 10.

Figura 10. Configurando a conexo ao banco de dados

Figura 8. Adicionando um arquivo .edmx

Informe os dados nesta tela conforme as suas configuraes e


ao final, clique em Test Connection para confirmar se os dados
informados esto corretos. Por fim clique em OK. As seguintes
informaes sero exibidas, conforme Figura 11.

Quando o Visual Studio mostrar a tela de Add New Item, selecione


no painel esquerda a opo Data, no painel direita selecione
a opo de ADO.Net Entity Data Model e no campo name digite
EntitiesVideos.edmx, conforme vemos na Figura 9 a seguir.

Figura 9. Adicionando o arquivo EntitiesVideos.edmx

Assim que clicar em Add ser apresentado um assistente


para configurao do nosso mapeamento, como nosso
banco de dados est pronto devemos selecionar a opo
Generate from database. Essa opo ir gerar o mapeamento
objeto/relacional a partir de um banco de dados j criado.
Clicamos ento em Next e na tela seguinte deveremos criar

Figura 11. Escolhendo a conexo com a base de dados

Com a conexo escolhida, o prximo passo selecionar os


objetos do banco de dados que vamos mapear. No nosso caso
como temos apenas uma tabela, vamos expandir a opo Tables,
selecionar a opo Videos e informar qual ser o Namespace,
coforme Figura 12.

Edio 23 - WebMobile Magazine

61

Listagem 5. Adicionando um vdeo

Figura 12. Escolhendo os objetos do banco de dados e finalizando a


criao do arquivo edmx

Ao final de todo esse processo temos o diagrama de classes


que representa as classes mapeadas, como visto na Figura 13.
Esse diagrama a representao visual do arquivo EntitiesVideos.edmx.
Em relao a este arquivo no temos mais nada a fazer, chegou o momento de codificarmos nossas pginas.

01 private void btnAdicionar_Click(object sender, RoutedEventArgs e)


02
{
03
if (String.IsNullOrEmpty(txtCaminho.Text))
04
{
05
lblMessages.Content = Necessrio selecionar
o vdeo.;
06
return;
07
}
08
if (String.IsNullOrEmpty(txtPostadoPor.Text))
09
{
10
lblMessages.Content = Necessrio informar quem est
11
postando o vdeo.;
12
return;
13
}
14
if (String.IsNullOrEmpty(txtTitulo.Text))
15
{
16
lblMessages.Content = Necessrio informar um
ttulo para
17
o vdeo.;
18
return;
19
}
20
21
Videos video = new Videos()
22
{
23
DataPost
= DateTime.Now,
24
PostadoPor = txtPostadoPor.Text,
25
TituloVideo = txtTitulo.Text,
26
Visualizacoes
= 0
27
};
28
29
video.CaminhoVideo = UploadVideo(txtCaminho.Text);
30
31
if (!String.IsNullOrEmpty(video.CaminhoVideo))
32
{
33
using (MyVideosShareEntities1 ent = new
34
MyVideosShareEntities1())
35
{
36
ent.AddToVideos(video);
37
ent.SaveChanges();
38
}
39
LimpaFormUpload();
40
41
lblMessages.Content = Arquivo salvo com sucesso!;
42
}
43
}

Fazendo o upload de vdeos


Vamos agora codificar a nossa tela de incluso de vdeo.
Nela, d um duplo clique no boto Adicionar Vdeo, com isso
ser adicionado o evento de click do boto. Insira no evento o
cdigo da Listagem 5 para tratarmos o envio dos vdeos.

Figura 13. Diagrama exibindo classe mapeada

62

WebMobile Magazine - Crie seu mini YouTube

Observe que antes de realizar o upload do arquivo validamos se


o usurio informou de forma correta o caminho para localizao
do arquivo de vdeo bem como seu ttulo e o nome de quem
est postando. Se tudo isso estiver correto ento instanciamos

ASP. NET

o objeto de tipo Vdeo, que foi gerado pelo Linq. Ento passamos
para esse objeto os valores digitados pelo usurio.
Como pode ser visto temos a chamada de um mtodo chamado UploadVideo() que tem a responsabilidade de carregar o
arquivo para nossa pgina no servidor. Mas antes de mostrar
como ele funciona, temos que criar, definir onde este arquivo
ser gravado no servidor. Neste exemplo estou utilizando
o seguinte caminho, C:\DevMedia\MyVideosShare\Videos,
lembrando que esta pasta dever ter permisso de gravao.
Agora vamos adicionar este caminho como uma configurao
do nosso projeto, clicando com o boto direito no seu projeto
e selecionando Properties. Na guia Settings adicione esta configurao da seguinte forma:
Name = PathOnServer;
Type = string;
Scope = Application;
Value = C:\DevMedia\MyVideosShare\Videos;
Como mostrado na Figura 14.
As configuraes de projeto permitem que possamos armazenar
e recuperar informaes necessrias para o programa de forma
dinmica. Ao determinar que o escopo de visualizao dessa configurao Application isso a torna visvel por todo o projeto.
Voltando agora para o nosso mtodo de upload, temos a
Listagem 6.
Criamos uma instncia da classe WebClient, que disponibiliza mtodos para o evio e recebimento de dados de qualquer
recurso que esteja local, em uma intranet ou na internet. A
seguir criamos o nome do arquivo que ser salvo no servidor
baseando-se na hora atual, isso para evitar que um vdeo
possa sobrescrever outro. Depois verificamos a permisso de
escrita na pasta especificada na configurao do sistema. Para
verificarmos as permisses de acesso a uma pasta utilizamos

Listagem 6. Mtodo UploadVideo()


01 private String UploadVideo(String pathCliente)
02
{
03
System.Net.WebClient myWebClient = new
04
System.Net.WebClient();
05
string fileName =string.Format
({0}\\{1:yyyyMMddHHmmss}.wmv,
06
Settings.Default.PathOnServer,
DateTime.Now);
07
08
try
09
{
10
FileIOPermission fp = new
11
FileIOPermission
(FileIOPermissionAccess.Write,
12
Settings.Default.PathOnServer);
13
fp.Demand();
14
15
myWebClient.UploadFile(new Uri(fileName),
pathCliente);
16
}
17
catch (Exception ex)
18
{
19
lblMessages.Content = ex.Message;
20
fileName = string.Empty;
21
}
22
23

return fileName;

a classe FileIOPermission, onde informamos qual permisso


que queremos verificar e a pasta onde deve verificar e ento
utilizamos o mtodo Demand() para verificar essa permisso.
Caso o usurio no tenha a permisso requerida este mtodo
ir lanar uma Exception, caso contrrio continuar o andamento normal do projeto.
O processo de upload bem simples, basta informar o caminho do arquivo de origem e o destino do mesmo para o
mtodo UploadFile().
Para facilitar a utilizao do usurio na localizao de
arquivos de vdeo a enviar, temos o boto Localizar que ir
exibir uma caixa de dilogo que permitir a busca. O WPF
no trabalha nativamente com nenhuma caixa de dilogo do
sistema operacional, necessrio adicionar uma referncia

Figura 14. Adicionando a configurao

Edio 23 - WebMobile Magazine

63

System.Windows.Forms. Feito isso, o normal seria referencila tambm na seo using, contudo se fizermos isso alguns
conflitos surgem com com outros namespaces do WPF. D um
duplo clique no boto adicionar e ser criado o evento Click,
nele adicionamos o cdigo da Listagem 7.

Nota
Poderamos utilizar tambm o UploadFileAsync() que tem a mesma funo do UploadFile(),
porm funciona de uma forma assncrona, ou seja no necessrio esperar a execuo desse
mtodo para continuar o processo, ele executado em segundo plano.
Listagem 8. DataTemplate

Listagem 7. Permitindo a localizao de um arquivo


01 private void
02
{
03
04
05
06
07
08
09
10
11
12
13
14
}

btnProcurar_Click(object sender, RoutedEventArgs e)


System.Windows.Forms.OpenFileDialog oDialog = new
System.Windows.Forms.OpenFileDialog();
oDialog.Multiselect = false;
System.Windows.Forms.DialogResult dResult =
oDialog.ShowDialog();
if (dResult == System.Windows.Forms.DialogResult.OK)
{
txtCaminho.Text = oDialog.FileName;
}

Uma instncia da classe OpenFileDialog criada. Veja que foi


preciso informar o namespace completo, System.Windows.Forms,
isto porque no adicionamos esse namespace na seo using.
Tambm especificamos nas propriedades do OpenFileDialog
que no permitido selecionar vrios arquivos simultaneamente. Ento exibidos o dilogo e armazenamos seu resultado
na varivel dResult para sabermos se o usurio selecionou
algum arquivo ou cancelou o processo.
Para finalizar vamos ver o mtodo LimpaUploadForm(), que
nada mais que limpar os campos que utilizamos para gravar
os dados do vdeo, conforme a seguir:
private void LimpaFormUpload()
{
txtCaminho.Clear();
txtPostadoPor.Clear();
txtTitulo.Clear();
}

Visualizando os vdeos mais assistidos


Aqui vamos exibir os vdeos ordenados pela quantidade de
visualizaes que obtiveram. necessrio primeiramente especificarmos como esses dados sero apresentados na pgina.
Eles sero listados em um ListBox, porm com WPF possvel
especificar at mesmo a aparncia desses dados dentro do
ListBox. Isso feito utilizando o recurso de DataTemplate.
Um DataTemplate especifica como os dados de um determinado
tipo sero visualizados. Para permitir a reutilizao deles em todo
o projeto podemos agrup-los em resources, que funcionam como
um ponto nico para organizar e manter esses templates.
Vamos criar um resource ento adicionando a tag Page.Resources logo antes da declarao do Grid. Na Listagem 8 vemos
nosso DataTemplate.
Neste DataTemplate adicionamos um StackPanel e dentro dele trs
objetos Label,e dentro de cada Label outro objeto do tipo WrapPanel,
mas para isso devemos adicionar a tag Label.Content. Em WPF,
diferentemente de aplicaes windows forms o Label possui uma
propriedade Content que pode receber tanto um texto normal
quanto outros objetos, podendo assim existir controles dentro
de controles. Tendo ento adicionado o WrapPanel adicionamos
dentro dele outros dois objetos do tipo TextBlock, sendo que no

64

WebMobile Magazine - Crie seu mini YouTube

01 <Page.Resources>
02
<DataTemplate x:Key=tmpListas>
03
<StackPanel>
04
<Label>
05
<Label.Content>
06
<WrapPanel HorizontalAlignment=Stretch>
07
<TextBlock>Ttulo: </TextBlock>
08
<TextBlock Text={Binding
TituloVideo} />
09
</WrapPanel>
10
</Label.Content>
11
</Label>
12
<Label>
13
<Label.Content>
14
<WrapPanel HorizontalAlignment=Stretch>
15
<TextBlock>Postado por: </TextBlock>
16
<TextBlock Text={Binding PostadoPor} />
17
</WrapPanel>
18
</Label.Content>
19
</Label>
20
<Label>
21
<Label.Content>
22
<WrapPanel HorizontalAlignment=Stretch>
23
<TextBlock>Postado em: </TextBlock>
24
<TextBlock Text={Binding DataPost} />
25
</WrapPanel>
26
</Label.Content>
27
</Label>
28
</StackPanel>
29
</DataTemplate>
30
</Page.Resources>

segundo ligamos sua propriedade Text propriedade DataPost.


Essa ligao feita atravs do mecanismo de databinding, que
permite ligar objetos comuns controles visuais. Para aplicarmos o DataTemplate ao ListBox vamos fazer uso da propriedade
ItemTemplate. Nela especificamos qual o template para a exibio
dos dados. Isso pode ser visto no cdigo a seguir.
<ListBox ItemTemplate={StaticResource tmpListas}
ItemsSource={Binding} Height=Auto Margin=10
Name=lstMaisAssistidos VerticalAlignment=Stretch />

Assim ento falta adicionarmos a codificao para exibirmos


os dados. Vamos utilizar o evento de SelectionChanged do objeto
TabControl para que sempre que o usurio mude de aba visualize os dados atualizados. Selecione o TabControl , pressione F4
para que sejam visualizadas suas propriedades. Acesse a guia
de eventos e d um duplo clique em SelectionChanged. e vamos
adicionar o cdigo da Listagem 9.
Observe que verificamos qual o TabItem ativo e de acordo
com isso chamamos um mtodo respectivo. Caso o TabItem
selecionado seja o referente aos vdeos mais assistidos o mtodo
BindingMaisAssistidos() executado.
BindingMaisAssistidos() seleciona os dados que vamos utilizar
no nosso ListBox. Este um mtodo muito simples, utilizando o
Linq vamos selecionar todos os vdeos ordenados por visualizaes e adicionar no DataContext, conforme cdigo a seguir.
private void BindMaisAssistidos()
{
lstMaisAssistidos.DataContext = from vi in Entities.Videos
orderby vi.Visualizacoes
descending
select vi;
}

ASP. NET

Listagem 9. SelectionChanged

Listagem 10. Adicionando o vdeo ao MediaElement

01 private void tabGuias_SelectionChanged(object sender,


02 SelectionChangedEventArgs e)
03
{
04
if (e.AddedItems[0] is TabItem)
05
{
06
if
07 (((TabItem)e.AddedItems[0]).Name.Equals(tabMaisAssitidos))
08
{
09
BindMaisAssistidos();
10
}
11
else if
12 (((TabItem)e.AddedItems[0]).Name.Equals(tabAdd))
13
{
14
LimpaFormUpload();
15
}
16
else
17
{
18
BindInicio();
19
}
20
}
21
}

01 private void lstVideos_SelectionChanged(object sender,


02 SelectionChangedEventArgs e)
03
{
04
Videos vi = e.AddedItems[0] as Videos;
05
if (vi != null)
06
{
07
mePlayer.Source = new Uri(vi.CaminhoVideo);
08
using (MyVideosShareEntities1 ent = new
09 MyVideosShareEntities1())
10
{
11
vi.Visualizacoes++;
12
ent.SaveChanges();
13
}
14
}
15
}

Em WPF no temos mais o DataSource como comum em


aplicaes Asp.Net. Temos agora o DataContext que representa
uma fonte de dados que pode ser ligada a um controle ou at
mesmo prpria Page.
Aqui a parte que deve ser comentada a codificao do Linq
from vi in Entities.Videos orderby vi.Visualizacoes descending select
vi; Como podemos ver no difere muito de como trabalharamos
com SQL, o que muda um pouco a ordem dos comandos. Fazendo um comparativo, em SQL teramos a seguinte instruo
select * from Videos order by Visualizacoes desc.

Criando a tela Inicial


Agora vamos trabalhar na nossa tela inicial. Para lembrar, ela
constituda de um objeto do tipo MediaElement e um ListBox. Ao
ListBox devemos adicionar o mesmo template que adicionamos no
ListBox da tela anterior. Para isso realize o mesmo procedimento
de adicionar a propriedade ItemTemplate e ItemsSource, tambm
deveremos adicionar o evento de SelectionChanged para verificarmos quando for selecionado outro item da lista.
Como vimos anteriormente no evento de SelectionChanged
do TabControl temos um mtodo chamado BindInicio(). Este
mtodo bem parecido com o mtodo que fizemos chamado
BindingMaisAssistidos(), a nica diferena que no BindInicio()
no iremos ordenar por visualizaes e sim pelo campo DataPost.
Assim teremos o seguinte cdigo:
private void BindInicio()
{
lstVideos.DataContext = from vi in Entities.Videos
orderby vi.DataPost descending
select vi;
}

Agora vamos codificar o evento SelectionChanged do ListBox,


que consiste em verificarmos o item selecionado, conforme
Listagem 10.
Com a informao que ser retornada pela varivel SelectionChangedEventArgs do tipo object, teremos que realizar um cast
dele para Videos. Ento verificamos se este cast foi bem sucedido,
caso tenha sido adicionamos o caminho do vdeo como Source no
MediaElement. Tambm incrementamos as visualizaes deste
vdeo e o salvamos novamente, utilizando o Linq.

Com isso nosso player j est funcionando, voc poder


testar pressionando a tecla F5 no seu Visual Studio. Para testar
adicione um novo vdeo e mude para a tela inicial e clique
nele para visualizar a sua execuo.
Antes de finalizarmos o projeto temos que adicionar mais
um evento ao objeto MediaElement, que o evento de MediaFailed. Codificar esse evento se faz necessrio pois o objeto
MediaElement e nenhum dos outros objetos de reproduo de
udio disparam excees quando no conseguem executar
um arquivo. Sempre que houver um problema com o arquivo
de mdia, impedindo sua reproduo, esse evento disparado
e nele podemos tratar qualquer inconveniente. Para nosso
projeto vamos apenas exibir uma mensagem de que ocorreu
um erro e qual foi o erro.
Para adicionar este evento clique no MediaElement e no painel de propriedades acesse os eventos. Ento d um duplo
clique em MediaFailed, assim teremos o seguinte cdigo:
private void mePlayer_MediaFailed(object sender,
ExceptionRoutedEventArgs e)
{
lblMessages.Content = Ocorreu um erro ao tentar abrir o
arquivo selecionado. Erro: + e.ErrorException.Message;
}

Concluso
Como podemos ver, trabalhar com vdeos em WPF muito
simples, no requerendo muita codificao. Dependendo da
forma que ser apresentado o vdeo talvez no seja preciso
nenhuma linha de cdigo, porm trabalhamos com este objeto
de uma forma bem superficial, temos dentro dele recursos
para criar os botes de Play, Pause, Stop. Podemos controlar a
velocidade de execuo do vdeo, volume do udio e muitas
outras propriedades.
Aqui vimos tambm como simples o processo para realizar
um upload de arquivos para o servidor e por fim vimos um
pouco de Linq To Entities, que um recurso muito interessante
de se utilizar.
D seu feedback sobre esta edio!
A Web Mobile tem que ser feita ao seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/webmobile/feedback

Edio 23 - WebMobile Magazine

65

Maximize a qualidade
do seu cdigo
Como medir o quanto o seu teste
unitrio cobre do cdigo

De que se trata o artigo


O que um teste unitrio;
O que o Code Coverage;
Exemplo prtico de desenvolvimento com Code Coverage.
Para que serve
Maximizar a qualidade do cdigo atravs do teste unitrio e avaliar possveis
potenciais de falhas e sombras do teste unitrio.
Em que situao o tema til
Em qualquer desenvolvimento de sistema, utilizando teste unitrios, seja
web, mbile ou desktop.

Thomas Alexander Semple


thomas.semple@t4w.com.br

26 anos, engenheiro eletrnico com nfase em telecomunicaes e lder


de projetos da T4W, com mais de 10 anos de experincia, participa de projetos para empresas dos mais diversos segmentos. A T4W uma empresa
de tecnologia cuja rea de desenvolvimento atende empresas de mdio e
grande porte em projetos corporativos e especiais. Thomas Alexander Semple tambm escreve para a .net Magazine da DevMedia e colunista de um
portal de tecnologia.

66

WebMobile Magazine - Maximize a qualidade do seu cdigo

Resumo do DevMan
Desenvolver um sistema perfeito o ideal de todo programador e o sonho de cada
cliente. Neste artigo vamos ver como aproximar seu desenvolvimento de um cdigo
ideal atravs de uma anlise baseada em exemplos e testes.
Usaremos NUnit e NCover para efetuar os testes e verificar o quo simples utilizar-se de testes unitrios.

ualidade no desenvolvimento algo primordial no


sucesso de qualquer projeto, mas como garantir que
o cdigo entre em produo com o menor nmero de
erros possvel? Independente da plataforma, seja .net, Java, ou
outras, como detectar rapidamente algum possvel defeito de
modo que seja possvel corrigir rapidamente?
Caso voc ainda no conhea, em linhas gerais, testes unitrios so mtodos que testam trechos de cdigo. Estes mtodos
de testes nunca sero utilizados diretamente pelo usurio final,
porm garantir que o que foi desenvolvido, est sem erro (ou
pelo menos com o menor nmero de erro possvel).
Um dos estilos de programao o TDD(Test Driven Development). Neste estilo de desenvolvimento recomenda-se fazer
o teste unitrio antes de desenvolver as classes e mtodos,
depois rodar os testes. Como as classes e mtodos no foram
implementados, todos os testes tero falhas.
Depois de desenvolver os mtodos necessrios, rodam-se
os testes novamente e verificamos se o resultado positivo.

ASP. NET

Caso o resultado seja negativo, corrigem-se os erros, at obter


sucesso em todos os processos.
Muitos j conhecemos e utilizamos testes unitrios, porm
mesmo com testes unitrios existem brechas que podem gerar buraco no cdigo, deixando algum trecho no testado e
que provavelmente ser descoberto apenas em produo, a
famosa lei de Murphy.
Neste artigo pretendo mostrar no o que um teste unitrio,
mas sim como fazer uma anlise do seu teste e como identificar
trechos de cdigos no testados (sombras), e fazer uma anlise
atravs de exemplos de como podemos melhorar a qualidade
do cdigo durante o desenvolvimento. Neste artigo utilizei a
plataforma .net, porm convido todos os programadores de
outras plataformas a lerem este artigo, pois mais do que uma
plataforma, pretendo mostrar uma anlise de desenvolvimento
que possa ser utilizada em qualquer desenvolvimento, seja
web, mbile ou desktop, independente da linguagem.

Mo na massa!
Vamos supor o seguinte cenrio: estamos fazendo um sistema
corporativo. Somos os responsveis pela camada cliente contida neste sistema. Este objeto o responsvel por representar
todos os clientes da corporao. Para este desenvolvimento,
utilizei o Visual Studio 2005 com VB.NET. Outras verses poderiam ser utilizadas.
Abra ento o Visual Studio e crie um projeto de classe. Na

Listagem 1, temos um exemplo de uma classe bastante simples.


Logo no comeo da classe existe uma enumerao com o tipo
do cliente. De acordo com a especificao da suposta equipe
comercial o cliente pode receber cinco nveis. O primeiro nvel
indefinido, ou seja, quando o tipo do cliente no est definido
pela equipe comercial. O segundo tipo um cliente direto, ou
seja, quando a empresa fornece diretamente para o cliente.
O terceiro tipo indireto, quando a empresa fornece servios
para o cliente atravs de uma outra empresa. Neste caso nossa
empresa sub-contratada. O quarto quando o cliente um
ex-cliente. Por algum tempo possua algum vnculo com a
empresa, mas por algum motivo deixou de ter relacionamento comercial. Por fim temos os prospects. Estes so possveis
futuros clientes.
Em seguida encontra-se o campo de identificao do cliente
(ID). Normalmente um campo de auto numerao do banco
de dados. Definimos tambm informaes cadastrais como
Nome, CNPJ, Endereo, Numero, CEP, Identificao do pas (PaisID)
e identificao da cidade (CidadeID). Como nosso sistema possui
uma rea de acesso aos clientes (rea imaginria) temos um
status de ativo. A propriedade ativo recebe um valor booleano
de verdadeiro ou falso. Temos tambm uma propriedade que
define o tipo do cliente, de acordo com a enumerao criada
no incio da Listagem 1.
No construtor da classe (Linha 134) o mtodo limpar invocado, para garantir que as propriedades estejam como valor

Listagem 1. Classe de cliente cliente.vb


1Public Class Cliente
2#Region Propriedades
3 Public Enum enumTipoCliente
4 [Indefinido] = 0
5 [Direto] = 1
6 [Indireto] = 2
7 [ExCliente] = 3
8 [Prospect] = 4
9 End Enum
10 Private m_iID As Integer
11 Public Property ID() As Integer
12 Get
13 Return m_iID
14 End Get
15 Set(ByVal value As Integer)
16 m_iID = value
17 End Set
18 End Property
19 Private m_sNome As String
20 Public Property Nome() As String
21 Get
22 Return m_sNome
23 End Get
24 Set(ByVal value As String)
25 m_sNome = value
26 End Set
27 End Property
28 Private m_sCNPJ As String
29 Public Property CNPJ() As String
30 Get
31 Return m_sCNPJ
32 End Get
33 Set(ByVal value As String)
34 m_sCNPJ = value
35 End Set
36 End Property
37 Private m_sEndereco As String
38 Public Property Endereco() As String
39 Get
40 Return m_sEndereco
41 End Get
42 Set(ByVal value As String)

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

m_sEndereco = value
End Set
End Property
Private m_sNumero As String
Public Property Numero() As String
Get
Return m_sNumero
End Get
Set(ByVal value As String)
m_sNumero = value
End Set
End Property
Private m_sCEP As String
Public Property CEP() As String
Get
Return m_sCEP
End Get
Set(ByVal value As String)
m_sCEP = value
End Set
End Property
Private m_iPaisID As Integer
Public Property PaisID() As Integer
Get
Return m_iPaisID
End Get
Set(ByVal value As Integer)
m_iPaisID = value
End Set
End Property
Private m_iCidadeID As Integer
Public Property CidadeID() As Integer
Get
Return m_iCidadeID
End Get
Set(ByVal value As Integer)
m_iCidadeID = value
End Set
End Property
Private m_bAtivo As Boolean

...

Edio 23 - WebMobile Magazine

67

Continuao da Listagem 1. Classe de cliente cliente.vb


83 Public Property Ativo() As Boolean
84 Get
85 Return m_bAtivo
86 End Get
87 Set(ByVal value As Boolean)
89 m_bAtivo = value
90 End Set
91 End Property
92 Private m_eTipo As enumTipoCliente
93 Public Property Tipo() As enumTipoCliente
94 Get
95 Return m_eTipo
96 End Get
97 Set(ByVal value As enumTipoCliente)
98 m_eTipo = value
99 End Set
100 End Property
101 Private m_iNotaCliente As Integer
102 Public ReadOnly Property NotaCliente() As Integer
103 Get
105 If m_iID > 0 Then
106 calcularNota()
107 End If
108 Return m_iNotaCliente
109 End Get
110 End Property
111 Private m_dInvestimentoMensal As Double
112 Public Property InvestimentoMensal() As Double
113 Get
114 Return m_dInvestimentoMensal
115 End Get
116 Set(ByVal value As Double)
117 m_dInvestimentoMensal = value
118 End Set
119 End Property
120 Private m_dRetornoMensal As Double
121 Public Property RetornoMensal() As Double
122 Get
123 Return m_dRetornoMensal
124 End Get
125 Set(ByVal value As Double)

Figura 1. Janela Add Reference

padro sempre que uma nova instncia do cliente criada. Na


linha 145 existe um mtodo chamado validarEmail. Este mtodo
utiliza uma expresso regular que valida se o e-mail vlido
ou no. Caso seja vlido, retornado um valor True.
O ltimo mtodo o da linha 156, chamado calcularNota.
Neste mtodo atribuda uma nota ao cliente, a formula 10
sobre o tipo de cliente vezes o retorno mensal que o cliente
prove sobre o investimento que a empresa tem com ele. Com

68

WebMobile Magazine - Maximize a qualidade do seu cdigo

126 m_dRetornoMensal = value


127 End Set
128 End Property
129#End Region
130#Region Mtodos
131 Public Sub New()
132 limpar()
133 End Sub
134 Public Sub limpar()
135 m_eTipo = enumTipoCliente.Indefinido
136 m_bAtivo = False
137 m_iCidadeID = 0
138 m_iPaisID = 0
139 m_sCEP = String.Empty
140 m_sNumero = String.Empty
141 m_sEndereco = String.Empty
142 m_sCNPJ = String.Empty
143 m_sNome = String.Empty
144 m_iNotaCliente = 0
145 m_dInvestimentoMensal = 0
146 m_dRetornoMensal = 0
147 End Sub
148 Public Function validarEmail(ByVal sEmail As String) As
Boolean
149 Dim bRetorno As Boolean = False
150 If Text.RegularExpressions.Regex.IsMatch(sEmail, _
151 \w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*) Then
152 bRetorno = True
153 End If
154 Return bRetorno
155 End Function
156 Private Sub calcularNota()
157 If m_dInvestimentoMensal > 0 Then
158 m_iNotaCliente = math.round(((10/m_eTipo)
*m_dRetornoMensal),2)/
159
m_dInvestimentoMensal)
160 End If
161 End Sub
162#End Region
163End Class

Figura 2. Adicionando referncia .dll nunit.framework.dll

este mtodo a suposta equipe comercial consegue priorizar e


classificar os melhores clientes. Apesar de bem simples, esta
classe nos d a base que precisamos para a anlise.
Aps criar a classe de clientes, vamos criar o teste unitrio.
Utilizei o NUnit, uma biblioteca muito boa e Open Source para
a plataforma .NET que pode ser baixada atravs do endereo
www.nunit.org. Instalei tambm um plug-in para o Visual Studio,
que vm com um software para anlise da cobertura do teste

ASP. NET

unitrio, chamado NCover. O plug-in pode ser baixado atravs


do site www.testdriven.net.
Adicione uma nova classe no seu projeto chamada TesteCliente.vb, de modo anlogo ao feito no arquivo anterior. Clique com
o boto direito do mouse em cima do projeto e selecione Add
Reference.. (Figura 1). Adicione uma referncia para a DLL
nunit.framework.dll, conforme Figura 2. Na classe TesteCliente.
vb adicione o cdigo da Listagem 2.
Na linha 01 da Listagem 2 importamos a biblioteca do NUnit
cuja referncia .dll foi adicionada ao projeto. Na linha 11 adicionamos um mtodo que testa as propriedades, indicando que
ele um mtodo somente de teste (linha 10). Este teste bastante
simples, para que possamos focar na anlise de como medir o
quanto o nosso teste est cobrindo o cdigo. A partir da linha
15, crio uma varivel para cara propriedade da classe Cliente
e atribuo valores fictcios. A partir da linha 28 so atribudos
os respectivos valores s propriedades do objeto cliente. Aps
atribuir os valores, como: Nome, Endereo, CNPJ, entre outros,
feita uma verificao se o valor atribudo o mesmo utilizando
o mtodo Assert.AreEqual. Este mtodo do teste unitrio garante
que os valores so iguais e foi utilizado de forma a garantir
que as propriedades esto sendo atribudas e recuperadas de
forma satisfatria. Vamos agora rodar o teste.
Como tenho instalado o plug-in TestDriven, com um acesso
rpido clicando com o boto direito em cima da soluo consigo selecionar o software de teste unitrio que desejo utilizar.
Selecione a opo NUnit, a ltima verso que voc tiver instalada na sua mquina, conforme Figura 3. Uma janela, similar
a Figura 4 ir se abrir.
Na treeview do lado direito ser apresentada uma lista de
todos os mtodos do teste unitrio que voc criou. Ao lado
esquerdo desta treeview h um boto Run, clique neste boto e
aguarde o processamento do teste. Caso os testes tenham passado, uma indicao com tudo verde ir aparecer no resultado.
Caso haja alguma falha, um resultado vermelho aparecer com
a mensagem de erro. Corrija o erro, e rode novamente at obter
um resultado positivo.
Aps um resultado positivo, inicialize o NCover. Clique com
o boto direito do mouse em cima do projeto, em Solutuion
Explorer, assim como foi feito para inicializar o NUnit. Selecione
a opo Teste With e em seguida Coverage (Figura 5). O NCover
outro excelente software para verificar o quanto o teste unitrio
cobre o cdigo. Aguarde o processamento at que uma janela
similar Figura 6. Note que porcentagens de o quanto o teste
unitrio cobriu o cdigo aparecem ao lado de cada classe e
mtodo desenvolvido. Neste teste tivemos uma cobertura de
83% da classe de cliente. No lado direito podemos observar o
cdigo da classe com uma marcao vermelha ou azul.
A Marcao azul indica que o teste passou pelo trecho de
cdigo, como por exemplo, a propriedade Investimento Mensal.
J a propriedade NotaCliente est marcada com vermelho, indicando que o teste no cobre este trecho de cdigo. Isto pode
ser um potencial de falha e aconselhvel fazer um teste que
cubra o maior nmero de trechos possveis. Porm o bom senso deve ser seguido. Caso haja algum cdigo antigo, que no

est mais sendo utilizado, no prioritrio test-lo, porm a


porcentagem no atingir a marca de 100% de cobertura. Mais
para frente ser feita uma anlise da real importncia de cobrir
o cdigo com 100% de teste.

Figura 3. Selecione NUnit para testar a classe

Figura 4. Resultado do teste unitrio

Figura 5. Inicializando o Code Coverage

Edio 23 - WebMobile Magazine

69

Figura 6. Resultado do Code Coverage

Agora que fizemos a classe de cliente, e o teste unitrio que


testa as propriedades, vimos que a cobertura do teste de 83%
do cdigo, ao rodar o NCover. Para atingir os 100% temos que
criar mais dois testes, um que testa o clculo da nota do cliente,
e outro que testa a validao do e-mail dos contatos do cliente.
Na Listagem 3, podem-se observar os novos testes necessrios. Estes mtodos devem estar no mesmo arquivo do outro
teste, TesteCliente.vb. O primeiro teste o verificarNotaCliente,
que testa se os clculos para todos os tipos de clientes esto
conforme especificado. Para este teste criada uma instncia
para cada tipo de cliente, definida pela enumerao criada na
Listagem 1. Em seguida so atribudos valores hipotticos ao
investimento mensal para com o cliente (adotamos o valor 10)
e o retorno mensal que o cliente prov empresa (adotamos

o valor 80). Em seguida feita uma verificao se o resultado


do mtodo o esperado. Veja que embora os valores sejam os
mesmos, para todas as simulaes de clientes, a nota muda de
acordo com o tipo de cliente, o que est coerente com a frmula,
visto que o tipo faz parte da equao.
Embora este teste seja bem simples, ele garante que futuramente se houver alterao no mtodo, os resultados permaneam os mesmo. Caso o resultado mude, o desenvolvedor
forado a verificar se a frmula realmente mudou, ou se ele
cometeu algum engano na lgica.
O segundo e ltimo mtodo de teste o que valida se o e-mail
atende a uma expresso regular. Embora o cliente no tenha
e-mail, estou supondo que haja outro objeto de contatos para o
cliente, e o e-mail do contato submetido antes esta validao.
No cenrio hipottico no estamos responsveis pela criao
do objeto de contatos.
Para testar o e-mail, so feitas duas verificaes, a primeira
se o teste acusa algum e-mail que no existe. O resultado do
mtodo deve ser false, ou no deve ser true, conforme teste da
linha 56. Em seguida um e-mail real (o meu) submetido ao
teste, e neste caso deve trazer um resultado positivo.
Agora que criamos todos os mtodos, repetimos o teste no NUnit para assegurar que esteja tudo 100%. Em seguida rodamos
novamente o NCover. O resultado agora de 100% de teste. Nosso
cdigo no tem trecho no testado, conforme Figura 7.

Testar 100% do cdigo garantia


de uma sistema perfeito?
Ser que testar 100% do cdigo garantia de um sistema a
prova de falhas? Ns fizemos a classe de cliente, criamos um
teste que cobre 100% do cdigo isto deve significar que o nosso
cdigo est perfeito, correto?
O sistema ento colocado em produo e os diretores da
empresa comeam a utiliz-lo. Logo nas primeiras horas de

Listagem 2. Primeiro teste unitrio teste das propriedades


1Imports NUnit.Framework
2
3<TestFixture()> _
4Public Class TesteCliente
5
6 <summary>
7 Mtodo que verifica todas as propriedades
8 </summary>
9 <remarks></remarks>
10 <Test(description:=Mtodo que testa as propriedades)> _
11 Public Sub verificarPropriedades()
12 Dim oCliente As New Cliente
13
14 Variveis com valores de teste
15 Dim eTipo As Cliente.enumTipoCliente = Cliente.
enumTipoCliente.Direto
16 Dim bAtivo As Boolean = False
17 Dim iCidadeID As Integer = 15
18 Dim iPaisID As Integer = 78
19 Dim sCEP As String = 04032-010
20 Dim sNumero As String = N 12B
21 Dim sEndereco As String = Rua do lado direito
22 Dim sCNPJ As String = 111.111.111/1111-11
23 Dim sNome As String = timo Cliente S/A
25 Dim dInvestimentoMensal As Double = 10578.45
26 Dim dRetornoMensal As Double = 754547.02
27
28 Atribuo as propriedades para testar
29
oCliente.ID = iID
30 oCliente.Tipo = eTipo

70

WebMobile Magazine - Maximize a qualidade do seu cdigo

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

oCliente.Ativo = bAtivo
oCliente.CidadeID = iCidadeID
oCliente.PaisID = iPaisID
oCliente.CEP = sCEP
oCliente.Numero = sNumero
oCliente.Endereco = sEndereco
oCliente.CNPJ = sCNPJ
oCliente.Nome = sNome
oCliente.InvestimentoMensal = dInvestimentoMensal
oCliente.RetornoMensal = dRetornoMensal

Recupero os valores para verificar se esto


conforme os valores atribudos
Assert.AreEqual(oCliente.ID, iID)
Assert.AreEqual(oCliente.Tipo, eTipo)
Assert.AreEqual(oCliente.Ativo, bAtivo)
Assert.AreEqual(oCliente.CidadeID, iCidadeID)
Assert.AreEqual(oCliente.PaisID, iPaisID)
Assert.AreEqual(oCliente.CEP, sCEP)
Assert.AreEqual(oCliente.Numero, sNumero)
Assert.AreEqual(oCliente.Endereco, sEndereco)
Assert.AreEqual(oCliente.CNPJ, sCNPJ)
Assert.AreEqual(oCliente.Nome, sNome)
Assert.AreEqual(oCliente.InvestimentoMensal,
dInvestimentoMensal)
55 Assert.AreEqual(oCliente.RetornoMensal, dRetornoMensal)
56
57 End Sub

ASP. NET

Listagem 3. Novos testes de TesteCliente.vb: Testes dos mtodos da classe cliente


1 <summary>
2 Mtodo que verifica testa a nota do cliente
3 </summary>
4 <remarks></remarks>
5 <Test(description:=Mtodo que teste a nota do cliente)> _
6 Public Sub verificarNotaCliente()
7 Dim oCliente As Cliente
8
9 Teste de calculo da nota do cliente direto
10 oCliente = New Cliente
11 oCliente.ID = 10
12 oCliente.InvestimentoMensal = 10
13 oCliente.RetornoMensal = 80
14 oCliente.Tipo = Cliente.enumTipoCliente.Direto
15 Assert.AreEqual(oCliente.NotaCliente, 80)
16
17 Teste de calculo da nota do cliente indireto
18 oCliente = New Cliente
19 oCliente.ID = 11
20 oCliente.InvestimentoMensal = 10
21 oCliente.RetornoMensal = 80
22 oCliente.Tipo = Cliente.enumTipoCliente.Indireto
23 Assert.AreEqual(oCliente.NotaCliente, 40)
24
25 Teste de calculo da nota do cliente ex-cliente
26 oCliente = New Cliente
27 oCliente.ID = 12
28 oCliente.InvestimentoMensal = 10
29 oCliente.RetornoMensal = 80
30 oCliente.Tipo = Cliente.enumTipoCliente.ExCliente
31 Assert.AreEqual(oCliente.NotaCliente, 27)

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

Teste de calculo da nota do prospect


oCliente = New Cliente
oCliente.ID = 13
oCliente.InvestimentoMensal = 10
oCliente.RetornoMensal = 80
oCliente.Tipo = Cliente.enumTipoCliente.Prospect
Assert.AreEqual(oCliente.NotaCliente, 20)

End Sub
<summary>
Mtodo que verifica testa a validao do e-mail.
</summary>
<remarks></remarks>
<Test(description:=Mtodo que teste a validao do e-mail)> _
Public Sub verificarValidacaoEmail()
Dim oCliente As New Cliente
Dim bResultado As Boolean
Teste de quado no for email vlido
bResultado = oCliente.validarEmail(NaoEmail)
Assert.AreNotEqual(True, bResultado)
Teste de quado for email vlido
bResultado = oCliente.validarEmail(thomas.semple@t4w.com.br)
Assert.AreEqual(True, bResultado)
End Sub

Neste caso uma boa prtica criar um teste unitrio com o


cliente com o tipo indefinido. Na Listagem 4, criamos este novo
teste no mtodo verificarNotaCliente do arquivo TesteCliente.vb.
Rode o teste e veja-o falhar (Figura 8). Em seguida corrija o
mtodo de clculo, colocando uma validao para que m_eTipo
seja maior que zero, conforme Listagem 5. Rode o teste novamente, agora o resultado deve ser 100% com sucesso! Coloquei
o mtodo antigo como obsoleto, por uma questo didtica.
Com este exemplo aprendemos que mesmo com 100% de
cobertura de teste no estamos com um software perfeito. Isto,
pois o usurio pode sempre realizar alguma operao que no
foi prevista no teste, ou ento o hardware pode se comportar
de maneira no usual, enfim, dificilmente conseguiremos fazer
um teste que verifique todas as probabilidades de combinaes
de entradas e estado do software.
Listagem 4. Novo teste que detecta o erro reportado, parte do teste
verificarNotaCliente

Figura 7. 100% de cobertura pelo teste unitrio, anlise do code coverage

uso do sistema voc recebe uma solicitao de suporte com um


erro no relatrio de cliente. Surpreendido, voc ento comea
a analisar o erro e se depara com uma diviso por zero. Todos
sabem que diviso por zero resulta em infinito. Como teste,
pegue uma calculadora e divida qualquer nmero por zero.
O resultado ser um erro, ou uma indicao de infinito. Em
softwares o mesmo erro ocorre. Mas como o nosso sistema
gerou um erro, se testamos tudo? Estamos 100% cobertos!
Depois de uma intensa anlise voc verifica que alguns cadastros esto com o tipo de cliente definido como indefinido.
O valor da enumerao para o tipo indefinido zero, como a
frmula da nota do cliente possu uma diviso pelo valor da
enumerao do tipo do cliente, ocorre uma diviso por zero e
conseqentemente um erro levantado.

1
2
3
4
5
6
7

Teste de calculo da nota do prospect


oCliente = New Cliente
oCliente.ID = 14
oCliente.InvestimentoMensal = 10
oCliente.RetornoMensal = 80
oCliente.Tipo = Cliente.enumTipoCliente.Indefinido
Assert.AreEqual(oCliente.NotaCliente, 0)

Um pouco de filosofia
Por que ento utilizar teste unitrio e verificar se ele cobre 100%
do cdigo se mesmo assim no garantia de um sistema perfeito?
Esta uma excelente pergunta. Muitos dizem que desenvolver
software uma arte. Outros dizem que uma cincia. Eu prefiro
acreditar que o software existe para facilitar a vida de outras
pessoas, para impulsionar negcios ou para reduzir custos. Ns
programadores investimos horas e horas para que outras pessoas
economizem, para que elas possam fazer operaes mais fceis,
e dedicar-se no que realmente so boas em fazer.

Edio 23 - WebMobile Magazine

71

Figura 8. Resultado do teste para reproduzir o erro reportado pelo cliente

Listagem 5. Correo do erro, Cliente.vb


<...>
157 <summary>
158 Nota Cliente
159 </summary>
160 <remarks></remarks>
161 Private m_iNotaCliente As Integer
162 Public ReadOnly Property NotaCliente() As Integer
163 Get
164 Calculo a nota
165 If m_iID > 0 Then
166 calcularNotaCorreta()
167 End If
168 Return m_iNotaCliente
169 End Get
170 End Property
<...>
260 <summary>
261 Mtodo que calcula a nota do cliente, para
262 efeitos comerciais
263 </summary>
264 <remarks></remarks>
265 <Obsolete()> _
266 Public Sub calcularNota()
267
268 neste mtodo atribuda uma nota ao cliente
269 a formula 10 sobre o tipo de cliente vezes
270 o retorno mensal que o cliente prove sobre o
271 investimento que a empresa tm com ele.
272 If m_dInvestimentoMensal > 0 Then
273 m_iNotaCliente = Math.Round(((10 / m_eTipo) *
m_dRetornoMensal) / m_dInvestimentoMensal, 0)
274 End If
275
276 End Sub
277
278 <summary>
279 Mtodo que calcula a nota do cliente, para
280 efeitos comerciais
281 </summary>
282 <remarks></remarks>
283 Private Sub calcularNotaCorreta()
284
285 neste mtodo atribuda uma nota ao cliente
286 a formula 10 sobre o tipo de cliente vezes
287 o retorno mensal que o cliente prove sobre o
288 investimento que a empresa tm com ele.
289 If m_eTipo > 0 And m_dInvestimentoMensal > 0 Then
290 m_iNotaCliente = Math.Round(((10 / m_eTipo) * m_d
RetornoMensal) / m_dInvestimentoMensal, 0)
291 End If
292
293 End Sub

72

WebMobile Magazine - Maximize a qualidade do seu cdigo

Criar software com erro no ajuda nenhum usurio, pelo


contrrio, ele perde tempo e depois precisa achar outras maneiras de solucionar o problema enquanto o suporte corrige as
falhas. Ao mesmo tempo, prestar suporte um tempo perdido
que poderia estar sendo utilizado em novos desenvolvimentos
ou melhorias.
Dependendo do erro, pode-se custar centenas se no milhares
de reais para o cliente. Talvez muito mais do que o investimento
para a criao do sistema. Imagine agora se o sistema controlar
um avio, ou estiver monitorando a vida de um paciente em
um hospital, o que um erro no pode causar.
Seja o tipo do software que estiver sendo desenvolvido, seja
um blog, um site, um sistema mobile, ou um sistema que movimenta bilhes de reais diariamente temos que fazer o possvel
para torn-lo com o mnimo de erros possveis, e caso eles
existam, possam ser facilmente detectados e corrigidos.
Os usurios esto cada vez mais acostumados a utilizar sistemas gratuitos de excelente qualidade, seja webmail, site de
notcia, mecanismos de busca, rede de relacionamento entre
muitos outros. Quando algum paga por um sistema, ou mnimo que a pessoa espera que seja melhor do que o sistema
gratuito que utiliza.

Code Covarage com Ant e Nant


O Ant uma ferramenta de script muito conhecida pelos
desenvolvedores Java que ganhou sua verso para .Net com o
Nant. O Ant permite automatizar processos como de publicao
de pginas, rodar testes unitrios entre outros. A base de toda
a configurao um arquivo XML. possvel, por exemplo,
rodar o teste unitrio e se estiver sem erros, automaticamente
publicar a aplicao em uma FTP. Na Listagem 6 podemos
observar um exemplo bastante simples. Nas primeiras linhas
so definidas algumas propriedades, como o endereo da

ASP. NET

Listagem 06. CodeCovarage com N-ant

Concluso

<project default=code-coverage>
<property value=.\NCover\Resultado.xsl name=ncover.
stylesheet/>
<property value=C:\Arquivos de programas\NCover\ncover.
console.exe name=ncover.executable/>
<property value=.\NUnit\nunit-console.exe name=nunit.
console/>
<property value=C:\MeusProjetos\Solucoes name=projects.
output.dir/>
<target name=code-coverage>
<foreach property=test.assembly.folder item=Folder>
<in>
<items>
<include name=${projects.output.dir}\*Test/>
</items>
</in>
<do>
<regex input=${test.assembly.folder}
pattern=^.*(\\/)(?asmregex.*)$>
<property value=${asmregex} name=assembly.test.
name/>
<property value=${string::replace(asmregex,.
Test,)}name=assembly.under.test.name/>
<property value=${projects.output.dir}\${assembly.
test.name}\bin\Debug\${assembly.test.name}.dll
//l Reports\Coverage.Log //a ${assembly.under.
test.name} name=ncover.path.arg/>
<exec commandline=${nunit.console} ${ncover.path.
arg} program=${ncover.executable}/>
<style style={ncover.stylesheet}
out=Reports\${assembly.under.test.name}-Coverage.html
in=Coverage.xml$>
</do>
</foreach>
</target>
</project>

Mesmo cobrindo todo o cdigo com testes, isso no garante


que o seu sistema est a prova de falhas, pois testar todas
as combinaes de estados do software algo muito difcil,
se no impossvel.
Desenvolver sistemas sem erro deve ser uma meta de cada
desenvolvedor. Quando o desenvolvimento em equipe,
fundamental que cada desenvolvedor faa sua parte sem
erro, e com a mxima qualidade possvel, para que quando o
cdigo for unido com outras partes, eles possam se encaixar
que cause a menor dor de cabea possvel.
O Visual Studio Team Edition tambm possui recursos de
testes unitrios e cobertura do teste que podem ser explorados. Existem inmeras outras ferramentas e bibliotecas
tambm auxiliam em processos de testes, inclusive objetos
Mock e Stubs. Caso voc ainda no conhea, fica uma dica
de estudo.
Para desenvolvedores Java, existem ferramentas consagradas, recomendo acessar o link: java-source.net/open-source/
code-coverage. O importante em desenvolvimento de cdigo
no a ferramenta utilizada, mas sim o resultado final
disponvel para o cliente.
Forte Abrao e at o prximo artigo!

planilha com o resultado do teste unitrio (Resultado.XLS), o


caminho fsico da aplicao do console do NCover e o caminho
fsico do console do NUnit, software responsvel em rodar o
teste unitrio.
Em seguida definido um lao de repetio responsvel em
rodar cada teste unitrio e atribuir o resultado a um relatrio.
Apesar do foco deste artigo no ser a utilizao do NAnt, podemos ver como possvel tirar proveito do Code-Coverage em
automatizao de processos.

D seu feedback sobre esta edio!


A Web Mobile tem que ser feita ao seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/webmobile/feedback

Edio 23 - WebMobile Magazine

73

Manipulao de dados
atravs do Silverlight
com Astoria
Criao de proxy para o ADO.NET
Data Services com IUpdatable para
Silverlight

Resumo do DevMan
De que se trata o artigo
Implementao da interface IUpdatable;
Criao de servios ADO.NET (Web Service REST);
Criao de um proxy para manipulao de servios ADO.NET;
Como consumir e manipular informaes atravs do Silverlight de forma assncrona.
Para que serve
Manipular informaes atravs do Silverlight com servios ADO.NET de forma assncrona.
Em que situao o tema til
Em projetos j em produo que no utilizam o Entity Framework e que
precisam consumir informaes atravs de web service.

Thomas Alexander Semple


thomas.semple@t4w.com.br

27 anos, engenheiro eletrnico com nfase em telecomunicaes e lder


de projetos da T4W, com mais de 10 anos de experincia, participa de projetos para empresas dos mais diversos segmentos. A T4W uma empresa
de tecnologia cuja rea de desenvolvimento atende empresas de mdio e
grande porte em projetos corporativos e especiais. Alm da Web Mobile,
Thomas escreve para a .Net Magazine, tambm da DevMedia, e grandes
portais de tecnologia.

74

Em meio a tantas tecnologias existentes no mercado escolher uma que melhor


se adapta a nossa necessidade acaba sendo uma tortura no dia-a-dia j que somos
obrigados (de maneira positiva) a estudar todas elas. O problema que vou exporar
aqui nesse artigo est totalmente relacionado a integrao de dados entre diferentes tecnologias. Como fazer uso de um Proxy para consumir informaes e servios
do ADO.NET e com SilverLight?
Vamos a fundo na tecnologia e usar o que h de mais recente no mercado. Vamos
fazer a criao de um proxy para acesso servios ADO.NET com Silverlight e implementao da interface IUpdatable.

Microsoft est lanando cada vez mais recursos, como


a famlia LINQ, Entity Framework, Silverlight, ADO.NET
data service (Astoria), entre outros. muito difcil incorporar em um sistema j em funcionamento os novos recursos
que vo surgindo. Neste artigo quero mostrar como ter um meio
termo entre as novas tecnologias e o seu sistema legado.
Faremos uma aplicao bem simples, como a base de trocas
de mensagens por um chat. A idia no fazer um chat 100%
funcional, com todos os recursos, mas sim mostrar como implementar a interface IUpdatable, criar o servio Astoria, criar
o proxy e interagir com o Silverlight.

Conceitos iniciais: REST, IUpdatable e Entity Framework


Antes de comearmos a por a mo na massa, vamos alinhar
alguns conceitos. Dois tipos de servios web muito utilizados
so os baseados em SOAP (Simple Object Access Protocol), que est
voltado a chamadas a mtodos atravs de um protocolo. O REST
(Representational State Transfer), muito conhecido do mundo Ruby
e Java, foi incorporado de modo nativo a plataforma .NET com
o ADO.NET Data Service, codinome Astoria. O REST em linhas

WebMobile Magazine - Manipulao de dados atravs do Silverlight com Astoria

asp.net

www.devmedia.com.br/webmobile

Acesse agora mesmo o portal do assinante WebMobile e veja uma vdeo aula de Rodrigo Sendin que mostra
como instalar e criar um modelo objeto-relacional utilizado o Entity Framework.
http://www.devmedia.com.br/articles/viewcomp.asp?comp=9472

Nota do DevMan
O JSON, ou JavaScript Object Notation, um formato leve para troca de informaes. Ele fcil de ser compreendido sem o auxlio de sistemas especficos. Baseado
em um subconjunto do JavaScript, sua estrutura fcil de ser analisada pelos mais
diversos sistemas e tecnologias como Java, Ruby, .NET e Delphi. Isso porque constitudo de texto simples, que completamente ignorante s linguagens de desenvolvimento. Por isso uma forma ideal de realizar intercmbio de informaes entre
sistemas distintos onde seria impossvel uma troca direta.

Figura 1. Crie uma nova soluo em Branco no Visual Studio

Figura 3. Novo projeto Silverlight Aplication

por ter um casamento muito bom. Porm, isto nem sempre


possvel em uma aplicao no mundo real, pois normalmente
existe muito cdigo legado que no utiliza o Entity Framework.
Assim, necessrio implementar a interface IUpdatable.
O IUpdatable por sua vez, uma interface que permite inserir ou
atualizar registros atravs do HTTP POST e pertence ao namespace
System.Data.Services, permitindo assim que dados provenientes
da aplicao Silverlight sejam atualizados ou inseridos.
Figura 2. Adicione um novo website soluo

gerais, utiliza-se dos mtodos do prprio http para manipulao


de informaes, como o mtodo GET, POST, PUT e DELETE.
As URLs devem por si s, trazer todas as informaes necessrias da requisio, ou seja, no pode haver informaes
salvas no cliente e no servidor que mantenha o estado. Em
suma, no permitido utilizao de cookie e session para manter
o estado da requisio. Um usurio deve poder enviar o endereo para outra pessoa, que visualizar as mesmas informaes.
Logicamente que as questes de autenticao e privacidade da
informao devem ser levadas em conta. Mais adiante veremos
como tratar a questo da segurana.
As informaes fornecidas pelo REST podem ser representadas por JSON ou ATOM (XML), definidos atravs do contenttype. O content-type do HTTP define o tipo do contedo da
resposta, como por exemplo, HTML, JPG, XML, entre outros.
O Entity Framework permite abstrair a base de dados em classes
e entidades, sendo possvel efetuar as operaes de consulta,
insero, atualizao e excluso de registros. O Entity Framework
o modo mais imediato quando se pensa em utilizar o Astoria,

Mos obra
Para criar um sistema utilizando o Astoria necessrio instalar o .net 3.5 SP1 do .NET Framework e do Visual Studio 2008. Para
efetuar o download procure por Download .net 3.5 sp1 no seu
mecanismo de busca favorito, ou acesse o site da Microsoft.
Abra o Visual Studio e crie uma nova soluo em branco,
utilizando o Framework 3.5, conforme a Figura 1.
Adicione um novo Web Site na soluo, conforme Figura 2.
Tambm utilize o Framework 3.5 e a linguagem VB.NET. Se
quiser desenvolver em C# fique a vontade. Nomeie o Web Site
de ChatSLWS. Adicione agora mesma soluo o projeto chamado SL, conforme Figura 3.
Observe que selecionamos um projeto do tipo Silverlight. Na
prxima tela, deixe do modo padro, de forma a vincular a
aplicao Silverlight ao Web Site.
Para continuar o desenvolvimento, necessrio verificar se
todas as referncias s bibliotecas externas esto corretas. Na
Figura 4, exibo todas as referncias necessrias para o Website.
Caso alguma esteja faltando ao seu projeto, adicione-a clicando com o boto direito em cima do projeto, e selecionando
a opo Add Reference.

Edio 23 - WebMobile Magazine

75

Figura 4. Adicione as referncias que faltarem no seu projeto, no website

O projeto Silverlight tambm precisa de referncias. Adicione a


referncia System.Windows.Controls.Data, conforme Figura 5.

para poder implementar IUpdatable. A seguir criada a classe


Mensagens que implementa a interface IUpdatable. Se voc escrever Implements IUpdatable e pressionar enter, diversos mtodos
necessrios para a implementao sero criados.
A seguir so definidas as variveis de lista de conversa, m_cMensagens e o caminho do arquivo, m_sArquivoXML. Note que este
caminho baseado no endereo fsico da aplicao, concatenado
com o nome do arquivo XML. Da mesma forma definimos o
caminho do arquivo schema do XML, Mensagens.xsd. A ltima varivel interna criada o DataTable de mensagens m_dtMensagens.
A nica propriedade da classe a lista de mensagens. Esta lista
definida como somente leitura, do tipo IQueryable, permitindo

Listagem 1. Classe de conversa do arquivo Conversa.vb da aplicao WEB

Figura 5. Adicione System.Windows.Controls.Data na aplicao SL

Verifique se todas as referncias esto corretamente adicionadas conforme Figura 6.

Criando a classes e interface IUpdatable


Agora que nosso ambiente est pronto para codificao,
adicione o arquivo Conversa.vb na pasta /app_code/ da aplicao
WEB. Na Listagem 1 so definidas as propriedades da classe
Conversa, como data e hora em que a mensagem foi enviada, a
mensagem, identificao do usurio que enviou a mensagem
e a identificao da mensagem.
Esta classe bem simples, e auxiliar ao funcionamento da
classe mensagens definida a seguir.
A classe de mensagens a responsvel pela insero e listagem das mensagens. Veja seu cdigo na Listagem 2.
Nas primeiras linhas da Listagem 2 so importadas as bibliotecas System.Data.Services, System.IO.File, System.Reflection
e para System.IO.File foi criado o apelido Arquivo, tudo isso

76

Public Class Conversa


Private m_dDataHora As String
Public Property DataHora() As String
Get
Return m_dDataHora
End Get
Set(ByVal value As String)
m_dDataHora = value
End Set
End Property
Private m_sMensagem As String
Public Property Mensagem() As String
Get
Return m_sMensagem
End Get
Set(ByVal value As String)
m_sMensagem = value
End Set
End Property
Private m_iUsuarioID As Integer
Public Property UsuarioID() As Integer
Get
Return m_iUsuarioID
End Get
Set(ByVal value As Integer)
m_iUsuarioID = value
End Set
End Property
Private m_iID As Integer
Public Property ID() As Integer
Get
Return m_iID
End Get
Set(ByVal value As Integer)
m_iID = value
End Set
End Property
End Class

WebMobile Magazine - Manipulao de dados atravs do Silverlight com Astoria

asp.net

Figura 6. Referncias da aplicao SL.


Listagem 2. Classe Mensagem.vb : Propriedades e mtodos
Imports System.Data.Services
Imports Arquivo = System.IO.File
Imports System.Reflection
Public Class Mensagens
Implements IUpdatable
#Region Prorpriedades e variveis internas
Private Shared m_cMensagens As List(Of Conversa)
Private m_sArquivoXML As String = _
HttpContext.Current.Server.MapPath(.) & \Mensagens.XML
Private m_sArquivoXSD As String = _
HttpContext.Current.Server.MapPath(.) & \Mensagens.xsd
Dim m_dtMensagens As New System.Data.DataTable
Public ReadOnly Property Mensagens() As IQueryable(Of Conversa)
Get
Return m_cMensagens.AsQueryable()
End Get
End Property
#End Region
#Region Mtodos
Public Sub New()
If Not Arquivo.Exists(m_sArquivoXML) Or Not
Arquivo.Exists(m_sArquivoXSD) Then
criarXML()
Else
m_dtMensagens.ReadXmlSchema(m_sArquivoXSD)
m_dtMensagens.ReadXml(m_sArquivoXML)
End If
m_cMensagens = New List(Of Conversa)
carregarMensagens()
End Sub
Public Sub criarXML()
Dim dcMensagens As Data.DataColumn
Dim drMensagem As Data.DataRow
m_dtMensagens.TableName = Mensagens
dcMensagens = New Data.DataColumn(System.Int32)
dcMensagens.ColumnName = ID
dcMensagens.AutoIncrementSeed = 0

que as mensagens sejam filtradas pelo Astoria.


O prximo passo criar os mtodos da classe. O primeiro
mtodo o construtor da classe. Neste mtodo feita uma
verificao se os arquivos XML e XSD existem. Caso existam,
o DataTable efetua a leitura do schema e dos registros respectivamente. Caso no existam, eles so criados com o mtodo
criarXML(). Em seguida a lista de mensagens recebe os valores
dos registros, atravs do mtodo carregarMensagens().
O prximo mtodo criarXML() bem simples. Inicialmente
criado um DataColumn que simboliza as colunas do registro,

dcMensagens.AutoIncrementStep = 1
dcMensagens.Unique = True
m_dtMensagens.Columns.Add(dcMensagens)
dcMensagens = New Data.DataColumn(System.String)
dcMensagens.ColumnName = Mensagem
m_dtMensagens.Columns.Add(dcMensagens)
dcMensagens = New Data.DataColumn(System.DateTime)
dcMensagens.ColumnName = DataHora
m_dtMensagens.Columns.Add(dcMensagens)
dcMensagens = New Data.DataColumn(System.Int32)
dcMensagens.ColumnName = UsuarioID
m_dtMensagens.Columns.Add(dcMensagens)
drMensagem = m_dtMensagens.NewRow
drMensagem(ID) = m_dtMensagens.Rows.Count + 1
drMensagem(Mensagem) = Ol, seja bem vindo ao chat!
drMensagem(DataHora) = Date.Now
drMensagem(UsuarioID) = 1 sistema
m_dtMensagens.Rows.Add(drMensagem)
If Not Arquivo.Exists(m_sArquivoXSD) Then
m_dtMensagens.WriteXmlSchema(m_sArquivoXSD)
End If
If Not Arquivo.Exists(m_sArquivoXML) Then
m_dtMensagens.WriteXml(m_sArquivoXML)
End If
End Sub
Public Sub carregarMensagens()
For Each dr As Data.DataRow In m_dtMensagens.Rows
Dim oMensagem As New Conversa
oMensagem.ID = CType(dr(ID), Integer)
oMensagem.DataHora = CType(dr(DataHora), DateTime)
oMensagem.Mensagem = Convert.ToString(dr(Mensagem))
oMensagem.UsuarioID = CType(dr(UsuarioID), Integer)
m_cMensagens.Add(oMensagem)
Next
End Sub
#End Region

como ID, Mensagem, DataHora e UsuarioID. Note que estes so os


mesmos nomes utilizados na classe de Mensagem, criada na Listagem 1. Para cada informao necessrio criar uma nova coluna
e adicion-la ao DataTable. A primeira coluna criada o ID. Seu
tipo Int32 e definido como nico e autoincrement de 1 em 1.
Depois de criar de forma anloga as colunas eu crio uma
mensagem inicial, caso o arquivo ainda no exista. Por fim salvo
o schema e o arquivo XML, de acordo com o caminho definido
no incio da classe.
Por fim criado o mtodo carregarMensagens(), responsvel

Edio 23 - WebMobile Magazine

77

por popular a lista de mensagens com os registros contidos


no XML. Neste mtodo, para cada linha no DataTable, criada
uma nova conversa, atribudo os valores para cada propriedade
da classe e adicionada lista de mensagens.
Note que o que fizemos at aqui foi reproduzir de forma
bem simples uma camada de acesso a dados. Talvez a nica
novidade at aqui tenha sido a propriedade IQueryable. A
seguir, veremos como criar os mtodos responsveis pela
implementao da classe IUpdatable.
Se voc pressionou a tecla Enter depois de ter definido a
implementao de IUpdatable no incio da Listagem 2, deve
ter reparado que diversos mtodos foram automaticamente
criados. Estes mtodos so inteis se no programarmos seu
contedo. Na Listagem 3 vemos a implementao.
Na Listagem 3 temos o mtodo setValue() que recupera a
propriedade atravs de reflection, utilizando GetType, setando
depois o valor para a propriedade. O mtodo CreateResource()
cria o objeto atravs de reflection tambm utilizando GetType,
adicionando depois mensagem para a lista de mensagens

na memria. DeleteResource remove a mensagem da lista. Um


dos mtodos mais interessantes o GetResource(). Ele utiliza um
enumerador e atravs de um loop verifica o objeto desejado.
Caso haja algum erro referente ao fullTypeName uma exceo
do tipo DataServiceException disparada. Caso no haja erro o
resultado com a enumerao retornado na funo.
O mtodo GetValue() recupera a propriedade tambm atravs
de reflection e retorna o valor da mesma. O prximo mtodo
o ResolveResource(). Este mtodo na verdade no faz nada, s
retorna o recurso. SaveChanges() o responsvel por salvar a
mensagem no arquivo XML. No incio deste mtodo verifico
se a mensagem ainda no existe no XML, atravs de um loop.
Se a varivel bAdicionar for verdadeira, uma nova linha do
DataTable criada. Cada propriedade atribuda s colunas no
DataRow. O DataRow ento atribudo ao DataTable. Para que a
informao seja salva no XML o mtodo WriteXml() chamado
passando como parmetro o caminho fsico do arquivo.
Os prximos cinco mtodos possuem um throw exeption, pois
no so necessrios para o exemplo deste artigo, mas devem ser

Listagem 3. Classe Mensagem.vb : Implementao do IUpdatable


#Region IUpdatable
Public Sub SetValue(ByVal targetResource As Object, _
ByVal propertyName As String, _
ByVal propertyValue As Object) _
Implements
System.Data.Services.IUpdatable.SetValue
Dim targetType As Type = targetResource.[GetType]()
Dim [property] As PropertyInfo =
targetType.GetProperty(propertyName)
[property].SetValue(targetResource, propertyValue, Nothing)
End Sub
Public Function CreateResource(ByVal containerName As String, _
ByVal fullTypeName As String) _
As Object Implements _
System.Data.Services.IUpdatable.CreateResource
Dim objType = Type.[GetType](fullTypeName)
Dim resourceToAdd = Activator.CreateInstance(objType)
m_cMensagens.Add(DirectCast(resourceToAdd, Conversa))
Return resourceToAdd
End Function
Public Sub DeleteResource(ByVal targetResource As Object) _
Implements System.Data.Services.IUpdatable.
DeleteResource
m_cMensagens.Remove(DirectCast(targetResource, Conversa))
End Sub
Public Function GetResource(ByVal query As System.Linq.
IQueryable, _
ByVal fullTypeName As String) As
Object _
Implements
System.Data.Services.IUpdatable.GetResource
Dim result As Object = Nothing
Dim enumerator = query.GetEnumerator()
While enumerator.MoveNext()
If enumerator.Current IsNot Nothing Then
result = enumerator.Current
Exit While
End If
End While
If fullTypeName IsNot Nothing AndAlso _
Not fullTypeName.Equals(result.[GetType]().FullName) Then
Throw New DataServiceException()
End If
Return result
End Function
Public Function GetValue(ByVal targetResource As Object, _
ByVal propertyName As String) _
As Object Implements
System.Data.Services.IUpdatable.GetValue
Dim targetType = targetResource.[GetType]()
Dim targetProperty = targetType.GetProperty(propertyName)
Return targetProperty.GetValue(targetResource, Nothing)
End Function
Public Function ResolveResource(ByVal resource As Object) _
As Object Implements _
System.Data.Services.IUpdatable.ResolveResource
Return resource

78

End Function
Public Sub SaveChanges() Implements
System.Data.Services.IUpdatable.SaveChanges
Dim drMensagem As Data.DataRow
Dim bAdicionar As Boolean = False
For Each oConversa As Conversa In Mensagens
bAdicionar = True
For Each drConversaSalva As Data.DataRow In
m_dtMensagens.Rows
If drConversaSalva(ID) = oConversa.ID Then
bAdicionar = False
Exit For
End If
Next
If bAdicionar Then
drMensagem = m_dtMensagens.NewRow
drMensagem(ID) = m_dtMensagens.Rows.Count + 1
drMensagem(DataHora) = oConversa.DataHora
drMensagem(Mensagem) = oConversa.Mensagem
drMensagem(UsuarioID) = oConversa.UsuarioID
m_dtMensagens.Rows.Add(drMensagem)
End If
Next
m_dtMensagens.WriteXml(m_sArquivoXML)
End Sub
Public Sub SetReference(ByVal targetResource As Object, ByVal
propertyName As String, ByVal propertyValue As Object) Implements
System.Data.Services.IUpdatable.SetReference
Throw New NotImplementedException()
End Sub
Public Sub AddReferenceToCollection(ByVal targetResource As
Object,
ByVal propertyName As String, ByVal resourceToBeAdded As Object)
Implements System.Data.Services.IUpdatable.
AddReferenceToCollection
Throw New NotImplementedException()
End Sub
Public Sub ClearChanges() Implements
System.Data.Services.IUpdatable.ClearChanges
Throw New NotImplementedException()
End Sub
Public Sub RemoveReferenceFromCollection(ByVal targetResource
As
Object, ByVal propertyName As String, ByVal resourceToBeRemoved
As
Object) Implements
System.Data.Services.IUpdatable.RemoveReferenceFromCollection
Throw New NotImplementedException()
End Sub
Public Function ResetResource(ByVal resource As Object) As
Object
Implements System.Data.Services.IUpdatable.ResetResource
Throw New NotImplementedException()
End Function
#End Region
End Class

WebMobile Magazine - Manipulao de dados atravs do Silverlight com Astoria

asp.net

mantidos para que a implementao de IUpdatable seja possvel.

Criando o servio Astoria


Para que tudo funcione perfeitamente, teremos que criar um
servio utilizando Astoria. A criao do servio se d criando
um arquivo .svc que conter as instrues de funcionamento.
Ns fazemos isso adicionando um arquivo ADO.NET Data
Service chamado Chat.svc, como mostra a Figura 7.
Este arquivo permite expor os dados atravs de XML e
permcite sua manipulao. Aps adicionado o arquivo, automaticamente criado outro arquivo com a classe do Astoria,
em chat.vb localizado na pasta App_Code. Abra esse arquivo e
realize as nicas alteraes necessrias: definir a fonte de dados
com Inherits DataService(Of Mensagens) e defina a permisso
de acesso com config.SetEntitySetAccessRule(*, EntitySetRights.
All), conforme Listagem 4.
Para testar se tudo est OK configure como pgina inicial o
arquivo chat.svc e rode a aplicao WEB. Caso esteja tudo certo
um XML dever ser exibido no navegador. Se voc acessar
o endereo: http://localhost/Chat.svc/Mensagens uma lista de
mensagens ser exibida conforme Figura 8.

Figura 7. Adicionando um arquivo do tipo ADO.NET Data Service


Listagem 4. Classe do Astoria app_code/Chat.vb
Imports System.Data.Services
Imports System.Linq
Imports System.ServiceModel.Web
Public Class Chat
Inherits DataService(Of Mensagens)
Public Shared Sub InitializeService(ByVal config As
IDataServiceConfiguration)
config.SetEntitySetAccessRule(*, EntitySetRights.All)
End Sub
End Class

Criando a aplicao Silverlight e o proxy


A primeira coisa a ser feita a criao do proxy para permitir
trabalhar com servios Astoria. Quando utilizamos um web service criado com SOAP, com arquivos asmx, possvel adicionar
uma referncia web ao projeto e apontar ao endereo do web
service. Com Astoria isso ainda no possvel, portanto vamos
recorrer ao recurso do proxy.
Para cri-lo abra o Command prompt do Visual Studio. Acesse
o diretrio da aplicao Silverlight e digite datasvcutil.exe /
uri:http://...seu endereo/Chat.svc /out:proxy.vb /language:VB,
conforme Figura 9.

Uma mensagem de concluso com sucesso ser exibida. Caso


haja algum erro uma mensagem em vermelho ser exibida.
Para saber mais informaes sobre a criao de proxy, digite
o comando datasvcutil.exe /?. Uma lista com todas as opes
de comandos ser exibida. Caso esteja trabalhando com C# o
proxy tambm pode ser gerado. Por fim, adicione o arquivo
Proxy.VB ao projeto conforme Figura 10.
Caso por curiosidade abra o arquivo proxy.vb, ver que classes
similares as criadas no projeto web foram automaticamente

Figura 8. Lista de mensagens em XML gerada pelo Astoria

Edio 23 - WebMobile Magazine

79

Nota
Observe que no endereo da pgina existe um nmero de porta, definido logo aps a palavra
localhost. Esse nmero aleatrio e obtido automaticamente pelo Visual Studio quando a
aplicao roda a partir dele. Tambm, para visualizar o XML contendo as mensagens, pode ser
necessrio desabilitar o leitor de feeds automtico de Internet Explorer.

Figura 9. Criando o arquivo proxy, atravs do Command Prompt do


Visual Studio

geradas pelo aplicativo datasvcutil.exe, conforme Figura 11.


No arquivo Page.xaml vamos definir os elementos do Silverlight que faro parte da interface com o usurio. Caso no esteja
familiarizado com XAML, um programa que pode auxiliar na
criao da interface o Microsoft Expression Blend 2. A verso de
avaliao pode ser baixada no site da Microsoft. Instale tambm
o SP1, do Blend, para que novos controles possam ser utilizados.
Na Figura 12 exibo a interface j criada com o Blend.
O cdigo XAML da interface pode ser visto na Listagem 5.
No incio do arquivo XAML so definidos os namespaces
utilizados. Os dois primeiros so padro e o terceiro permite
uma manipulao com dados. Aps essa definio criamos
o grid que ser a base do layout do projeto e conter todos os
demais elementos. Em seguida definido um retngulo de
fundo degrad para dar um bom efeito visual.
Aps o retngulo adicionado um boto chamado btnEnviarMensagem. Este boto ser utilizado pelo usurio para enviar
novas mensagens para o Chat, de forma assncrona.
Em seguida uma caixa de texto adicionada ao projeto para
que o usurio possa digitar a mensagem. Note que informaes
auxiliares como altura, largura, cor, entre outras so adicionadas aos elementos.
O Listbox adicionado para exibir as mensagens, nele
atribudo o valor {Binding} propriedade ItemsSource, para
informar ao controle que a fonte de dados ser atravs de
bind. O bind um recurso que permite ligar controles visuais
a objetos, permitindo assim sua devida exibio. Note que,

Nota do DevMan
O Proxy na verdade um padro de projeto que oferece uma referncia a um
objeto que possui a real implementao. Ele encapsula o objeto real no expondo
toda sua complexidade. Neste exemplo temos a classe Mensagem que atua como um
Proxy. Ela est encapsulando o acesso aos servios do Astoria.

Figura 10. Adicione o arquivo proxy.vb ao projeto

assim como um repetidor no ASP.NET necessrio definir um


item template, ou seja, a especificao de como os dados sero
exibidos ao usurio.
No template dos itens sero exibidas as informaes de ID e
Mensagem, criadas na Listagem 1. Para exibir estas informaes
so criados TextBlock com as propriedades de Text={Binding
ID} e Text={Binding Mensagem}.
Por fim adicionei um ttulo ao chat utilizando uma TextBlock.
Apesar do ttulo ser exibido no incio do layout, ele foi adicionado no fim da listagem XAML. Isto ocorre, pois o posicionamento em Silverlight pode ser fixo, atribudo propriedade
Margin as posies X e Y do controle.
Agora que criamos a interface do usurio, vamos criar o
cdigo responsvel por interagir com a interface Silverlight e o
servidor, utilizando o proxy com o Astoria. Acesse o cdigo VB
da pgina Silverlight e adicione o cdigo da Listagem 6.
Inicialmente so definidas as bibliotecas externas, como por
exemplo, o proxy SL.SLEntity. possvel que em seu projeto
tenha um nome diferente. Como estamos criando um controle
Silverlight, a primeira coisa definida na classe Inherits UserControl, assim como em uma pgina ASP.NET herdada de
System.Web.UI.Page.
Como varivel global criada a lista de mensagens da classe
proxy, e uma ObservableCollection de conversa. A ObservableCollection permite armazenar uma lista de objetos de forma
a facilitar a interao com controles da interface Silverlight.
Se ela for atualizada, o controle responsvel por exibir suas
informaes ser notificado da alterao e apresentar ao
usurio o valor atualizado.
O endereo do servio Astoria definido na varivel sEndereco.
www.devmedia.com.br/clubedelphi/portal.asp

Acesse agora mesmo o portal do assinante WebMobile e veja uma vdeo aula de Euclides Loureno Chuma que
mostra como criar uma aplicao Silverlight utilizando o Microsoft Expression Blend.
http://www.devmedia.com.br/articles/viewcomp.asp?comp=6589

80

WebMobile Magazine - Manipulao de dados atravs do Silverlight com Astoria

asp.net

Figura 11. Arquivo de Proxy gerado pelo sistema.


Listagem 5. Arquivo Page.xaml
<UserControl x:Class=SL.Page
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/
presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
xmlns:data=
clrnamespace:System.Windows.Controls;assembly=System.Windows.
Controls.Data
Width=400 Height=300>
<Grid x:Name=LayoutRoot Background=White>
<Rectangle Stroke=#FF000000>
<Rectangle.Fill>
<LinearGradientBrush EndPoint=0.5,1 StartPoint=0.5,0>
<GradientStop Color=#FF000000/>
<GradientStop Color=#FFFFFFFF Offset=1/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Button Height=34 HorizontalAlignment=Right Margin=0,0,42,8
VerticalAlignment=Bottom Width=89 Content=Enviar
x:Name=btnEnviarMensagem/>
<TextBox Height=54 Margin=28,0,42,46
VerticalAlignment=Bottom
Text= TextWrapping=Wrap
x:Name=txtNovaMensagem/>
<ListBox Margin=28,33,42,105 Name=LBMensagens
ItemsSource={Binding}
RenderTransformOrigin=0.5,0.5>
<ListBox.Background>

Deixei sem tipo de forma proposital, para dar uma breve introduo em tipos annimos. Esse recurso foi introduzido recentemente
na plataforma .Net e possibilita que, embora no tenha sido declarado o tipo da varivel durante a declarao, ela no seja tratada
como um objeto e sim uma String, ou outro tipo, de acordo com
o que for atribudo a ela. Neste caso ento a varivel ser tratada
como String. O prximo mtodo a ser criado o construtor da
classe. O Mtodo New(), apenas define a varivel m_cConversa
como uma nova ObservableCollection de Conversa.
O mtodo responsvel por atualizar as mensagens o atualizarMensagens(). Ele utiliza-se de uma consulta Linq, selecionando todas as mensagens com o ID maior que zero. Fiz esta
pesquisa apenas por fins didticos, mostrando como voc pode

<LinearGradientBrush EndPoint=0.5,1
StartPoint=0.5,0>
<GradientStop Color=#FF565353/>
<GradientStop Color=#FFD7D4D4 Offset=0.513/>
<GradientStop Color=#FF565555 Offset=1/>
</LinearGradientBrush>
</ListBox.Background>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation=Horizontal Margin=5>
<TextBlock FontSize=12 Text={Binding ID}
Foreground=#FF000000/>
<TextBlock Text=>> />
<TextBlock FontSize=12 Text={Binding
Mensagem}/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Height=21 Margin=28,8,42,0
VerticalAlignment=Top
Text=Proxy com Astoria e Silverlight com
IUpdatable
TextWrapping=Wrap Foreground=#FFF40000
FontWeight=Bold FontFamily=Portable User
Interface
FontSize=12/>
</Grid>
</UserControl>

filtrar uma informao de modo simples. Por de baixo dos panos o que ocorre que esta consulta do Linq transformada em
uma pesquisa pela prpria URL, seguindo os padres de filtro
do Astoria. Este filtro possvel graas interface IQueryable
utilizada na Listagem 2, que absorve todo o trabalho rduo
que seria implementar o filtro com tecnologias anteriores.
Como toda chamada no Silverlight ao servidor feita de
forma assncrona, torna-se necessrio criar o mtodo atualizarCallBack(), que recebe como parmetro a varivel iar do tipo
IAsyncResult. Nele criada uma varivel de query que recebe o
resultado a operao assncrona, que ento atribuda lista
de mensagens. Essa lista ento exibida na ListBox atravs
do comando LBMensagens.DataContext = m_cConversa. Um

Edio 23 - WebMobile Magazine

81

Figura 12. Utilizando Blend para criao da interface grfica em Silverlight

Listagem 6. Arquivo Page.xaml.vb


Imports System.Data.Services.Client
Imports SL.SLEntity
Imports System.Collections.ObjectModel
Partial Public Class Page
Inherits UserControl
Private m_oProxy As Mensagens
Private m_cConversa As ObservableCollection(Of Conversa)
Private Const sEndereco = http://localhost:1316/ChatSLWS/
Chat.svc/
Public Sub New()
InitializeComponent()
m_cConversa = New ObservableCollection(Of Conversa)
End Sub
Public Sub atualizarMensagens()
Dim pesquisa As DataServiceQuery(Of SLEntity.Conversa) = _
(From m In m_oProxy.Mensagens _
Where m.ID > 0 _
Select m Order By m.ID Descending)
pesquisa.BeginExecute(AddressOf atualizarCallBack, pesquisa)
End Sub
Public Sub atualizarCallBack(ByVal iar As IAsyncResult)
Dim query As DataServiceQuery(Of Conversa) = _
DirectCast(iar.AsyncState, DataServiceQuery(Of Conversa))
Dim ListaMensagens As _
IEnumerable(Of Conversa) = query.EndExecute(iar)
m_cConversa.Clear()
For Each oMensagem In ListaMensagens
m_cConversa.Add(oMensagem)
Next
LBMensagens.DataContext = m_cConversa
End Sub
Public Sub finalizarAtualizacao(ByVal iar As IAsyncResult)
m_oProxy.EndSaveChanges(iar)
End Sub
Private Sub btnEnviarMensagem_Click(ByVal sender As Object, _
ByVal e As System.Windows.RoutedEventArgs) _
Handles btnEnviarMensagem.Click
Dim uriEndereco As New _
Uri(sEndereco)
m_oProxy = New SLEntity.Mensagens(uriEndereco)
Dim oConversa As New SLEntity.Conversa()
oConversa.Mensagem = txtNovaMensagem.Text
oConversa.DataHora = Date.Now
oConversa.UsuarioID = 2
m_oProxy.AddToMensagens(oConversa)
m_oProxy.BeginSaveChanges(AddressOf finalizarAtualizacao,
Nothing)
atualizarMensagens()
txtNovaMensagem.Text = String.Empty
End Sub
End Class

82

DataContext em Silverlight correlato ao DataSource utilizado


em aplicaes ASP.NET, indicando a fonte dos dados que sero
exibidos no controle.
O Mtodo btnEnviarMensagem_Click() o responsvel por tratar o evento de Click do boto enviar mensagens. Neste mtodo
criado uma varivel proxy e outra conversa. O texto do TextBlock
atribudo propriedade de conversa, assim como a data e hora, e
o ID de um usurio fictcio, para no perder o foco do artigo.
Em seguida o mtodo AddToMensagens() utilizado para
adicionar a nova conversa lista. Ento o mtodo BeginSaveChanges() utilizado para salvar a mensagem de forma assncrona e aps salva a mensagem, a lista atualizada e o valor
do TextBlock de nova mensagem limpo.

Concluso
Com este artigo vimos como implementar a classe IUpdatable
e como criar um proxy para consumir o servio Astoria utilizando uma aplicao Silverlight. O importante, muito mais do
que a aplicao neste artigo, o conceito que est por trs. A
tecnologia REST permite integrao de sistemas de diferentes
plataformas de modo simples, pois utiliza somente o http e
seus mtodos nativos. Como dica de estudo fica a criao de
modelos utilizando Entity Framework sendo disponibilizados
pelo Astoria. O Silverlight certamente abre aos desenvolvedores uma nova forma de programao web. Com certeza as
funcionalidades atuais so apenas o comeo desta promissora
tecnologia. Forte abrao e at o prximo artigo.
D seu feedback sobre esta edio!
A Web Mobile tem que ser feita ao seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/webmobile/feedback

WebMobile Magazine - Manipulao de dados atravs do Silverlight com Astoria

asp.net

Edio 23 - WebMobile Magazine

83

84

WebMobile Magazine - Manipulao de dados atravs do Silverlight com Astoria

Оценить