You are on page 1of 84

J2ME

Aprenda os segredos de uma


boa interface com usurio e
como desenvolv-la
Web Services
Seguros em .NET
Conhea o WSE 2.0
ASP.NET
Aumente o desempenho de
suas aplicaes web Parte III
Pocket PC
Smartphone
&
AJAX
Aprenda na prtica a utilizar a tcnica para
desenvolvimento de aplicaes web mais
interativas e com melhor desempenho
Veja na prtica as novidades trazidas pelo
Windows Mobile .0 e Visual Studio 200



J
a
v
a

-


.
N
E
T


-


G
a
m
e
s

-


P
a
l
m
S
o
u
r
c
e

-

M
e
r
c
a
d
o

-

J
2
M
E

-

A
s
p
.
N
E
T
A revista do desenvolvedor Web e Wireless
Edio 05 . Ano 01 . R$ 9,90 . Publicao Bimestral
C++ para Symbian OS
Conhea as tcnicas de desenvolvimento
de interfaces grficas
PDA e J2ME
Veja passo a passo como desenvolver
uma aplicao para PDA com J2ME
J2ME
Trabalhando com persistncia
em celulares - Parte 2
B

N
U
S
!
A
P
E
N
A
S

R
$

9
,
9
0
wm05.indb 1 3/10/2005 15:46:27
WebMobile
ANO I . 05 Edio
Publicao Bimestral
Outubro/Novembro . 2005
Publicidade
Para informaes sobre veiculao de anncio na revista ou no site
entre em contato com:
David Niegeski
publicidade@devmedia.com.br
Para fechar parcerias ou aes especficas de marketing com a
DevMedia, entre em contato com:
Gerente de Marketing e Atendimento
Kaline Dolabella
kalined@terra.com.br
Assistente de Marketing
Jeff Wendell
jeff@devmedia.com.br
Atendimento ao Leitor
A DevMedia conta com um departamento exclusivo para o aten-
dimento 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:
Aline Saldanha Atendimento ao Leitor
webmobile@devmedia.com.br
(21) 2283-9012
Kaline Dolabella Gerente de Marketing e Atendimento
kalined@terra.com.br
(21) 2283-9012
0
5
25
75
95
100
0
5
25
75
95
100
0
5
25
75
95
100
0
5
25
75
95
100
wm05.indb 2 3/10/2005 15:46:32
U
ma interface grfica atraente sem dvida um pr-requisito para o sucesso de qualquer aplicao. Quando o as-
sunto interface para dispositivos mveis existe um outro fator muito importante: a acessibilidade aos recursos
do aplicativo. Alm disto, o desenvolvedor de aplicaes para dispositivos mveis deve estar atento a estes fatos de
maneira tal que os menus da interface grfica tenham uma boa navegabilidade e que os grficos no consumam muitos
recursos do aparelho, o que prejudica a performance da aplicao. Neste contexto, a Web Mobile destaca nesta edio
uma excelente matria sobre o desenvolvimento de interfaces grficas para dispositivos mveis.
Outra matria bastante interessante Desenvolvendo aplicaes para Pocket PC e Smartphone para Windows Mobile
5.0 no Visual Studio 2005. Nela, os autores apresentam como os avanos do Visual Studio 2005 tornam o futuro do de-
senvolvimento de aplicaes para dispositivos mveis que utilizam o sistema operacional Windows Mobile rico e cheio
de oportunidades. Alm disto, so tambm analisadas as facilidades relacionadas ao desenvolvimento de aplicaes
que o novo Windows Mobile fornece.
Continuando a discusso sobre a tecnologia .NET, temos mais duas matrias. Em Desenvolvendo Web Services
seguros na plataforma .NET, so demonstradas algumas das tcnicas de segurana com web services trabalhando es-
pecificamente com o WSE 2.0. J no artigo ASP.NET Aumentando a performance de suas aplicaes web Parte III,
Guinther apresenta os objetos envolvidos no tratamento e gerenciamento de sesso e estado de aplicaes web.
Gostaria de destacar tambm a segunda parte da matria sobre Symbian C++. Desta vez, o assunto em foco o
desenvolvimento de aplicaes com interface grfica em Symbian.
Mudando a tecnologia em foco e partindo para Java. No artigo Desenvolvendo aplicaes J2ME para PDAs so
apresentados todos os passos tcnicos relacionados ao desenvolvimento de uma aplicao para PDAs, desde a insta-
lao das ferramentas necessrias para seu desenvolvimento, at o desenvolvimento de uma aplicao. J na matria
Implementando persistncia com fluxos em J2ME, apresentado o uso de tcnicas de armazenamento e recuperao
que permitem que um registro contenha tipos de dados Java diferentes.
Por fim, temos uma excelente matria Entendendo o AJAX, leitura obrigatria. Neste artigo voc entender o que
est por trs do GMail. Para os usurios comuns, a surpresa com os mais de 1GB de espao de armazenamento. Para
os programadores, o espanto de perceber como uma aplicao web com inmeras funcionalidades pode ser to leve,
amigvel e ter um tempo de resposta to curto. Leia e descubra.
Editorial
Um abrao e at a prxima!!!
Rodrigo Oliveira Spnola
editorwebmobile@devmedia.com.br
Editor Geral
Rodrigo Spinola
editorwebmobile@devmedia.com.br
Revisor
Gustavo Spinola
gustavo.spinola@gmail.com
Vinicius O. Andrade
viniciusoandrade@yahoo.com.br
Editores Tcnicos
Arilo Cludio
acdn@cos.ufrj.br
Guinther Pauli
guinther@devmedia.com.br
Rafael Barcelos
Barcelos@cos.ufrj.br
Redatores desta edio
Marcelo Morgade; Fbio Medeiros; Bruno Chaves Rocha Lima
e Edgar Barbosa de Souza; Antonio Eloi de Sousa Jnior;
Andrey Sanches; Guinter Pauli; Eduardo Peixoto e Renato Iida;
Alexandre Fernandes Chaud Tarifa, Jos Antonio Leal de Farias
e Equipe Web Mobile
Traduo Tcnica
Juliano D. Carniel e Clovis Teixeira
Jornalista Responsvel
Kaline Dolabella
kalined@terra.com.br
Projeto Grfico e Capa - pH Design
phdesign@phdesign.com.br
Felipe Natividade Machado
Jaime Peters Junior
Mnica Queiroz
Tarcisio Bannwart
WEB
www.portalwebmobile.com.br
Distribuio
Fernando Chinaglia Dist. S/A
Rua Teodoro da Silva, 907
Graja RJ 20.656-900
WebMobile
ANO I . 05 Edio
Publicao Bimestral
Outubro/Novembro . 2005
WebMobile 3
ndice
Publicidade
Para informaes sobre veiculao de anncio na revista ou no site
entre em contato com:
David Niegeski
publicidade@devmedia.com.br
Para fechar parcerias ou aes especficas de marketing com a
DevMedia, entre em contato com:
Gerente de Marketing e Atendimento
Kaline Dolabella
kalined@terra.com.br
Assistente de Marketing
Jeff Wendell
jeff@devmedia.com.br
Atendimento ao Leitor
A DevMedia conta com um departamento exclusivo para o aten-
dimento 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:
Aline Saldanha Atendimento ao Leitor
webmobile@devmedia.com.br
(21) 2283-9012
Kaline Dolabella Gerente de Marketing e Atendimento
kalined@terra.com.br
(21) 2283-9012
cones Internos
Editorial
Entrevista Figura
Nota
Download
Listagem
Livros Minibiografia
Ateno
Links
Tabela
Quadro
Tutoriais
News
Projeto Grfico
Realizao
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 e qual artigo voc menos gostou. Fique a vontade para
entrar em contato com os editores e dar a sua sugesto!
Se voc estiver interessado em publicar um artigo na revista ou
no site WebMobile, entre em contato com os editores, informando o
ttulo e mini-resumo do tema que voc gostaria de publicar:
Rodrigo Spinola - Editor da Revista
editorwebmobile@devmedia.com.br
Alfredo Ferreira - Editor do Site
alfredo@clubedelphi.net
Jogos
04. News
por Equipe Web Mobile
08. Entendendo o AJAX
por Marcelo Morgade
18. Desenvolvendo aplicaes J2ME
para PDAs
por Fbio Medeiros
25. Interface Grafica para aplicacoes
J2ME - Uma introduo MIDP UI API
por Bruno Chaves Rocha Lima e Edgar Barbosa
de Souza
40. Implementando persistencia com
fluxos em J2ME
por Antonio Eloi de Sousa Jnior
50. Desenvolvendo Web Services
seguros na plataforma .NET
por Andrey Sanches
58. ASP.NET - Aumentando a performance
de suas aplicaes web-ParteIII - Session,
ViewState, Cache e State Server
por Guinter Pauli
66. Desenvolvendo aplicaes para Pocket
PC e Smartphone para Windows Mobile 5.0
no Visual Studio 2005
por Alexandre Fernandes Chaud Tarifa e Jos Antonio
Leal de Farias
74. Desenvolvimento C++ para Symbian OS
Como funciona o sistema de interface com
o usurio
por Eduardo Peixoto e Renato Iida
0
5
25
75
95
100
0
5
25
75
95
100
0
5
25
75
95
100
0
5
25
75
95
100
wm05.indb 3 3/10/2005 15:46:54
5 Edio
News por Equipe Web Mobile
Google projeta sua prpria internet
O Google no d descanso a seus rivais. Agora, o sistema de buscas est compran-
do cabos de fibra ptica em todo Estados Unidos e adquirindo conexes velozes das
telecoms Cogente Communications e WiTel. Para qu? Para, segundo o site Business
2.0, construir uma internet paralela, j batizada de Google Net, que poder ser aces-
sada gratuitamente por seus usurios.
A GoogleNet permitiria tambm economizar milhes de dlares em operaes de
busca. Explica-se: cada vez que um internauta realiza uma pesquisa, o Google tem de
pagar US$ 60 mensais por megabit por segundo para um provedor fazer a ponte entre
seus servidores e uma operadora de acesso rede por banda larga.
Com uma internet prpria, o Google poderia dispensar o provedor, reduzindo bas-
tante seus custos, que se tornam mais altos, na medida em que crescem seus servios
de publicidade online.
Alm disso, os internautas seriam beneficiados, pois poderiam baixar mais rapida-
mente grandes arquivos de vdeo e udio de parceiros do Google, como a Fox News e
C-Span.
Fonte: Estado
Google Talk
Google lanou recentemente seu programa de mensagens instantneas e conversas
por udio. O Talk surpreende por sua simplicidade e leveza, o que pode ser um atrativo
para alguns usurios. Outros internautas, no entanto, podem sentir falta dos badula-
ques do MSN Messenger e do ICQ.
O programa ainda est em sua primeira verso, e carece de alguns recursos bsicos,
como agrupamento de contatos e transferncia de arquivos. Tambm deve ficar mais
poderoso no quesito VoIP, permitindo ligaes para nmeros de telefone, como o
Skype. Quem quiser experimentar o Google Talk basta baixar o arquivo de instalao
de 900 Kb no endereo talk.google.com. Mas necessrio ter uma conta do Gmail para
us-lo.
Fonte: Terra
Contra-ataque
No mesmo dia do lanamento do Google Talk, a Microsoft anunciou a verso final do
MSN Messenger 7.5, inclusive em portugus. Entre as novidades, backgrounds dinmi-
cos e clipes de voz. Para baix-lo, v ao endereo messenger.msn.com.
A Skype revelou, tambm no mesmo dia, que vai abrir a sua tecnologia de mensagens
instantneas para que desenvolvedores possam integr-as em websites e outros aplica-
tivos. A empresa espera ampliar o seu nmero de usurios, que j de 51 milhes.
Fonte: Terra
Registrada 1 grande infeco de vrus de celular
A empresa de segurana finlandesa F-Secure noticiou, ao final da semana passada,
o que parece ser a primeira grande infeco por vrus de telefones celulares em um
ambiente corporativo.
Sem revelar o nome da empresa afetada, a F-Secure afirma que foi chamada para
controlar uma epidemia de contaminaes pela praga Commwarrior.B, que envia men-
sagens multimdia infectadas a outros celulares inteligentes e tambm arquivos cor-
rompidos para smartphones dentro da sua rea de cobertura Bluetooth.
De acordo com a F-Secure, dzias de empregados da empresa receberam o vrus e,
o mais grave, abriram os arquivos contaminados por acreditarem ser uma mensagem
autntica de um colega de trabalho.
wm05.indb 4 3/10/2005 15:47:02
WebMobile
News
wm05.indb 5 3/10/2005 15:47:09
5 Edio
News
O Commwarrior.B uma praga que ataca somente smartphones
- celulares avanados, que combinam funes de PDA - equipados
com sistema operacional Symbian.
Esta , segundo a empresa finlandesa de segurana, a primeira
notcia de infeco em massa dentro de um ambiente corporativo,
chamando a ateno para que companhias desenvolvam polticas
de uso de conexes Bluetooth e MMS no trabalho
Fonte: IDGNow
Travesseiro com tecido luminoso recebe SMS
Pesquisadores criaram um tecido luminoso que usa LEDs -
componentes semicondutores que convertem energia eltrica di-
retamente em luz - flexveis para criar luzes e imagens na sua
superfcie. Interessante mesmo o uso que a Philips j deu
inveno: travesseiros SMS. Isso mesmo, travesseiros revestidos
com o tecido, que acendem luzes com diversas cores, formam
imagens e recebem mensagens de texto.
Isso significa que, se um dia os tais travesseiros chegarem ao
mercado, voc poder mandar um SMS direto para o da sua na-
morada, e ela ver coraes e mensagens de amor na fronha do
travesseiro antes de dormir.
A Philips tambm vislumbra o uso do tecido luminoso em rou-
pas, principalmente para os jovens, que poderiam sair por a com
um belo SMS no
peito. O tecido
luminoso ser
apresentado em
uma feira de
eletrnicos em
Berlim, na Ale-
manha.
Fonte: Terra
Vendas online crescem 30,7% no Brasil
As vendas online no Brasil fecharam o primeiro semestre deste
ano em R$ 974 milhes, com um aumento de 30,7% em com-
parao com o resultado do mesmo perodo do ano anterior -
R$ 745 milhes. De acordo com a companhia de pesquisas
e-bit, que divulgou os ndices, o nmero de pedidos de compra
tambm cresceu no primeiro semestre e ficou em pouco mais de
3 milhes. Cerca de 4 milhes de brasileiros j fizeram compras
pela Internet.
O perfil do comprador eletrnico tambm se manteve parecido:
a maioria (71%) tem entre 25 e 49 anos e homem (58%). A
grande maioria dos consumidores (81%) se considera satisfeita
com o servio das lojas, e os CDs, DVDs e vdeos continuam na
liderana da lista dos produtos mais vendidos, com 22%. Depois
vm livros, revistas e jornais (17%).
Fonte: Terra
Cert.br lana cartilha de segurana
O Centro de Estudos, Resposta e Tratamento de Incidentes de
Segurana no Brasil (Cert.br), vinculado ao Comit Gestor da
Internet no Brasil (CGI.br), lanou no dia 06/09 a verso 3.0 da
cartilha de segurana para internet.
De acordo com Cristiane Hoepers, analista de segurana snior
do Cert, a edio atualizada da cartilha tem com objetivo auxiliar
o usurio final a se proteger das novas ameaas virtuais.
Entre as principais mudanas da verso 3.0 esto novos termos
acrescentados ao glossrio de segurana, detalhes sobre os novos
formatos de fraude utilizados na internet e como se prevenir da
ameaa a novas tecnologias, como WPA (Wi-Fi Protected Access),
celular e bluetooth.
A cartilha traz ainda dicas de combate a vrus, worms (progra-
mas que fazem cpias de si mesmos e danificam o computador) e
spywares (programas espies). Ensina tambm a evitar fraudes e
phishing, golpes que podem revelar senhas de banco e informa-
es confidenciais do internauta.
A cartilha est no endereo www.cartilha.cert.br.
Fonte: IDGNow
TV digital: governo s define em 2006
O padro brasileiro de TV Digital dever ser definido at o incio
do ano que vem, quando o presidente Luiz Incio Lula da Silva
recebe o projeto elaborado por 106 instituies que estudam um
sistema adaptado s condies sociais e tecnolgicas do pas,
estima a Casa Civil da Presidncia da Repblica.
O grupo tcnico, formado por 505 mestres e doutores, de
universidades e centros de pesquisa, trabalha em rede desde
novembro de 2003 e entregar seu relatrio final at fevereiro
de 2006.
Segundo o assessor especial da Casa Civil Andr Barbosa, o
Sistema Brasileiro de TV Digital primar pelo acesso universal, ou
seja, adotar padres j existentes que permitam transmisso,
transporte e compresso de dados, e que possam ser captados
por um simples aparelho de TV de 14 polegadas, com uma antena
interna, por exemplo.
O objetivo que, no Brasil, o aparelho que possibilite que uma
TV analgica receba o sinal digital custe, no mximo, R$ 30. Seria
uma espcie de conversor, um terminal de acesso que traduza
as informaes passadas da casa do telespectador para o radio
transmissor.
Barbosa prev que a TV digital brasileira permitir operaes
como teleconferncias, consultas mdicas e escolha da programa-
o desejada por meio do controle remoto. A TV digital vai per-
mitir a interatividade, vai permitir que o telespectador participe
da programao e que ele possa construir a informao que ele
pretende, explica ele.
Fonte: IDGNow
wm05.indb 6 3/10/2005 15:47:10
WebMobile
News
58+ Solues em .Net
Este o ttulo do mais novo livro do Fbio
Camara e Time de Desenvolvimento Avanado
da ArchITettura. Para aqueles que ainda no o
conhecem, Fbio Camara Diretor de Opera-
es da ArchITettura e responsvel pela diviso
Technical Services. Escreveu os livros Projetos com Windows DNA
e .NET, Dominando o Visual Studio.NET com C#, 58+ Solues
em .NET e Orientao a Objeto com .NET dentre outros. Ele
entende muito do assunto!
Nesta obra, so apresentadas solues para problemas encontra-
dos por desenvolvedores .net no seu dia a dia. Solues estas j
comprovadas experimentalmente nos diversos projetos desenvolvi-
dos pela ArchITettura. uma grande fonte de informao. Alguns
exemplos de solues apresentadas so: segurana com SSL para
web services, tcnicas de redimensionamento de forms, guia de
autenticao ASP .NET e, criando relatrios com SQL Reporting
Services, dentre muitos outros tpicos bastante interessantes.
Como informa a prpria
capa do livro Solues
Prticas > Solues Fun-
cionais > Solues Avan-
adas.
58+ Solues em .Net
Autor: Fbio Camara e
Time de Desenvolvimento
Avanado ArchITettura
Editora: Visual Books
ISBN: 85-7502-158-3
Preo: R$ 79,00
378 pginas
Brasil sexto em ranking mundial de celular
O Brasil subiu uma posio e agora o sexto pas em nmero
de celulares, segundo dados da Unio Internacional de Telecomu-
nicaes (UIT) referentes a 2004 de 183 pases.
Nesse ano, Brasil superou a Itlia e o Reino Unido, mas foi ul-
trapassado pela Rssia, que apresentou um crescimento de 104%,
segundo dados da UIT, publicado no site Teleco.
O lder do ranking a China, com 335 milhes de celulares e
312 milhes de telefones fixos. Em segundo lugar, est os Esta-
dos Unidos com 181 milhes e 178 milhes, respectivamente.
Japo, Rssia e Alemanha completam a lista. De acordo com pro-
jees, o Brasil deve terminar 2005 em quinto lugar, com mais de
88 milhes de celulares, superando a Alemanha.
Fonte: IDGNow
Internet em celulares ganha domnio prprio
Os usurios de internet vo contar com mais um substituto
para o popular .com, o sufixo .MOBI, referente a websites
construdos especificamente para acesso via telefone celulares. O
novo sufixo foi recentemente aprovado pela Internet Corporation
for Assigned Names and Numbers (ICANN).
Fonte: IDGNow
Apple anuncia celular com msica e iPod Nano
A Apple confirmou que vai lanar um telefone celular com ca-
pacidade para tocar msica por meio do seu servio iTunes. Tam-
bm anunciou um novo iPod, to fino quanto um lpis n 2, mas
com capacidade para guardar at mil canes.
O telefone celular Rokr e o iPod Nano representam mais duas
tentativas de estender a enorme popularidade dos tocadores de
msica da Apple, de acordo com o cNet. O iPod detm 53% do
mercado de players digitais. A empresa tambm anunciou a quin-
ta verso do iTunes, seu software de gerenciamento de msicas.
Fonte: Terra
Nokia lana e-mail no celular para empresas
A Nokia anunciou o lanamento de um sistema de e-mail que
permite a funcionrios de empresas a transmisso de mensagens
eletrnicas a partir de seus celulares. O Nokia Business Center,
nome do novo sistema de e-mail, quer preencher o espao entre
as 650 milhes de contas empresariais de e-mail do mundo e a
elite de cerca de 10 milhes de profissionais que tm acesso m-
vel s caixas de correio eletrnico de suas empresas.
Fonte: Terra / Reuters
Sun mira setor financeiro com novos servidores
A Sun Microsystems anunciou em Nova York sua linha de ser-
vidores com padres industriais, que tem no setor financeiro um
dos seus principais alvos.
A famlia de equipamentos traz trs modelos - Sun Fire X2100,
X4100, e X4200 - que utilizam processadores Opteron, da Advanced
Micro Devices (AMD).
De acordo com Jonathan Schwartz, presidente e Chief Operating
Officer (COO) da Sun, o setor financeiro representa um mercado
que tem recebido ateno especial da companhia, que tem bus-
cado firmar parcerias que atendam s necessidades desse pblico.
Trabalhar com parceiros que complementem nossas solues
um passo muito importante para ns e muitos deles j anunciam
aplicaes para serem executadas no Solaris 10, declarou duran-
te o evento Network Computing 2005.
Fonte: Computer World
wm05.indb 7 3/10/2005 15:47:13
5 Edio
por Marcelo Morgade
Entendendo
o AJAX
A
popularizao da web nos trouxe a possibilidade de criar
novas interfaces para os sistemas de informao. Sistemas
web trouxeram grandes vantagens como a possibilidade de
serem acessados em qualquer parte do planeta, a capacidade de
serem utilizados em qualquer plataforma cliente que suporte um
browser HTTP e a enorme facilidade de atualizao. Hoje em dia, a
grande maioria dos pacotes de software das mais diferentes reas
utilizam esse tipo de interface. De pequenas aplicaes em intra-
net aos grandes sistemas de gesto; de um software simples de
administrao de usurios a um complexo firewall. Quase todas as
verses mais recentes destas novas aplicaes trazem interfaces
com o usurio atravs da web. Interfaces de controle de e-mail via
web (os webmails) hoje em dia so provavelmente mais usadas
que os clientes desktop tradicionais, e certamente a aplica-
o com interface web mais utilizada na internet. Este
mesmo exemplo do webmail tambm demonstra
uma das desvantagens deste tipo de interface:
o elevado tempo de resposta do sistema.
Quem est acostumado a usar um cliente
de e-mail tradicional, e se v obrigado
a usar um webmail geralmente se ir-
rita com a diferena na velocidade de
acesso s suas mensagens e com a po-
breza da interface web em relao
aplicao desktop.
Ao observar o processo do HTTP
fica fcil notar que na maioria das ve-
zes a etapa que mais consome o tempo
de reposta a gerao do HTML e seu en-
vio ao browser. Esse processo, combinado
com a existncia de um design carregado
com dezenas de imagens e tabelas dentro
de tabelas acentuam ainda mais o problema.
Normalmente, para cada clique do usurio ou
formulrio submetido, a tela completamente
recarregada com seus cabealhos,
rodaps, menus, tabelas, imagens,
etc. Ou seja, o usurio v o siste-
ma desaparecer da tela e reapa-
recer aos poucos depois de vrios
segundos. O programador web
wm05.indb 8 3/10/2005 15:47:17
WebMobile
Java Web
Entendendo
o AJAX
normalmente no se sente responsvel pelo problema j que con-
sidera a gerao do HTML e um belo design como ferramentas que
no podem ser descartadas.
Mas, eis que surge uma revoluo chamada GMail. Para os usu-
rios comuns, a surpresa com os 1GB de espao de armazena-
mento. Para os programadores, o espanto de perceber como uma
aplicao web com inmeras funcionalidades pode ser to leve,
amigvel e ter um tempo de resposta to curto. Desde ento, vem
entrando em discusso a utilizao da metodologia de interfaces
web conhecida como AJAX.
O que AJAX?
AJAX uma sigla para o termo Asynchronous JavaScript and
XML. Quem ouve falar pela primeira vez sobre o termo e procura
informaes em sites de busca acaba bastante perdido. Muitos
pensam em achar algum framework ou biblioteca com este nome
e acabam no encontrando nada do que esperado. Isso acontece
por que o AJAX no um software nem uma linguagem de pro-
gramao, mas sim uma metodologia de construo de interfaces
web dinmicas e leves. Ele envolve a utilizao de tecnologias
distintas que se tornaram padres h algum tempo. a forma
de utilizao em conjunto destas tecnologias que define o AJAX,
criando uma forma de interao com a web bem diferente daquilo
que estamos acostumados.
O que mais assusta a quem quer comear a usar a metodologia
do AJAX justamente a necessidade de conhecer toda lista de
tecnologias associadas a ele. Esta lista compreende XML, XHTML/
DHTML, CSS e JavaScript usando o padro DOM em conjunto com
a classe XMLHttpRequest:
XML: formato padro dos dados trocados entre browser e
servidor;
XHTML / CSS: definidores do design da interface;
JavaScript: linguagem de programao usada para criar o
motor do AJAX. A comunicao assncrona com o servidor deve
ser feita utilizando a classe XMLHttpRequest.
DOM: usado no lado servidor para criao de documentos
XML, e no lado cliente para processamento dos documentos
recebidos e para a gerao do XHTML dinmico.
Tudo isso sem citar a necessidade do conhecimento de uma
linguagem web responsvel pela gerao de contedo do lado
servidor. Qualquer linguagem pode ser usada no lado servidor, mas
em projetos grandes aconselhvel utilizar alguma que tenha um
bom suporte para processamento de XML.
Somente a viso desta lista de tecnologias suficiente para
perceber que a forma de desenvolvimento para web usando a
abordagem do AJAX realmente mais complexa do que a forma
tradicional. Mas o resultado final , muitas vezes, bastante recom-
pensador, garantindo um menor trfego na rede, uma interface
mais rica, dinmica e com um menor tempo de resposta.
A abordagem do AJAX consiste em usar todas estas tecnologias
no lado cliente para criar uma camada adicional de software entre
o browser e o servidor web. O menor tempo de resposta neste caso
explicado pelo fato do usurio interagir com um cdigo que j
est em sua memria, ao invs de sempre ir ao servidor para atua-
lizar dados na interface grfica. Observe na 1 um comparativo
simplificado do AJAX com uma abordagem de desenvolvimento
tradicional.
O motor AJAX um conjunto de rotinas em JavaScript cujas
principais funes so o envio de requisies HTTP para o servidor
usando a classe XMLHttpRequest, e o processamento das respos-
tas em XML destas requisies para, enfim, atualizar a interface
com usurio atravs da gerao dinmica de XHTML formatado
com CSS. O trfego HTTP durante o uso da aplicao diminui por
que as respostas em XML contm apenas dados estruturados, que
quase sempre so bem menores que pginas HTML inteiras en-
viadas pela rede. Alm disso, um motor AJAX bem construdo
pode manter estes dados estruturados de requisies anteriores,
criando um cache em memria. Isso permite, por algum tempo, a
navegao em um conjunto de dados dinmicos sem a necessida-
de de enviar um nico byte pela rede! Alguns sistemas trabalham
com implementaes do padro MVC (Model View Controller) todo
escrito em JavaScript dentro do motor AJAX.
Outra caracterstica interessante do AJAX a sua natureza as-
sncrona. O mecanismo bsico da web o HTTP, e este baseado
em um processo simples de requisio-resposta. Na abordagem
web tradicional, browser e servidor sempre atuam um de cada
vez de forma sncrona. Ou seja, quando o usurio pede uma p-
gina, precisa aguardar todo o processo de conexo-requisio-
resposta para comear a interagir com o contedo. Depois que o
contedo chega, a vez do servidor esperar que o usurio leia
a pgina ou preencha um formulrio para s ento uma nova
requisio ser feita. Na abordagem do AJAX, com utilizao do
objeto XMLHttpRequest, possvel fazer requisies HTTP que
no provocam a recarga da pgina. O usurio pode interagir com
a pgina mesmo que a resposta do servidor s ltimas requi-
sies AJAX ainda no tenham chegado. Tomando novamente
o exemplo do GMail, note que ao mesmo tempo em que voc
l ou escreve um e-mail no formulrio de envio, o motor AJAX
pode estar checando na sua caixa de entrada no servidor se h
uma mensagem nova e ainda pode estar enviando ao servidor
os dados sobre as ltimas mensagens que voc marcou como
spam. Desse modo, as operaes so assncronas por natureza,
uma vez que diferentes trechos de script podem rodar ao mesmo
1. Abordagem original X abordagem AJAX.
wm05.indb 9 3/10/2005 15:47:22
10 5 Edio
tempo. Isso traz todas as vantagens (e toda a complexidade!)
de podermos executar tarefas de modo concorrente no browser.
Algumas interfaces podem ser 100% assncronas, nas quais todo
o cdigo JavaScript baixado na primeira requisio para fazer
a manipulao dos eventos e das requisies HTTP. Isso faz com
que a carga da pgina inicial seja um pouco mais lenta, porm
provoca uma diminuio do trfego posterior na rede e do tem-
po de resposta do sistema (esse o caso do nosso exemplo do
GMail). Mas tambm possvel usar o AJAX apenas em algumas
partes do sistema, fazendo uma mistura entre a abordagem sn-
crona e a assncrona.
Neste artigo vamos descrever os detalhes de uso de cada uma
das tecnologias que interagem no AJAX, criando uma aplicao
web simples que usa esta metodologia. Ser usado um Servlet Java
que pode ser instalado em qualquer servidor que suporte este pa-
dro. Voc precisa conhecer o bsico sobre servlets para entender
o funcionamento do mdulo servidor. Como esta implementao
usa generics para diminuir o cdigo, voc precisa da verso 1.5 da
mquina virtual Java para fazer o exemplo funcionar.
Uma pequena aplicao AJAX
O cdigo do motor AJAX deve ser implementado em um ou mais
arquivos *.js parte. Neste exemplo usaremos um arquivo cha-
mado ajax.js com todas as funes, mas possvel criar arquivos
separados para processamento das requisies e para o tratamen-
to de eventos do usurio. aconselhvel encontrar uma IDE que
tenha um bom suporte para a edio deste tipo de arquivo, j que
nele estar grande parte do cdigo da interface com o usurio.
Outra dica interessante fazer testes usando o browser FireFox e
suas timas ferramentas de depurao de JavaScript.
Quem j conhece JavaScript sabe do problema infernal de
incompatibilidade entre os browsers. comum ver scripts que
funcionam em um browser no funcionarem em outro devido a
algumas diferenas entre nomes de objetos do JavaScript. Usu-
rios do FireFox, por exemplo, sempre tm problemas em pginas
que insistem em usar o objeto document.all que proprietrio do
Internet Explorer.
Mas, problemas de incompatibilidade em todas as reas de
tecnologia sempre se resolveram com uma soluo simples: o
estabelecimento e utilizao de padres. justamente o esta-
belecimento de um padro que tornou possvel a utilizao do
AJAX em grandes aplicaes. Este padro conhecido como DOM
(Document Object Model).
Para os que esto acostumados a trabalhar com XML, o DOM
um velho conhecido. Ele pode ser encarado simplesmente como
um conjunto de interfaces padro de objetos utilizados para criar
e/ou processar documentos que seguem as regras de sintaxe do
XML. Ou seja, o DOM no um software nem uma biblioteca. Ele
uma especificao do W3C que, para a nossa sorte, foi imple-
mentado em quase todos os browsers mais utilizados na web. Se
um browser faz a propaganda de que implementa o padro DOM,
sabemos ento quais os conjuntos de objetos, mtodos e atribu-
tos podemos usar em JavaScript para processar documentos XML
e pginas XHTML. A implementao DOM do JavaScript usado
tanto para processar o XML enviado pelo servidor como tambm
para modificar elementos HTML da pgina exibida no browser e,
assim, movimentar a interface com o usurio. Dessa forma, para
criar um motor AJAX que seja realmente cross-browser (suporte
mltiplos browsers), basta trabalhar sempre sobre as interfaces
DOM. Em vez de usar o document.all para localizar um elemen-
to na pgina, deve-se usar por exemplo o mtodo document.
getElementById(<id>), que est previsto no padro DOM e por
isso suportado na maioria dos browsers.
Como vimos, outro elemento essencial a classe XMLHttpRequest
do JavaScript. Esta classe o recurso bsico para comunicao
do motor AJAX com o servidor web. atravs do uso de obje-
tos XMLHttpRequest que possvel fazer requisies HTTP sem
interrupes visuais para o usurio. Como nem tudo perfeito,
o uso da classe ainda tem um problema de compatibilidade que
pode ser facilmente contornado. O XMLHttpRequest surgiu inicial-
mente no Internet Explorer como um objeto ActiveX que podia
ser instanciado via JavaScript. Um pouco depois, outros browsers
como os da famlia Mozilla e o Safari da Apple implementaram o
XMLHttpRequest como objetos nativos do JavaScript. Como ain-
da no h um padro definido, o cdigo de criao do objeto
XMLHttpRequest o nico ponto do motor AJAX em que somos
realmente obrigados a checar em qual browser o cdigo est ro-
dando. A 1 mostra o cdigo da primeira funo do arquivo ajax.
js que conter o motor AJAX da aplicao exemplo.
A funo httpReq dever ser chamada pelo browser sempre
que precisarmos conversar com o servidor. Das linhas 7 a 11 ob-
servamos o problema de criao do XMLHttpRequest. A linha 7
checa se o browser suporta a classe de forma nativa. Se no tiver
sucesso, verifica o suporte ao ActiveX. Se nenhum desses funcio-
nar, o browser no pode acessar o sistema.
Antes de ver a linha 13, observe que na linha 14 definimos o
wm05.indb 10 3/10/2005 15:47:26
WebMobile 11
Java Web
1. ajax.js
1. /***********************************************
2. FunobasepararequisioHTTPassncrona
3. ***********************************************/
4. functionhttpReq(params){
5. //usamosumavarivellocalparaevitar
problemasdeconcorrncia
6. varajaxRequest=null;
7. if(window.XMLHttpRequest)
8. ajaxRequest=newXMLHttpRequest();
9. elseif(window.ActiveXObject)
10.ajaxRequest=newActiveXObject(Microsoft.XMLHTTP);
11.elsealert(AJAXnosuportado.Atualizea
versodestebrowser);
12.
13.ajaxRequest.onreadystatechange=dispatch;
14.ajaxRequest.open(GET,./servlet/ajaxtest.
Agenda?+params,true);
15.ajaxRequest.send(null);
16.
17.functiondispatch(){
18.if(ajaxRequest.readyState==4){
19.if(ajaxRequest.status==200){
20.varmessage=ajaxRequest.
responseXML.documentElement;
21.varop=message.
getAttribute(op);
22.eval(tratar_+op+(message.
childNodes););
23.}else{
24.alert(Erronoservidor:\n+
ajaxRequest.responseText);
25.}
26.}
27.}
28.}
0. no inicializado
1. carregando documento
2. documento carregado
3. processando documento
. requisio completa
Neste exemplo s nos importamos com o estado 4, o qual sig-
nifica que a requisio foi enviada e uma resposta j foi obtida
do servidor. Quando este estado detectado, checamos o status
HTTP da resposta. Um status diferente de 200 significa que algo
errado ocorreu, e neste caso a funo mostra a caixa de alerta
com a resposta do servidor em forma de texto (responseText).
Finalmente, um status 200 significa que tudo ocorreu bem e que
um contedo enviado pelo servidor pode ser processado pelo
script. Para entendermos as linhas 20 a 22, precisamos dar uma
olhada no XHTML do sistema e ver o que ocorre
do lado servidor.
Uma pgina XHTML pode ser encarada como
uma pgina HTML bem comportada. No XHTML
devemos seguir os padres XML, fechando e es-
truturando corretamente todas as tags e evitando
usar atributos de design no mais recomendados.
O cdigo da pgina define apenas estrutura bsi-
ca, deixando o trabalho de design para um arquivo
CSS em separado. Isso tudo serve para deixar o
cdigo mais legvel, j que iremos usar os iden-
tificadores das tags para definir novos elementos
dinamicamente na pgina. Observe na 2 o ni-
co arquivo XHTML.
Na linha 1 observa-se que existe um validador
DTD para o XHTML. No obrigatrio ser comple-
tamente rgido com o formato documento, mas
um pouco de cuidado nunca demais. Na linha 5
definimos o arquivo de folha de estilos que ir dar
o design pagina. Observe que mesmo com um
documento HTML aparentemente simples, poss-
vel criar um design mais rebuscado para a pgina.
A 2 mostra o que algumas definies de estilo
podem fazer com este pequeno arquivo HTML.
Conhecer os modelos CSS importante para
deixar seu cdigo HTML limpo sem abrir mo de
um design interessante. surpreendente a flexi-
bilidade que pode se dar a uma pgina cujo de-
sign baseado apenas nas folhas de estilo de um
arquivo CSS.
Na linha 6 temos uma declarao importante.
Nela faz-se a incluso do arquivo ajax.js que con-
tm nosso motor AJAX no contexto de execuo
de scripts da pgina. No corpo da pgina defi-
nimos elementos div e formulrios que sero os
mtodo HTTP e o endereo da requisio (neste caso o caminho
para um servlet que far todo o processamento mais um conjunto
de parmetros passado), e na linha 15 disparamos a requisio para
o servidor. A grande questo aqui que o fluxo do script no pra
na linha 15 enquanto a requisio enviada, pois a chamada
assncrona. Por isso, a funo httpReq retorna instantaneamente.
como se uma nova linha de execuo fosse criada no momento da
requisio. Outro segredo est guardado na linha 13. Nesta linha,
definimos a funo de callback que ser executada toda vez que o
estado interno do XMLHttpRequest mudar. O dispatch uma fun-
o interna httpReq (definida assim para evitar problemas com
requisies concorrentes) que usamos como callback (linhas 17 a
27). Observe que esta funo acessa o objeto ajaxRequest defi-
nido na funo externa para observar seu estado (readyState).
O valor do readyState pode ser:
wm05.indb 11 3/10/2005 15:47:27
12 5 Edio
2. contatos.htm
1.<!DOCTYPEhtmlPUBLIC-//W3C//DTDXHTML1.0Strict//EN
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd>
2.<htmlxmlns=http://www.w3.org/1999/xhtml>
3.<head>
4.<title>Ajax-ListadeContatos</title>
5.<linkhref=contatos.cssrel=stylesheettype=text/css/>
6.<scripttype=text/javascriptlanguage=JavaScript
src=ajax.js></script>
7.</head>
8.
9.<body>
10. <divid=cabecalho>Ajax-ListadeContatos</div>
11. <formid=buscaonSubmit=returnfalse>
12. Nome:<inputtype=textid=txt_filtro/>
13. <inputtype=buttononclick=evento_busca();
value=buscar/>
14. <inputtype=buttononclick=evento_adiciona();
value=adicionar/>
15. </form>
16.
17. <divid=lista>ListadeContatos</div>
18. <formid=edicaoonSubmit=returnfalse>
19. <divclass=campos>
20. Nome:<inputtype=textid=txt_nomedisabled/>
<br/>
21. e-mail:<inputtype=textid=txt_email/><br/>
22. Telefone:<inputtype=textid=txt_telefone/>
<br/>
23. <inputtype=button
onclick=evento_atualizaContato();value=OK/>
24. </div>
25. </form>
26. </body>
27. </html>
3. Continuao do arquivo ajax.js
1. /**********************************
2. EVENTOSDAINTERFACECOMOUSURIO
3. ***********************************/
4. functionevento_busca(){
5. varnome=document.getElementById(txt_filtro).
value;
6. httpReq(op=busca&nome=+escape(nome));
7. }
8.
9. functionevento_adiciona(){
10. varcampo=document.getElementById(txt_filtro);
11. httpReq(op=adiciona&nome=+escape(campo.value));
12.campo.value=;
13.}
14.
15.functionevento_carregaContato(nome){
16.httpReq(op=carregaContato&nome=+escape(nome));
17.}
18.
19.functionevento_atualizaContato(){
20. varemail=
document.getElementById(txt_email).value;
21. vartelefone=document.getElementById(
txt_telefone).value;
22. varnome=document.getElementById(txt_nome).value;
23.httpReq(op=atualizaContato&nome=+escape(nome)
24.+&email=+escape(email)
25.+&telefone=+escape(telefone));
26.}
2. Apresentao inicial do XHTML.
tos chamadas aos tratadores de eventos que estaro definidos
no nosso arquivo ajax.js. Estes eventos podem ser observados
na 3.
fcil observar que quase todas as funes trabalham de modo
semelhante. As funes de busca, adio e atualizao de con-
tatos recolhem um determinado valor digitado pelo usurio em
um campo de formulrio para criar uma string de parmetros de
requisio HTTP. Esta string finalmente passada funo de
requisio AJAX. Cada funo passa um parmetro op distinto que
usado no servidor para informar aplicao web qual operao
est sendo requisitada para os dados enviados.
Finalmente, para fechar o crculo, devemos verificar o cdigo
que roda no servidor ( ).
A classe Contato na descreve os objetos que representam
os contatos da agenda no servidor. Nesta classe (que est bem
simplificada para diminuir o tamanho do cdigo), vemos os atri-
butos do contato e a presena do mtodo serializarParaXML.
controles grficos utilizados pelo usurio. Observe que quase to-
dos tm a definio do atributo id. atravs destes atributos que
o cdigo do nosso motor AJAX consegue manipular a interface.
Observe tambm que os botes tm associados aos seus even-
wm05.indb 12 3/10/2005 15:47:31
WebMobile 13
Java Web
4. Classe Contato
1. packageajaxtest;
2.
3. publicclassContato{
4. publicStringnome;
5. publicStringemail;
6. publicStringtelefone;
7.
8. publicContato(Stringn){
9. nome=n;
10. email=desconhecido;
11. telefone=desconhecido;
12. }
13.
14. publicStringserializarParaXML(){
15. StringBuffersb=new
StringBuffer(<contato);
16. sb.append(nome=\+nome
+\);
17. sb.append(email=\+email
+\);
18. sb.append(telefone=\+
telefone+\);
19. sb.append(/>);
20. returnsb.toString();
21. }
22. }
5. Servlet Agenda
1. packageajaxtest;
2.
3. importjava.io.*;
4. importjava.util.*;
5. importjavax.servlet.*;
6. importjavax.servlet.http.*;
7.
8. publicclassAgendaextendsHttpServlet{
9.
10. privateHashMap<String,Contato>lista=
newHashMap<String,Contato>();
11.
12. protectedvoiddoGet(HttpServletRequest
req,HttpServletResponseres)throws
ServletException,
IOException{
13. res.setContentType(text/xml;
charset=UTF-8);
14. res.setHeader(Cache-Control,
no-cache);
15. PrintWriterout=res.getWriter();
16.
17. Stringop=req.getParameter(op);
18. out.print(<respop=\+op+\>);
19. if(op.equals(busca)){
20. Iterator<Contato>it=
lista.values().iterator();
21. Stringfiltro=
req.getParameter(nome);
22. while(it.hasNext()){
23. Contatoc=it.next();
24. if(c.nome.indexOf(filtro)>-1){
25. out.print(
c.serializarParaXML());
26. }
27. }
28. }elseif(op.equals(adiciona)){
29. Contatoc=newContato(req.
getParameter(nome));
30. lista.put(c.nome,c);
31. }elseif(op.equals(carregaContato)){
32. Contatoc=lista.get(req.
getParameter(nome));
33. out.print(c.serializarParaXML());
34. }elseif(op.equals(atualizaContato)){
35. Contatoc=lista.get(req.
getParameter(nome));
36. c.email=req.
getParameter(email);
37. c.telefone=req.getParameter(
telefone);
38. out.print(c.serializarParaXML());
39. }
40. out.print(</resp>);
41. }
42. }
possvel observar que o mtodo transforma o objeto em um ni-
co elemento XML, no qual existem atributos descrevendo todos
os dados do contato. Neste exemplo simples, criamos o XML na
mo. Em uma aplicao mais profissional isso no muito acon-
selhvel. O ideal seria tirar esse processo de serializao da classe
Contato e usar uma biblioteca Java para criao de XML.
Por fim, vamos ao servlet (ver ). O servlet Agenda mostra
o processo que roda no servidor. O servlet guarda como atributo
um HashMap com os contatos da Agenda indexados por strings. O
quebra-cabea comea a se fechar quando observamos o cdigo do
mtodo doGet. As linhas 13 e 14 so indispensveis em qualquer
servlet que gere XML para um motor AJAX. A linha 13 seta o tipo de
wm05.indb 13 3/10/2005 15:47:32
1 5 Edio
contedo da resposta, fazendo com que o objeto XMLHttpRequest
no browser interprete a resposta realmente como XML, e use um
charset definido (o UTF-8 usado neste caso pois a codificao
padro das strings Java). O cabealho HTTP adicionado na linha
14 importante para evitar que o XMLHttpRequest use o cache do
browser nas requisies seguintes.
Detalhando o processo
Para compreender o restante do servlet, vamos viajar por todo o
processo. Para testar a aplicao, preciso que ela seja instalada
em um contexto de qualquer servidor web que suporte servlets.
Os arquivos contatos.htm, ajax.js e contatos.css devem estar
na raiz do contexto. As classes Contato e Agenda devem estar
devidamente instaladas (diretrio WEB-INF/classes) no servidor. A
aplicao comea quando o usurio faz uma requisio do arquivo
contatos.htm. Observe que esta requisio tambm far com que
o browser tambm carregue o arquivo CSS e o JavaScript com a
implementao do motor AJAX. Este exemplo 100% assncrono,
caindo no caso em que a primeira requisio um pouco mais len-
ta justamente devido necessidade de carregar todos os arquivos
de uma vez (no to lenta neste caso j que os trs arquivos so
bem pequenos). Depois da carga inicial, o usurio se depara com
a tela da 2 na qual ele pode adicionar ou buscar contatos.
Como a lista est inicialmente vazia, vamos detalhar os passos
que ocorrem quando o usurio digita um nome no campo superior
da tela e clica em adicionar.
1. Ao digitar o texto Z no campo e clicar no boto adi-
cionar, o browser chama a funo evento_adiciona ( 3)
que est no arquivo ajax.js. Esta ligao foi determinada no
atributo onclick, que definimos na pgina XHTML.
2. A funo evento_adiciona procura no XHTML o elemento
de id igual a txt_filtro usando o mtodo getElementById do
objeto document (como especificado no DOM). Esta uma das
funcionalidades do atributo id usado nas tags. O elemento pro-
curado justamente o campo em que o usurio digitou Z.
A funo ento captura o texto digitado numa varivel e faz
a chamada funo de requisio assncrona passando como
parmetro o texto op=adiciona&nome=Z.
3. Seguindo a anlise que fizemos sobre httpReq, vemos que
feita uma requisio para o recurso ./servlet/ajaxtest.
Agenda?op=adiciona&nome=Z. A
funo retorna instantaneamente
sem esperar a resposta do ser-
vidor. O usurio j pode, por
exemplo, digitar outro nome
para ser adicionado enquanto a
requisio est sendo enviada e pro-
cessada pelo servidor.
. Pelo endereo do recurso,
observa-se que o servidor
executar o mtodo doGet do servlet Agenda no nosso contexto
para gerar o contedo da resposta. Observe que o servlet receber
na requisio os parmetros op e nome. Este servlet sempre gera
como resposta um documento com um elemento raiz de nome resp
e um atributo op. As linhas 17 e 18 da mostram que o valor do
atributo op sempre igual ao parmetro de requisio op. Nesta
primeira requisio passamos um op de valor igual a adiciona,
causando a execuo das linhas 29 e 30. Nestas linhas, um objeto
contato criado com o nome recebido como parmetro (Z) e
adicionado no HashMap. O HashMap indexado pelo nome do con-
tato para facilitar as buscas. A linha 40 fecha o documento XML
que ter nesta resposta o contedo final igual a:

<respop=adiciona></resp>

Gerar um documento XML que possa ser lido pelo objeto


XMLHttpRequest importante. Qualquer falha de sintaxe no
documento causa um erro no momento em que a resposta
processada pelo motor AJAX. Por isso, em projetos grandes no
aconselhvel gerar diretamente o XML como fizemos. O ideal
seria utilizar uma implementao do DOM na linguagem do lado
servidor para criar os documentos de reposta.
. Quando o objeto XMLHttpRequest terminar de receber
esta resposta corretamente, seu readyState mudar para 4
e o status mudar para 200. A funo de callback definida
como dispatch ser chamada e agora sim far o processamen-
to da resposta. Na linha 20 da 1, usamosajaxRequest.
responseXMLpara retornar o objeto Document que represen-
ta o XML recebido. Este objeto pode ser manipulado seguin-
do o padro DOM. Assim, o ajaxRequest.responseXML.
documentElement retorna o Element raiz do documento XML
(neste caso, o nosso elemento resp). Em uma aplicao AJAX
grande, normalmente estabelecido um padro para o XML
de resposta para simplificar o cdigo da funo callback que
trata as respostas do servidor. Nesta aplicao, o padro pode
ser observado nas linhas 21 e 22 da 1. Usamos outro mto-
do DOM (getAttribute) para descobrir o valor do atributo
op recebido na raiz do documento (que nesta primeira requisi-
o igual a adiciona). Este valor usado para construir um
comando JavaScript que ser processado em tempo de execu-
o pela funo eval. Esta uma forma simples de despachar
as mensagens XML para as devidas funes de processamento.
Observe que nesta primeira requisio, a expresso gerada
tratar_adiciona(message.childNodes);. O DOM de-
fine que o atributo childNodes de um Element conter a
lista de ns filhos do elemento (que neste caso uma lista
vazia). Assim, finalmente a funo eval chamar o tratador
de resposta adequado, passando a lista dos ns contidos no
XML que podem ser usados para modificar a interface com o
usurio.
wm05.indb 14 3/10/2005 15:47:34
WebMobile 1
Java Web
. As funes de tratamento nesta aplicao esto tam-
bm no arquivo ajax.js e esto definidas na . A funo
tratar_adiciona no faz muita coisa nem processa dados
da resposta. Apenas confirma o cadastro do contato, modifi-
cando o texto da barra de status no browser. Para incrementar
a resposta da interface no momento em que a confirmao de
um cadastro chega, basta adicionar funcionalidades no cdigo
desta funo.
O estudo cuidadoso dos detalhes deste processo comea a
esclarecer melhor as causas do menor tempo de resposta da abor-
dagem AJAX. Na abordagem clssica, alm do usurio precisar
aguardar todo o processo do HTTP terminar, seria necessrio o
servidor reenviar todo o HTML da pgina para re-exibir o for-
mulrio. Isso geraria um trfego de quase 1K (1024 bytes), que
poderia ser muito maior se o nosso cdigo no fosse enxuto.
Usando o XMLHttpRequest, alm de aproveitar a natureza assn-
crona do AJAX, possvel observar que o trfego do XML gerado
de apenas 27 bytes.
Os outros eventos de usurio completam a funcionalidade
da aplicao. O evento do boto buscar gera uma requisio
(./servlet/ajaxtest.Agenda?op=busca&nome=algumnome)
que faz com que o servlet Agenda execute as linhas 20 a 27 na
. Neste ponto, o servlet faz a interao com cada um dos
contatos cadastrados, buscando aqueles que contm a string de
filtro recebida em seus nomes. Na linha 25, para cada objeto en-
contrado enviada a sada do mtodo serializarParaXML do
contato. Assim, o documento XML gerado para uma busca em uma
lista completa com filtro igual Jo em uma lista que tem Z,
Joo e Jos seria algo parecido com:
<respop=busca>
<contatonome=Jooemail=joao@provedor.com
telefone=4444444/>
<contatonome=Josemail=jose@provedor.com
telefone=3333333/>
</resp>
A funo tratar_busca a que ser chamada para tratar
esta resposta. O objetivo mostrar os contatos buscados e criar
links para fazer o evento carregaContato. Novamente na , a
linha 6 faz a localizao do elemento div de id igual a lista que
foi definido no XHTML. As linhas 8 e 9 limpam todo o contedo
que possa estar dentro do elemento lista. Observe nestas linhas
a chamada ao mtodo removeChild do Element que tambm
est definido no DOM. O loop da linha 12 faz o processamen-
to de cada elemento recebido dentro do resp no XML gerado.
A linha 13 faz a captura do atributo nome. A partir da linha
6. Continuao do arquivo ajax.js
1./***********************************
2.TRATADORESDERESPOSTASDOSERVIDOR
3.***********************************/
4.functiontratar_busca(conteudo){
5.varlista,no,nome,i;
6.lista=document.getElementById(lista);
7.
8.while(lista.childNodes.length>0){
9. lista.removeChild(lista.firstChild);
10. }
11.
12. for(i=0;i<conteudo.length;i++){
13. nome=conteudo[i].getAttribute(nome);
14. no=document.createElement(a);
15. no.className=linkcontato;
16. no.setAttribute(href,
javascript:evento_carregaContato(+nome+));
17. no.appendChild(document.createTextNode(nome));
18. lista.appendChild(no);
19. }
20. window.status=conteudo.length+contatos;
21. }
22.
23. functiontratar_adiciona(conteudo){
24. window.status=Elementoadicionado!;
25. }
26.
27. functiontratar_carregaContato(conteudo){
28. vartxt_edicao_email=document.getElementById(
txt_nome);
29. txt_edicao_email.value=
conteudo[0].getAttribute(nome);
30.
31. vartxt_email=document.getElementById(txt_email);
32. txt_email.value=conteudo[0].getAttribute(email);
33.
34. vartxt_telefone=document.getElementById(
txt_telefone);
35. txt_telefone.value=conteudo[0].getAttribute(telefone);
36. window.status=Editandocontato;
37. }
38.
39. functiontratar_atualizaContato(conteudo){
40. alert(Dadosatualizados);
41. }
wm05.indb 15 3/10/2005 15:47:36
1 5 Edio
14 comeamos a ver como ocorre as atualizaes na interface
com o usurio. Nesta linha, usado um mtodo DOM capaz de
alterar a estrutura do documento XHTML atravs da criao de
novos elementos. Um elemento a criado para exibir um link.
A linha 15 seta a classe da folha de estilo usada pelo novo link.
Na linha 16 usado o mtodo setAttribute para modificar um
parmetro da tag. Setamos o href para fazer a chamada funo
evento_carregaContato com o nome do contato a cada cli-
que no novo link. A linha 17 adiciona o texto do link. O mtodo
document.createTextNode cria o elemento de texto usando
o nome do contato e adiciona-o como filho do link. Finalmente,
a linha 18 adiciona o novo link ao elemento lista. Cada vez que
a linha 18 executada, um novo link fica disponvel para o usu-
rio. Tomando como exemplo a resposta busca com filtro Jo,
a funo tratar_busca criaria dinamicamente o HTML abaixo e
adicion-lo-ia ao elemento lista:
<ahref=javascript:evento_carregaContato(Joo)class=
linkcontato>Joo</a>
<ahref=javascript:evento_carregaContato(Jos)class=
linkcontato>Jos</a>
Esses novos links aparecem para o usurio sem que seja ne-
cessrio recarregar a pgina, semelhante ao modo como uma
aplicao desktop atualiza um elemento de sua interface. Nesse
momento, o usurio veria algo parecido com a tela da 3.
Observe novamente que o CSS foi o responsvel por arrumar o
design dos links e criar o efeito de mudana de cor com o movi-
mento e clique do mouse. O uso correto de estilos CSS tambm
evita a utilizao de muitas tabelas no cdigo HTML. Veja o cdi-
go do arquivo contatos.css na .
3. Tela do sistema com alguns elementos na lista.
7. Arquivo de folhas de estilo contatos.css
1body{
2 background:ButtonFace;
3 margin:0px;
4 color:ButtonText;
5 font-family:Verdana;
6}
7#cabecalho{
8 background:ActiveCaption;
9 color:ButtonHighlight;
10 padding:3px;
11 text-align:center;
12 font-size:large;
13}
14#busca{
15padding:5px;
16margin:2px;
17 text-align:center;
18border:1pxActiveBorderoutset;
19}
20#lista{
21 float:left;
22 background:window;
23 width:20%;
24 height:400px;
25 border:1pxblacksolid;
26 font-size:small;
27}
28 #edicao{
29 height:400px;
30 margin:0px;
31 border:1pxblacksolid;
32}
33.linkcontato{
34display:block;
35text-decoration:none;
36}
37.linkcontato:HOVER{
38background:Highlight;
39 color:highlightText;
40}
41.linkcontato:ACTIVE{
42background:buttontext;
43 color:buttonFace;
44}
45.campos{
46 text-align:right;
47 width:450px;
48 line-height:40px;
49}
wm05.indb 16 3/10/2005 15:47:40
WebMobile 1
Java Web
Ao clicar em um desses links, executa-se a funo
evento_carregaContato. A requisio gerada por essa funo
apenas faz com que o servlet localize o contato de nome igual ao
passado no HashMap (linhas 32 e 33 na ). O tratador desta
resposta (funo tratar_carregaContatonas linhas 28 a 36
da ) localiza cada campo do formulrio de edio e atualiza os
seus valores com os dados do contato encontrado no XML.
Finalmente, a funo evento_atualizaContato disparada
pelo clique no boto OK do formulrio de edio. Ela gera uma
requisio que far a alterao nos dados do contato. O servlet faz
a busca e atualizao nas linhas 35 a 37 da . O tratamento da
resposta apenas a apresentao de uma caixa de dilogo confir-
mando a operao, como mostra a funo(linha 40 da ).
Para quem quiser praticar, um bom exerccio inicial seria agora
criar um boto no formulrio de edio que permita excluir um
contato da lista.
Consideraes
Esse um exemplo de aplicao bem simples que usa a aborda-
gem AJAX de forma totalmente assncrona. Observe que o ende-
reo na barra de localizao do browser nunca sai do apontador
para o arquivo contatos.htm.
Do lado servidor, o primeiro problema bvio da aplicao que
no existe persistncia dos contatos. Ou seja, quando o contexto
do servidor for reiniciado os contatos cadastrados sero perdidos.
Voc pode usar alguns dos inmeros mtodos de persistncia de
objetos para resolver o problema. Usar o acesso a um banco de
dados relacional e guardar os dados dos contatos numa tabela
certamente a maneira mais simples e conhecida para solucionar
a questo. Outro problema a ser destacado novamente no servidor
a gerao do XML na mo. Certamente a primeira coisa a se
modificar na aplicao seria aplicar a utilizao de uma implemen-
tao DOM do Java para fazer a criao dos
documentos XML.
J no lado do browser,
no foi implementada
Marcelo Burgos Morgade Cortizo
(morgade@gmail.com) Mestre em Redes
de Computadores pela Universidade Salvador e
Bacharel em Cincia da Computao pela
Universidade Salvador. Atualmente
professor de Tcnicas e Linguagens de Programao
e Sistemas Distribudos do curso de Sistemas de
Informao das Faculdades Jorge Amado (Salvador
BA) e Analista de Sistemas da Empresa Baiana de
guas e Saneamento (EMBASA).
Ajax, A New Approach to Web Applications
www.adaptivepath.com/publications/essays/archives/000385.php
[Artigo do J. J. Garret, que props a utilizao do termo AJAX]
Document Object Model
www.w3.org/dom [Especicao do DOM]
Detalhes sobre o objeto XMLHttpRequest
www.xml.com/pub/a/2005/02/09/xml-http-request.html
Casdascading Style Sheets
www.w3.org/Style/CSS/ [Especicao do CSS]
nenhuma estrutura de cache dos dados. possvel criar um mdulo
do motor AJAX para guardar na memria os dados dos contatos
j buscados ou dos contatos que j foram cadastrados. Assim,
possvel evitar o acesso ao servidor em alguns eventos do usu-
rio. possvel inclusive implementar classes em JavaScript que
espelhem as classes ou dados dos objetos serializados em XML,
tornando o trabalho mais elegante. bvio que isso aumenta
bastante o tamanho e a complexidade do cdigo, alm trazer to-
dos os problemas de verificao de cache desatualizado.
Outra questo importante diz respeito ao controle das transa-
es. sempre interessante informar de alguma maneira ao usurio
que as operaes pedidas pelo browser esto sendo confirmadas
pelo servidor. Esta aplicao usa apenas a barra de status do
browser para mostrar algumas mensagens de confirmao. Seria
interessante mostrar estas informaes em um espao que cha-
masse mais a ateno do usurio.
Muita coisa ainda pode ser melhorada nesse exemplo. Mas ape-
sar da simplicidade da aplicao, possvel com ela entender as
diferenas fundamentais entre a abordagem clssica de interfaces
web e a abordagem assncrona com AJAX. Agora s estudar um
pouco mais a lista de tecnologias associadas ao AJAX e comear a
criar o seu prprio GMail!
wm05.indb 17 3/10/2005 15:47:43
1 5 Edio
Desenvolvendo
aplicaes J2ME
para PDAs
ao desenvolvimento de uma aplicao para este tipo de plata-
forma, desde a instalao das ferramentas necessrias para seu
desenvolvimento, at o desenvolvimento de uma aplicao real
atravs de um exemplo bsico.
Processo tcnico de desenvolvimento
de uma aplicao Palm OS
O desenvolvimento de uma aplicao para dispositivos mveis,
mais precisamente PDAs, envolvem alguns passos tcnicos bas-
tante simples e que so necessrios para sua realizao. Os passos
que sero descritos ao longo deste artigo so:
1. Definio das ferramentas necessrias para o desenvol-
vimento;
2. Preparao do ambiente de de-
senvolvimento (instalao e confi-
gurao das ferramentas);
3. Desenvolvimento da aplica-
o (sua construo efetiva);
. Converso da aplicao de
pacote .jar para arquivo .prc;
. Simulao da aplicao.
As prximas sees iro descre-
ver cada uma desses passos citados
anteriormente, apresentando um
exemplo bem simples de aplicao
como mecanismo para facilitar o
aprendizado. O exemplo a ser des-
crito consiste em uma aplicao
do tipo Hello World.
O
s dispositivos portteis tm se tornado algo muito comum
atualmente. Celulares, PDAs (Personal Digital Assistant ou
Assistente Pessoal Digital) e smartphones (juno de PDA
e celular) esto sendo utilizados cada vez mais pelas pessoas
para realizar diversas tarefas do nosso cotidiano tais como apli-
caes de fora de venda, coletores de dados, comanda eletrni-
ca, entre outras. Com isso, surge um novo mercado em expanso
e muito promissor: o de desenvolvimento de software para dis-
positivos portteis.
Existem diversos sistemas operacionais executando nestes dis-
positivos: Windows Mobile, Palm OS, Linux e Symbian. No que diz
respeito a linguagens de programao, existe um universo muito
maior. S para citar, temos: C, C++, C#,
Pascal, Visual Basic e Java.
Iremos demonstrar o desen-
volvimento de software para
o sistema operacional mais
utilizado em PDAs, o Palm OS
(que j pode ser encontra-
do em alguns smartphones).
Para isso, utilizaremos a lin-
guagem Java, que j muito
utilizada em servidores web
e aplicaes desktop e vem
ganhando notoriedade nestes
tipos de aplicaes atravs
da plataforma J2ME (Java 2
Micro Edition).
Ao longo deste artigo ire-
mos apresentar todos os
passos tcnicos relacionados
por Fbio Medeiros
wm05.indb 18 3/10/2005 15:47:50
WebMobile 1
Java Mobile
Definio das ferramentas necessrias
O primeiro passo quando iniciamos o desenvolvimento de qual-
quer tipo de aplicao a especificao e configurao do am-
biente onde ser realizado o desenvolvimento. Para este artigo,
ser necessria a instalao dos seguintes programas (todos dis-
ponibilizados gratuitamente na internet), seguindo essa ordem:
Wireless ToolKit (WTK) da Sun Microsystems;
O Websphere Everyplace Micro Environment (WEME) da IBM;
O simulador do Palm OS, da palmSource.
A seguir iremos descrever as atividades necessrias para a ins-
talao e configurao de cada programa citado, e sua forma de
obteno.
Instalando o WTK
O WTK a ferramenta disponibilizada pela Sun para a criao,
gerao e teste/simulao das aplicaes Java para dispositi-
vos portteis (basicamente de celulares), chamadas de suite de
MIDlets ou, simplesmente, MIDlets. Alguns passos e pr-requisitos
so necessrios para a instalao e configurao do WTK.
Instalao do J2SDK
Antes de instalar o WTK, o leitor dever ter instalado em seu
computador o J2SDK 1.4.2 ou uma verso superior e ter noes
bsicas da linguagem de programao Java e de J2ME. O paco-
te do J2SDK 1.4.2 pode ser obtido gratuitamente no endereo
http://java.sun.com/j2se/1.4.2/download.html.
Download do WTK
O WTK pode ser baixado do site da Sun (http://java.sun.com/
products/j2mewtoolkit/download-2_2.html) e, at a data da escri-
ta deste artigo, est na verso 2.2, possuindo suporte s seguin-
tes tecnologias:
Connected Limited Device Configuration (CLDC) 1.1;
Mobile Information Device Profile (MIDP) 2.0;
Wireless Messaging API (WMA) 2.0;
Mobile Media API (MMAPI) 1.1;
PDA Optional Packages for the J2ME Platform (JSR-75);
Java APIs para Bluetooth;
Web Services;
Mobile 3D Graphics API for J2ME.
Instalao do WTK
A instalao do arquivo do WTK (j2me_wireless_toolkit-2_2-
windows.exe) bastante simples. Basta executar o arquivo bai-
xado. Durante a instalao ser solicitado o diretrio onde est
instalado o J2SDK e o diretrio onde se deve instalar o WTK. Deixe
o padro (C:\WTK22) e prossiga at o fim da instalao. Terminada
a instalao, a estrutura de diretrios da 1 criada.
Onde no diretrio:
appdb so armazenados os arquivos de persistncia que
venham a ser criados pelas aplicaes com a API RMS (Record
Management System) do J2ME;
apps ficam os projetos criados (observem que j existem
alguns projetos que podem ser testados com o WTK);
bin ficam os executveis do WTK;
docs fica a documentao do WTK;
lib ficam as bibliotecas que sejam necessrias;
sessions ficam gravadas as sesses de execuo da simula-
o no prprio ambiente do WTK;
wtklib esto bibliotecas utilizadas pelo WTK.
Instalando o WEME
O WEME (Websphere Everyplace Micro Environment) contm a
implementao Java da IBM para dispositivos portteis com sis-
tema operacional Palm OS a partir da verso 5.2.x. Os passos para
sua instalao so:
Download do WEME
O download pode ser feito no site da PalmSource
(www.palmos.com/dev/tech/java/). Para isso, basta clicar em
Download Java Technology for Palm OS Garnet Toolkit.
O WEME que ser baixado para ser utilizado na simulao o
pacote para simulao com Windows. Ele contm no s a mqui-
na virtual Java (JVM), conhecida por J9, mas tambm ferramentas
para a converso dos pacotes gerados pelo WTK (a suite MIDlets
composta de dois arquivos com o mesmo nome, mas de extenses
diferentes: um com extenso .jad, que basicamente o descri-
tor da aplicao e outro com extenso .jar, que o arquivo que
contm os MIDlets e arquivos de recurso necessrios aplicao)
para o formato de arquivos do Palm OS (.prc), bem como a docu-
mentao do WEME.
Instalao do WEME
O arquivo compactado (Java_Tech_for_Garnet_WEME57.zip)
pode ser descompactado em qualquer lugar. Para a finalidade do
artigo, descompactamos em C:\WEME. Quando descompactado,
ele apresenta a estrutura da 2.
1. Estrutura de diretrios
do WTK
2. Estrutura de diretrios do
WEME.
wm05.indb 19 3/10/2005 15:47:54
20 5 Edio
Onde no diretrio:
Documentation fica a documentao do WEME;
Jsr172 ficam os arquivos .prc que podem ser carregados
para o simulador que implementam a JSR 172, ou, os Web
Services para J2ME;
Jsr75 ficam os arquivos .prc que podem ser copiados para
o simulador e que implementam a JSR 75, ou, PDA Optional
Packages, que contm as APIs de acesso ao PIM (Personal
Information Manager ou Gerenciador de Informaes Pessoais)
e as APIs de acesso a arquivos;
Jvm temos somente o subdiretrio Simulator que contm os
arquivos necessrios para se executar a JVM no simulador;
Samples tem-se uma aplicao exemplo que pode ser copia-
da para o simulador;
Tools temos mais dois subdiretrios: bin e lib. No subdiret-
rio bin temos a ferramenta da IBM para a converso de pacotes
.jar para arquivos .prc. E no subdiretrio lib temos as classes
utilizadas para a ferramenta de converso.
Instalando o simulador
O ltimo passo na configurao do ambiente de desenvolvimen-
to consiste na instalao do simulador do Palm OS.
Download do simulador
O simulador de Palm OS pode ser baixado do site da PalmSource
(www.palmos.com/dev/tools/simulator/). No site podemos encontrar
basicamente dois tipos de simuladores: os simuladores do sistema
operacional Palm OS Garnet (verso 5.2, 5.3 e 5.4) e os simuladores
do Palm OS Cobalt (verso 6.0, 6.0.1 e 6.1). A verso do simulador
utilizada ser a do Palm OS Garnet 5.4, pois a nica verso para
simulao que o WEME oferece suporte at o momento.
Instalao do simulador
Tendo baixado o arquivo compactado (PalmOS_Garnet_54_
Simulator.zip), basta descompact-lo em qualquer lugar (para
nosso exemplo ser descompactado em C:\PalmOS54). Na 3
temos a estrutura de diretrios criada.
Observe os subdiretrios debug e release. Em ambos os diret-
rios, encontramos o simulador de Palm OS, a nica diferena que
a verso que est no diretrio debug a do simulador com opes
de debug para teste de aplicaes, enquanto a verso que est no
diretrio release consiste somente do simulador. Assim, usaremos
o simulador do diretrio release por
no termos necessidade de depurar o
nosso software.
No subdiretrio Scripting temos
um outro subdiretrio, que contm
pequenas bibliotecas na linguagem
de programao Perl utilizadas pelo
simulador.
Instalao do WEME no simulador
Como se sabe, aplicaes Java necessitam de uma JVM para
funcionar. Assim, precisamos copiar a JVM do WEME para o simu-
lador para que o nosso exemplo funcione. Para instalar a JVM do
WEME no simulador, basta seguir estes passos:
1. copiar a DLL J9JavaVMMidp20.dll (C:\Weme\Jvm\
Simulator) para o diretrio onde est instalado o simulador do
Palm OS (C:\PalmOS54\release);
2. executar o arquivo palmsim.exe. Em seguida ser solici-
tado a ROM do sistema operacional que ser utilizada (a ROM
neste caso a imagem do sistema operacional utilizada no
dispositivo real). Escolha a Simulator_Full_enUS_Release.rom
(ver ) que contm somente o sistema operacional em in-
gls (infelizmente nesta verso do simulador no temos a ROM
com o idioma portugus);
3. Tendo selecionado a ROM, a tela da ser apresenta-
da. Esta a interface inicial do PDA. Se por acaso a tela que
aparecer no for esta, basta clicar no desenho da casinha que
existe no canto inferior esquerdo do simulador. Este cone
chamado de Home;
. Antes de instalarmos a JVM no simulador, precisamos con-
figur-lo para que funcione corretamente. Clicando-se com o
boto direito em cima do simulador, um menu aberto com al-
. Selecionando a ROM para o simulador.
. Tela inicial do sistema
operacional. . Configurando a memria RAM.
3. Estrutura de diretrios
do simulador.
wm05.indb 20 3/10/2005 15:47:59
WebMobile 21
Java Mobile
gumas opes. Dentre elas temos a opo Settings. Nela iremos
configurar as opes de memria do simulador. Observe a
e selecione a opo 8 MB para memria RAM. Se ela j no es-
tiver selecionada, o simulador ir reiniciar e pode-se continuar
a configurao.
. Tendo configurado a memria RAM, vamos configurar a
memria Heap (que consiste na memria disponvel para exe-
cuo das aplicaes). Para executar a JVM necessrio que se
tenha pelo menos 1024 KB de memria Heap. Observe a e
selecione 1024 KB. O simulador ir reiniciar novamente.
. Pronto. Com a memria do simulador configurada, vamos
instalar a JVM. Para isso, clique novamente com o boto direito
sobre o simulador e escolha a opo Install | Database. Uma
tela de procura do Windows ir aparecer e nela procuramos
o diretrio onde esto os arquivos da JVM (C:\WEME\JVM\
Simulator). Selecione os arquivos da e clique em Abrir. Os
arquivos que sero copiados constituem a JVM:
o ams.prc, j9keystore.prc e o J9Launcher.prc, so os ar-
quivos que gerenciam os MIDlets no PDA;
o J9JavaVMMidp20.prc e o PalmMidp20.prc, so os ar-
quivos que contm a implementao do CLDC (Connected
Limited Device Configuration) e do MIDP (Mobile Information
Device Profile) para Palm OS;
os arquivos j9pref.prc, j9secpol.prc e pref.prc, permitem
que se configurem, no simulador, algumas caractersticas
relativas ao uso dos MIDlets no Palm OS.
Aps a instalao, o simulador mostrar a tela da . Com
isso, temos preparado o nosso ambiente de desenvolvimento.
Desenvolvendo a aplicao
Agora comearemos o desenvolvimento da aplicao exemplo
HelloWorld. Para isso, usaremos a ferramenta KToolbar (acessada
atravs do caminho apresentado
na 10). Para criar um novo
projeto no WTK, clique no boto
New Project e defina os campos
nome com HelloWorldPDA e nome
da classe principal com Hello-
WorldPDA.
Tendo criado o projeto, sero
apresentadas suas configuraes.
Em Target Platform, escolha
Custom (escolhemos a Custom
pois assim podemos especificar
quais APIs faro parte do nosso
projeto) e marque as opes mos-
tradas na 11.
. Configurando a memria Heap.
. Selecionando os arquivos da JVM.
. Tela mostrando a JVM instalada.
10. Executando a KToolbar no menu Iniciar do Windows.
11. Tela de configurao da aplicao.
wm05.indb 21 3/10/2005 15:48:02
22 5 Edio
Escolhemos como Profile (um profile ou perfil um conjunto
de APIs adicionadas a uma determinada configurao para ofe-
recer suporte a dispositivos mveis especficos. Assim um perfil
serve para ampliar o conjunto de APIs da configurao ao qual
foi desenvolvida) o MIDP 2.0, que a verso mais atual do perfil
MIDP, pois contm melhoras nos componentes grficos. Esco-
lhemos a Configuration (na plataforma J2ME, uma configurao
define um mnimo para execuo do ambiente Java para uma
famlia de dispositivos: uma Java Virtual Machine JVM e um
conjunto de APIs bsicas) CLDC 1.1, que tambm a mais atual
da configurao CLDC.
Como neste exemplo no necessitaremos das APIs de men-
sagens, escolhemos a opo No WMA Support em Optional. As
demais APIs tambm no foram escolhidas pelo mesmo motivo
da API de mensagens, ou seja, no sero usadas na aplicao.
Feito isto, daremos incio implementao da aplicao. A
1 apresenta o cdigo da aplicao HelloWorldPDA.java. Nas li-
nhas 1 e 2 fazemos os imports necessrios para a aplicao, que
sero alguns componentes grficos e a classe MIDlet. Na linha 3
declaramos o nome da classe e de quem ela herda (neste caso,
ela herda diretamente da classe MIDlet que a classe principal
para o perfil MIDP, assim como a classe Applet a classe princi-
pal para se criar Applets) e implementamos a interface Comman-
dListener que serve para capturar os eventos do ativamento do
Commands, tais como pressionamento do boto.
Da linha 4 8, declaramos as classes a serem utilizadas na
aplicao. Entre elas dois Command, que no simulador serviro
como botes, um TextField que nada mais que uma caixa de
texto; um Display, que serve para gerenciar a tela do dispositivo
e um Form que herda da classe Screen, permitindo que compo-
nentes grficos (tais como, Command e TextField) sejam monta-
dos nela para serem visualizados na tela.
Na linha 9 temos o construtor da classe que atribui as classes
aos objetos da aplicao e acrescenta os objetos ao Form. Das
linhas 10 a 14 temos a instncia dos objetos declarados nas
linhas 4 a 8. Observe que a instncia destes objetos muito se-
melhante quando se desenvolve em Java para aplicao desktop,
ou seja, nomeDoObjeto = new nomeDaClasse(). Nas linhas 15
a 18 observamos um mtodo usado repetidamente do objeto
form, o mtodo append(). A 1 descreve um comentrio sobre
a alocao dos objetos de interface em uma posio especfica
na tela do aparelho.
1. Exemplo de Hello World
1.importjavax.microedition.lcdui.*;
2.importjavax.microedition.midlet.*;
3.publicclassHelloWorldPDAextendsMIDletimplements
CommandListener
{
4.publicCommandcmdOK;
5.publicCommandcmdExit;
6.publicTextFieldtxtTexto;
7.publicDisplaytela;
8.publicFormform;
9.publicHelloWorldPDA()
{
10.tela=Display.getDisplay(this);
11.form=newForm(TestePDA);
12.cmdOK=newCommand(OK,Command.OK,1);
13.cmdExit=newCommand(Sair,Command.EXIT,1);
14.txtTexto=newTextField(Exemplo,null,50,
TextField.UNEDITABLE);
15.form.append(txtTexto);
16.form.addCommand(cmdOK);
17.form.addCommand(cmdExit);
18.form.setCommandListener(this);
}
19.protectedvoidstartApp()
{
20.tela.setCurrent(form);
}
21.protectedvoidpauseApp()
{}
22.protectedvoiddestroyApp(booleancondicao)
{}
23.publicvoidcommandAction(Commandc,Displayabled)
{
24.if(c==cmdOK)
{
25.txtTexto.setString(OlMundo!);
}
26.elseif(c==cmdExit)
{
27.destroyApp(true);
28.notifyDestroyed();
}
}
}
wm05.indb 22 3/10/2005 15:48:04
WebMobile 23
Java Mobile
1. Alocao de objetos de interface em uma
posio especfica da tela
Diferente do desenvolvimento em Java para desktop, em J2ME no
podemos colocar os objetos de interface na tela na posio que
desejamos, mas somente podemos adicion-los ao form, que os
organiza um abaixo do outro.
S podemos colocar objetos na posio da tela que desejamos se
criarmos classes que herdem de Canvas ou CustomItem.
Na linha 19 temos o mtodo que d incio aplicao, o
startApp(), que deve existir em qualquer MIDlet. No caso de
aplicaes Java para desktop, no possumos este mtodo para
dar incio aplicao, mas sim o mtodo main. Os outros dois
mtodos, pauseApp() na linha 21 utilizado quando o MIDlet
for pausado por um evento externo, por exemplo e o mtodo
destroyApp() na linha 22 que chamado quando a aplicao
encerrada. Este ltimo pode ser utilizado para liberar recur-
sos do dispositivo, garantir o fechamento de arquivos que foram
abertos dentro da aplicao. Ambos so mtodos obrigatrios
nos MIDlets, pois como so mtodos abstratos na classe MID-
let, devem ser implementados nas classes que herdam de MIDlet,
mesmo que o mtodo seja vazio. E na linha 23 temos o mtodo
executado quando um dos Commands for ativado. Se tiver sido o
Command OK a caixa de texto recebe uma mensagem, se tiver
sido o Command Exit, samos da aplicao.
Aps a codificao da aplicao, salve o arquivo como
HelloWorldPDA.java no diretrio C:\WTK22\apps\HelloWoldPDA\src.
Na estrutura de diretrio criada, o diretrio bin o local onde fi-
caro guardados os arquivos .jar e .jad. O diretrio lib, onde ficaro
as bibliotecas de terceiros que venhamos a utilizar no desenvolvi-
mento do software. No diretrio res, ficam os arquivos de recursos
(imagens, cones e udio, por exemplo) utilizados na aplicao;
e no diretrio src ficaro todos os arquivo .java da aplicao. A
12 mostra a tela da KToolbar com a criao do projeto.
Agora clique no boto Build, que compilar nossa aplicao.
A aplicao j foi desenvolvida para o nosso exemplo. O passo
seguinte consiste na criao de um pacote com extenso .jar. Para
isso, clique no menu Project e na opo Package Create Package.
O pacote ser criado e estar disponvel no diretrio bin.
Convertendo a aplicao .jar para .prc
A converso do pacote .jar para .prc se faz necessria para que
ele seja copiado para a memria do simulador que somente aceita
aplicativos com a extenso .prc (que seriam os executveis, se
comparado com o ambiente Windows) ou .pdb (que seriam os
arquivos utilizados pelos executveis).
Para converter este pacote para o formato .prc usamos a
ferramenta de converso do WEME, a IBM WebSphere Micro
Environment Palm OS Developer Toolkit. Para iniciar a converso,
basta executar o arquivo jartoprc_w.exe, que se encontra em
C:\WEME\Tools\bin (ver 13).
Nela procuramos o nome do arquivo .jad que ser convertido
clicando-se em Browse... que est ao lado da caixa de texto de
JAD File or URL. Uma tela se abrir e nela escolheremos o arquivo
HelloWorldPDA.jad, criado anteriormente.
Observe que alguns campos so preenchidos automaticamente.
Os outros dois campos (Large Icon File e Small Icon File) servem
para que se use um cone, no formato PNG, para representar a
aplicao no simulador.
Basta agora preencher a caixa Creator ID com pda0, por exem-
plo. O Creator ID serve para identificar o software e suas bases
de dados no sistema operacional Palm OS e composto de quatro
caracteres. Geralmente ele nico por aplicao. Para o conversor
da IBM, ele deve possuir pelo menos um dgito numrico.
Agora s clicar em Generate PRC para realizar a converso
dos arquivos. Se a gerao for bem sucedida a tela mostrar uma
mensagem parecida com a da 1.
O arquivo HelloWorldPDA.prc foi gerado e est no mesmo dire-
trio do arquivo .jad, no diretrio bin.
12. Tela aps a criao do projeto.
13. Tela principal da ferramenta de converso.
1. Mensagem de confirmao.
wm05.indb 23 3/10/2005 15:48:06
2 5 Edio
Fbio Medeiros (fabmedeiros@gmail.com)
Tecnlogo em Telemtica, formado pelo CEFET-CE.
Desenvolve desde 2000, tendo trabalhado
com PHP, C, C++, C# e Java. Atualmente
trabalha no Ministrio Pblico Federal
como Tcnico em informtica. Nas horas vagas gosta de
desenvolver aplicaes J2ME para PDAs.
Simulando a aplicao
O ltimo passo no desenvolvimento de uma aplicao para PDAs
consiste na simulao da aplicao. A simulao serve para que
possamos ver como nossa aplicao funcionar em um dispositivo
real. Claro que nem sempre problemas apresentados em um uso
real sero apresentados pelo simulador devido s caractersticas
do hardware real. Assim, simulando a aplicao podemos ver como
est a nossa interface grfica, o que poderia ser melhorado, que
erros podem acontecer, etc.
Para copiar o arquivo HelloWorldPDA.prc gerado para o simula-
dor, basta clicar com o boto direito no simulador e escolher a
opo Install Database8. Uma tela de localizao de arquivo
abrir e escolhemos o arquivo HelloWorldPDA.prc (pode-se fazer
a cpia tambm selecionando o arquivo HelloWorldPDA.prc e ar-
rastando-o para o simulador). Tendo copiado o arquivo, a tela da
1 ser apresentada.
Agora basta clicar naplicao HelloWorldPDA que a tela da
1 ser mostrada. Observem que a tela tem somente dois
botes.
Ao se clicar no boto OK a mensagem Ol Mundo! ser exibi-
da na caixa de texto Exemplo. Se for pressionado o boto sair, a
aplicao encerrada.
Se o leitor clicar no menu com o ttulo TestePDA, um sub-menu
ser aberto com as opes OK e Sair, possuindo as mesmas fun-
cionalidades dos botes. Isso porque a JVM transforma todos os
botes inseridos na aplicao em opes de sub-menu.
Com isso chegamos ao final do desenvolvimento de uma aplica-
o bsica para Palm OS.
Concluso
Como pudemos ver, o desenvolvimento de aplicaes Java para
o Palm OS relativamente fcil. Um ponto bastante interessante
abordado neste artigo a seqncia de passos que leva um de-
senvolvedor, iniciante, a construir uma nova aplicao, desde a
preparao do ambiente de desenvolvimento at a simulao da
aplicao.
Por no ser o foco principal do artigo, foram mostrados somen-
te alguns componentes bsicos, como botes e caixas de texto,
mas a API possui recursos como ComboBox, barra grfica, caixa
de lista e outros. Outros MIDlets baixados da internet para celu-
lares tambm podem ser convertidos com a ferramenta do WEME,
desde que no usem APIs proprietrias do fabricante do celular.
Alm disso, importante ressaltar que a aplicao que desenvol-
vermos pode ser utilizada tanto em celulares que possuam uma
JVM quanto PDAs com sistema operacional Windows Mobile 2003,
que possui tambm uma verso da JVM J9.
Este o passo inicial no desenvolvimento deste tipo de aplica-
o. Em um prximo artigo iremos expandir esse conhecimento,
apresentando a utilizao de novos componentes grficos do J2ME
permitindo o desenvolvimento de aplicaes mais complexas. Mos-
traremos as principais caractersticas desses componentes e como
eles ficam implementados em dispositivos com Palm OS.
1. Software HelloWorldPDA
instalado. 1. Tela inicial da aplicao.
wm05.indb 24 3/10/2005 15:48:09
WebMobile 2
Java
por Bruno Chaves Rocha Lima e
Edgar Barbosa de Souza
Interface
Grfca
para
aplicaes
J2ME
U
ma interface grfica atraente, com uma arte bem trabalha-
da, um bom pr-requisito para o sucesso de um jogo ou
de um aplicativo. Quando se trata de dispositivos mveis,
como celulares e PDAs, existe um outro fator muito importante
para o sucesso dessas aplicaes: a acessibilidade aos recursos do
aplicativo. Devido s limitaes do aparelho (tamanho da tela,
quantidade de cores, memria, entre outras), a interao do usu-
rio com o dispositivo bem diferente, por exemplo, da interao
que ele teria com um computador.
Devido a essas caractersticas especficas deste tipo de apli-
cao, o desenvolvedor de aplicaes para dispositivos mveis
deve estar atento a estes fatos de maneira tal que os menus da
interface grfica tenham uma boa navegabilidade e que os grfi-
cos no consumam muitos recursos do aparelho, o que prejudica
a performance da aplicao. importante que as opes sejam
acessadas por comandos intuitivos e de fcil acesso em interfaces
similares quelas das aplicaes nativas. Tudo isso para ajudar o
usurio em seu processo de aprendizagem, mesmo porque nem
todos tm intimidade com os recursos disponveis em um apare-
lho celular.
A quantidade de telas e a dificuldade de navegao entre elas
so diretamente proporcionais complexidade da aplicao.
Deve-se sempre analisar cuidadosamente o impacto que a inclu-
so de uma nova funcionalidade ir gerar na interface grfica.
Ainda mais em um dispositivo to limitado quanto um celular,
onde o usurio tem a possibilidade de usar apenas uma mo para
manusear o aparelho.
pensando um pouco nestes aspectos que iremos discutir neste
artigo algumas caractersticas da construo de interfaces grfi-
cas para aparelhos celulares, e comentar as ferramentas bsicas
fornecidas pela API MIDP 2.0 que foram usadas no desenvolvi-
mento da aplicao de Jogo da Velha publicado na
quarta edio da Web Mobile.
Viso geral da API MIDP 2.0
A segunda verso do Mobile Information
Device Profile est descrita na JSR-118, que
a especificao Java que define um conjun-
to de APIs associadas necessrias para a cria-
o de um ambiente de desenvolvimento de apli-
caes destinadas a um determinado conjunto
de dispositivos. baseada na primeira verso
e fornece 100% de compatibilidade de forma
que uma aplicao escrita para o ambientes
MIDP 1.0 possam executar em ambientes MIDP
2.0.
A API MIDP 2.0 divide as classes de interface
com o usurio em dois pacotes: javax.microedition.
lcdui, que contm as principais classes para desenvolvimento
de interfaces para aplicativos, e javax.microedition.lcdui.game,
que contm classes especficas para o desenvolvimento de jogos.
Uma introduo
MIDP UI API
wm05.indb 25 3/10/2005 15:48:12
2 5 Edio
Vamos comear pela principal classe da API, a classe Display.
A 1 apresenta uma hierarquia das principais classes de
interface com o usurio, comeando com a classe Display.
A classe Display
Um objeto da classe Display o gerenciador da tela, pois
controla tudo aquilo que mostrado no dispositivo. Todo MIDlet
pode obter uma referncia para um objeto do tipo Display por
meio de uma chamada ao mtodo esttico getDisplay() de-
clarado dentro desta classe. Esse objeto oferece mtodos para
se obter informaes sobre a tela atual (quantidade de cores,
por exemplo) e para solicitar que um determinado objeto seja
mostrado na tela.
A classe Displayable
Seguindo a hierarquia descrita na 1, a classe seguinte
Displayable.
Para que um componente possa ser mostrado na tela ele deve
estar contido dentro de um objeto do tipo Displayable. Em qual-
quer momento, a aplicao poder mostrar apenas um objeto
Displayable na tela do dispositivo usando o mtodo setCurrent()
da classe Display e com este objeto que o usurio ir interagir.
O MIDP inclui duas subclasses de Displayable: Screen e Canvas
(ver 1).
Como a classe Displayable abstrata, no possvel criar
um objeto do tipo Displayable diretamente. A soluo para
isso estender a classe Canvas ou a classe Screen e, dessa
forma, ter acesso aos mtodos de Displayable:
publicabstractclassDisplayable
publicabstractclassScreenextendsDisplayable
publicabstractclassCanvasextendsDisplayable
Basicamente, isto pode ser feito de trs formas diferentes:
Estender a classe Canvas diretamente, lembrando que
a aplicao deve prover uma implementao vlida para o
mtodo paint(), pois este declarado como abstrato em
Canvas( 1).
Usar subclasses de Screen: a API MIDP 2.0 j tem
componentes prontos que so subclasses de Screen. So
eles: List, Alert, TextBox e Form;
Estender uma das classes anteriores (List, Alert,
TextBox ou Form).
Componentes de alto nvel
As classes que compem a API de alto nvel so
as mais adequadas quando o objetivo desen-
volver aplicativos que funcio-
nem em um maior
nmero possvel
de dispositivos.
Isso porque quem define a aparncia dos componentes no o
aplicativo, mas sim a implementao do MIDP no prprio disposi-
tivo. Tambm a implementao no dispositivo que se encarrega
de gerenciar internamente os eventos capturados pelos compo-
nentes da tela.
A classe Screen
Screen a classe bsica da qual so derivadas todas as telas
da API de alto nvel. Os objetos das subclasses de Screen so os
componentes de alto nvel da interface com o usurio. A partir
de agora, iremos descrever cada subclasse de Screen, conforme
descrito na 1.
Classe TextBox
Um exemplo de subclasse de Screen a classe TextBox, uma
tela para mostrar e editar texto. Por ocupar a tela inteira do dis-
positivo, este componente pode conter uma grande quantidade
de texto espalhado em vrias linhas. O cdigo descrito na 2
exemplo muito simples de como TextBox pode ser usado e a
2 mostra o resultado no J2ME Wireless Toolkit, um ambiente
de emulao fornecido pela Sun para o desenvolvimento de apli-
caes MIDP.
Classe Form
A subclasse de Screen que normalmente a mais utilizada
Form, pois permite construir interfaces com vrios componentes
os Items. Convm ressaltar que Item no subclasse de Form,
mas foi ilustrado dessa maneira na 1, pois ela uma super-
classe de componentes que podem ser adicionados a um Form. A
seguir est uma lista descrevendo os componentes que podem ser
adicionados a um Form:
ChoiceGroup: prov um conjunto de opes que podem
ser ou no mutuamente exclusivas. Pode apresentar escolhas
1. Hierarquia de classes.
wm05.indb 26 3/10/2005 15:48:16
WebMobile 2
Java
explcitas por meio de botes de seleo ou mltiplas escolhas
atravs de caixas de seleo.
TextField: um campo com uma nica linha para entrada
de texto, muito semelhante ao TextBox.
DateField: uma verso de TextField especfica para mani-
pular o objeto java.util.Date utilizando as teclas do dispositivo
mvel. De acordo com a implementao, pode apresentar uma
aparncia e funcionalidade que simplifique o processo de es-
colha de datas.
Gauge: a famosa barra de progresso, to popular nos com-
putadores desktop. Pode ser interativa, permitindo a seleo de
um valor dentro de um conjunto de valores, ou no-interativa,
mostrando o progresso de uma determina operao.
ImageItem: permite especificar a forma com que uma ima-
gem ser exibida em um objeto Form.
StringItem: mostra um rtulo esttico e uma mensagem
de texto na interface grfica. Como o usurio no pode editar
nem o rtulo e nem o texto, um objeto StringItem no pode
reconhecer eventos.
Na 3 temos o exemplo de um Form com dois itens: um
ChoiceGroup e um DateField. direita est a maneira com que a
implementao do MIDP ajuda o usurio a escolher uma data. O
cdigo referente tela apresentada na 3 est descrito na 3.
Classe Alert
Continuando a descrever as classes que compem a 1, a
seguinte a classe Alert. Esta uma subclasse de Screen que se
comporta de forma parecida com uma caixa de dilogo, embora
tenha funcionalidades bem reduzidas. Este objeto pode ocupar
uma parte ou toda a tela com uma mensagem de texto e uma
imagem, e seu uso mais comum para mostrar uma mensagem
de aviso ou erro.
Um Alert pode permanecer na tela at que o usurio pressione
uma tecla ou apenas por um determinado intervalo de tempo at
ser fechado automaticamente. Este objeto tem um atributo do
tipo AlertType que usado pelo aparelho para mudar a aparncia
do componente e ajudar o usurio a fazer distino entre mensa-
gens de erro, informao, advertncia, confirmao e alarme.
Classe List
Agora s nos resta falar de List, o ltimo dos componentes
grficos de alto nvel. Assim como o ChoiceGroup, um objeto List
1. Estendendo a classe Canvas.
publicclassJogoDaVelhaextendsCanvas{
//cdigo
publicvoidpaint(Graphicsg){
//maiscdigoaqui
}
}
2. Instanciao de um objeto TextBox.
TextBoxtb=newTextBox(Ttulo,texto,200,
TextField.ANY);
Display.getDisplay(this).setCurrent(tb);
2. Exemplo de um TextBox.
3. Exemplo de ChoiceGroup e DateField.
3. Criao de um Form com os
objetos ChoiceGroup e DateField.
FormmainForm=newForm(Ttulo);
ChoiceGroupcg=
newChoiceGroup(Escolhaumaopo:,Choice.EXCLUSIVE);
cg.append(Opo1,null);
cg.append(Opo2,null);
cg.append(Opo3,null);
mainForm.append(cg);
DateFielddf=newDateField(Data:,DateField.DATE);
df.setDate(newDate());
mainForm.append(df);
Display.getDisplay(this).setCurrent(mainForm);
wm05.indb 27 3/10/2005 15:48:19
2 5 Edio
implementa a interface Choice e contm uma srie de escolhas.
Em outras palavras, List a verso de ChoiceGroup que ocupa
toda a tela do dispositivo.
Alm de suportar seleo exclusiva e selees mltiplas, List
tem um terceiro modo de operao: a seleo implcita. Neste
modo, um objeto List se comporta como uma lista padro, restrin-
gindo a seleo a apenas um elemento por vez. Este modo de ope-
rao muito utilizado na criao de menus, pois em uma lista
implcita o elemento em destaque implicitamente considerado
como o elemento selecionado. A apresenta um exemplo de
uma lista implcita construda com um cdigo ( ) muito seme-
lhante ao cdigo mostrado no exemplo do ChoiceGroup.
Com isso, descrevemos as classes que compem os componen-
tes de alto nvel de uma interface (classe Screen).
Componentes de baixo nvel
Usar a API de baixo nvel para construir interfaces grficas exi-
ge um pouco mais de criatividade e esforo. Enquanto que usando
componentes de alto nvel era possvel criar interfaces que funcio-
nassem perfeitamente em uma grande quantidade de dispositivos,
agora, com os componentes de baixo nvel isso no acontece mais
devido s diferentes caractersticas dos aparelhos, principalmente
a resoluo da tela e a quantidade de cores suportadas.
Esta API utilizada principalmente em jogos, pois em uma
interface de baixo nvel possvel ter controle total de cada pixel
da tela e possvel responder rapidamente s aes do usurio,
enquanto que a API de alto nvel no permite que o desenvolve-
dor desenhe diretamente na tela.
As classes principais que compem a API de baixo nvel so:
Canvas: a tela na qual as imagens podem ser pintadas.
4. Criao de um objeto List.
Listlist=newList(ListaImplcita,List.IMPLICIT);
list.append(Opo1,null);
list.append(Opo2,null);
list.append(Opo3,null);
Display.getDisplay(this).setCurrent(list);
Por ser uma subclasse direta de Displayable, ela fornece mtodos
para tratamentos de eventos de baixo nvel, mas no pode con-
ter outros componentes.
Graphics: a caneta que deve ser usada para escrever
na tela. Essa classe contm mtodos para especificar cores e
desenhar retngulos, crculos, linhas e texto.
Classe Canvas
A classe Canvas a base para as aplicaes que precisam mani-
pular eventos de baixo nvel e gerenciar elementos grficos per-
sonalizados. muito utilizada em jogos e em interfaces grficas
mais elaboradas. Vale destacar aqui tambm que possvel para
uma aplicao mesclar telas de baixo nvel com telas que conte-
nham componentes de alto nvel.
Como esta classe fornece um grande controle sobre a tela e so-
bre o teclado, necessrio avaliar muito bem os prs e os contras
da criao de uma aplicao dependente do dispositivo. Especial-
mente nos jogos, a utilizao de recursos especficos de um deter-
minado conjunto de dispositivos pode, por exemplo, melhorar a
jogabilidade, mas certamente vai restringir o pblico-alvo.
J foi dito anteriormente que Canvas uma classe abstrata e
que necessrio criar uma subclasse e implementar o mtodo
paint(). S ento que o novo objeto poder ser configurado como
o componente Displayable atual e assim, poderemos desenhar o
que quisermos na tela. O mtodo paint() serve para pintar os
pixels da tela e chamado quando:
o objeto Canvas se torna visvel aps uma chamada ao m-
todo setCurrent() da classe Display;
uma parte ou todo o Canvas reaparece aps um alerta ou
um menu de comandos;
o cdigo da aplicao solicita a pintura da tela.
Classe Graphics
Um objeto do tipo Graphics passado ao mtodo paint() e
este objeto que deve ser usado para desenhar na tela. De acordo
com a especificao do MIDP, no possvel guardar uma refern-
cia do objeto Graphics para uso posterior em algum outro lugar.
Um cdigo bem simples que limpa a tela e depois desenha um
retngulo e escreve um texto est descrito na .
Vamos explicao do cdigo. Na linha 1 foi utilizado o mtodo
setColor() que recebeu como parmetro um nmero inteiro no
formato hexadecimal especificando a cor branca atravs do siste-
ma RGB (Red Green Blue). Em seguida, o mtodo fillRect()
(linha 2) desenhou na tela um retngulo preenchido com a cor
branca. Para usar corretamente este mtodo, devemos entender
como funciona o sistema de coordenadas da tela. A origem do
sistema est indicada pelo ponto (0, 0) (ver ), o ponto
mais acima e mais esquerda do Canvas. Ao longo do eixo x, os
valores vo do zero (no lado esquerdo) at o valor mximo no lado
direito. O mesmo acontece no eixo y, onde ponto inicial o ponto
mais ao alto e o valor mximo o ponto mais embaixo na tela.
. Exemplo de lista implcita.
wm05.indb 28 3/10/2005 15:48:21
WebMobile 2
Java
1. Boas prticas
conveniente utilizar poucas telas e fazer a navegao entre elas
o mais linear possvel. Certamente isso ir facilitar o trabalho
do programador e o usurio se sentir menos confuso durante
a navegao. Ainda em relao navegao, os comandos e os
menus, alm de intuitivos, devem ser dispostos de forma coerente.
Exemplo: manter sempre a mesma soft key para acionar o comando
de cancelar/voltar.
Neste exemplo, a implementao da interface grfica em alto
nvel se d na classe principal do aplicativo, o MIDlet, que foi
declarada da seguinte maneira:
publicclassInovaVelhaMIDletextendsMIDletimplements
CommandListener,DiscoveryListener
Ou seja, a classe herda de MIDlet ( a classe principal para os
aplicativos em J2ME), implementa as interfaces CommandListener
e DiscoveryListener, esta ltima no diz respeito implementao
da interface grfica. Implementamos a interface CommandListener
para tratar os eventos de alto nvel, como o acionamento de um
comando na tela, portanto devemos sobrescrever o seu nico m-
todo abstrato:
publicvoidcommandAction(Commandc,Displayabled)
Este mtodo chamado quando ocorre um evento de comando
na tela. O parmetro Command c um objeto identificando o
comando acionado em uma tela e o parmetro Displayable d re-
presenta a tela na qual o comando foi inserido e acionado.
Como estamos manipulando poucas telas, j deixaremos cria-
dos todos os objetos necessrios para a montagem destas. Com o
auxlio do esquema apresentado na , identificamos todos os
componentes que devero ser criados (ver ):
Por enquanto os componentes foram apenas declarados, ainda
no foram instanciados. Para isso criamos um mtodo responsvel
por inicializar todos estes objetos. Como esta operao deve ser
realizada durante o carregamento da aplicao, deixamos a cha-
mada para este mtodo no construtor do MIDlet, como mostrado
na .
Inicialmente, definimos os cinco commands necessrios (linhas
5 a 9, ). importante notar que estes comandos no
possuem a informao de qual a ao realizada durante sua
ativao, isto ser visto mais a frente quando estivermos
detalhando o mtodo commandAction( ). Ao instanciar o
Command definimos o Label, o Tipo e a Prioridade:
O Label o texto que aparece no boto. Este texto
deve ser curto e objetivo o suficiente para informar ao
usurio a funo do comando.
O Tipo utilizado pelo celular para saber onde posicio-
nar o comando. Por exemplo, se um dispositivo tem uma
. Primeiro exemplo de Canvas.
5. Exemplo de cdigo utilizando a classe Graphics.
1.g.setColor(0x00FFFFFF);
2.g.fillRect(0,0,getWidth(),getHeight());
3.g.setColor(0x00000000);
4.g.drawRect(10,10,40,15);
5.g.drawString(texto,20,10,Graphics.TOP|Graphics.LEFT);
Interfaces grficas na prtica
Utilizando as diversas classes disponveis no pacote LCDUI,
pode-se facilmente desenvolver uma interface grfica em alto n-
vel simples e rpida para o seu aplicativo. Entretanto, para deixar
a interface grfica mais customizada e com a cara do seu apli-
cativo, pode-se utilizar as classes de desenvolvimento em baixo
nvel, onde se tem um maior controle dos objetos apresentados na
tela, tornando a tarefa um pouco mais trabalhosa, mas que pode
apresentar um resultado recompensador.
Para ilustrar e ajudar no entendimento das ferramentas e dos
conceitos citados, veremos em detalhes a construo da interface
grfica com o usurio do jogo Inova Velha desenvolvido por F-
bio Mesquita Pvoa, integrante do grupo Inova Mobile que foi
publicado na quarta edio da Web Mobile. Em seguida, criaremos
uma nova verso do Inova Velha, onde modificaremos a interface
grfica para deix-la com um visual mais amigvel.
Construindo interfaces em alto nvel
Embora os aplicativos para celulares sejam pequenos e apre-
sentem, em sua maioria, um nmero pequeno de telas (cenrios)
distintas, uma boa prtica estruturar o fluxo de navegao das
telas para facilitar o desenvolvimento e compreenso do aplica-
tivo como um todo. A apresenta uma espcie de storyboard
do jogo em questo (ler 1).
wm05.indb 29 3/10/2005 15:48:23
30 5 Edio
padronizao de posicionamen-
to dos comandos de retorno em
um determinado soft-button (boto de
acionamento dos comandos, geralmente posicio-
nado abaixo da tela do celular), a implementao
pode utilizar a informao de Tipo de um comando
do tipo BACK para posicionar este comando naquele
soft-button.
J a Prioridade define a importncia de um comando em
relao aos outros comandos na mesma tela. A Prioridade
representada por um nmero inteiro, quanto menor esse valor
maior a sua importncia. Este parmetro utilizado para de-
terminar a disposio dos comandos na tela, e caso os valores
das prioridades sejam iguais, a implementao se encarrega de
escolher a ordem na qual os comandos sero apresentados.
Em seguida instanciamos os Gauges (linhas 10 a 12) configu-
rando-os de maneira no interativa, com valor mximo indefi-
nido e com valor inicial definido como CONTINUOUS_RUNNING.
Fizemos esse tipo de configurao pelo fato de que neste caso
no conseguimos medir o progresso realizado no tipo de espera
em que o Gauge ser apresentado, ou seja, o tempo de espera
indefinido.
Depois disso criamos os objetos Displayables (linhas 13 a 27
e 35 a 42):
TextBox: so as caixas de texto, que neste caso foi utilizada
apenas para apresentar um texto informativo, por isso foi con-
figurada como no editvel.
Form: os formulrios so bastante utilizados pelo
fato de comportarem vrios itens na mesma tela. Mas
neste caso utilizamos apenas para mostrar os Gauges
criados anteriormente.
List: definimos as listas implcitas e associamos
cones s opes da lista.
Alert: Criamos um alerta informativo e o configu-
ramos para que seja apresentado durante um tempo de
2000 milisegundos.
Para cada um dos Displayables criados, adicionamos
os comandos e determinamos o CommandListener. Este
ltimo responsvel por ficar escutando o aciona-
mento dos comandos na tela.
O Alert criado (linha 40) ser utilizado em diversas
situaes, mostrando diferentes mensagens. Por isso,
criamos um mtodo para configur-lo de acordo com as
necessidades ( ).
importante observar que em nextDisplayable
guardada a tela que ser apresentada aps o alerta. Sua
utilizao ser vista na .
Com todos os componentes instanciados e configu-
rados precisamos agora fazer o tratamento das aes
que devem ser tomadas de acordo com o acionamento dos co-
mandos. Como j havamos comentado, este tratamento feito
no mtodo commandAction( ), como mostrado na (parte do
cdigo foi omitido por no se tratar da implementao referente
interface com o usurio). Este mtodo ser chamado sempre
que um comando for acionado, isso acontece porque definimos
um Listener para cada uma das telas atravs do mtodo setCom-
mandListener( ).
Como pode ser visto na , o tratamento das aes tomadas
feito com base no comando acionado e na tela corrente. Como
so passadas as referncias para esses dois componentes, bas-
ta fazer comparaes com suas variveis de referncia (como: if
(d == alert) ) para saber qual o comando acionado e a sua tela
correspondente, permitindo decidir qual ao deve ser realizada.
O fato da tela corrente ser passada para o mtodo
commandAction( ) nos permite que um mesmo comando possa
ser utilizado em diferentes telas, como o caso do comando
Voltar. Entretanto, convm ressaltar que um mesmo Item (como
um Gauge ou TextField) no pode ser adicionado a mais de um
Form, o que lanaria a exceo java.lang.IllegalStateException
em tempo de execuo.
Construindo interfaces em baixo nvel
Agora iremos modificar o jogo Inova Velha para deixar a interface
com o usurio com um visual mais atraente, o que fundamental
em um jogo. Como visto anteriormente, a implementao em alto
nvel no d muita liberdade no desenvolvimento da interface do
seu aplicativo pelo fato de se trabalhar com peas semi-prontas
. Fluxo de Navegao das Telas.
wm05.indb 30 3/10/2005 15:48:25
WebMobile 31
Java
onde o desenvolvedor pode apenas ajustar alguns parmetros de
configurao. Alm disso, a apresentao desses componentes de
alto nvel dependente do celular, ou seja, um TextBox pode ter
a aparncia bem diferente em celulares de marcas ou modelos
diferentes. J na implementao em baixo nvel, o programador
tem mais liberdade para desenhar na tela, podendo desenvolver
seus prprios componentes com a possibilidade de se trabalhar
com diferentes cores, formas, imagens e at mesmo animaes.
Entretanto, toda esta liberdade tem seu preo; o desenvolvimento
em baixo nvel mais trabalhoso e, dependendo da implementa-
o, o aplicativo poder funcionar corretamente em um nmero
bem mais limitado de aparelhos devido a grande variedade de
dimenses de telas, por exemplo.
Com o intuito de focar apenas na implementao da interface
grfica, criamos uma nova aplicao para trabalhar com o desen-
volvimento da interface grfica em baixo nvel sem se preocupar
com a lgica do jogo em si, porm, o cdigo do jogo integrado
com a nova interface grfica encontra-se disponvel no portal da
Web Mobile.
Iniciamos com a criao da classe principal do nosso aplicativo,
o MIDlet, visto na 10. Esta classe apenas instancia o Game-
MenuCanvas (Linha 8), que responsvel pela interface em baixo
nvel. Coloca o gameMenuCanvas como tela corrente (Linha 17) e
chama o mtodo responsvel por mostrar a SplashScreen.
Em seguida, criamos a classe GameMenuCanvas que ir fazer
todo o tratamento das telas do menu, baseando-se novamente no
fluxo de navegao apresentado na .
Seguindo a implementao original do jogo Inova Velha,
6. Componentes criados para a interface com o usurio.
privateCommandnewSearchCommand; //ComandodeNovaBusca.UtilizadonateladeDispositivos
//encontrados.
privateCommandselectCommand; //ComandoSelecionar.UtilizadonateladeDispositivos
//encontrados.
privateCommandexitCommand; //ComandoSair.Utilizadonatelainicial.
privateCommandbackCommand; //ComandoVoltar.UtilizadonastelasSobreeDispositivos
//encontrados.
privateCommandcancelCommand; //ComandoCancelar.Aparecenastelasdeespera.importante
//permitir,semprequepossvel,queousuriopossacancelar
//umaoperaoemandamento.

privateListserverClientList; //Listacomasopesdatelainicial:Servidor,Clientee
//Sobre.
privateListdeviceList; //Listacomosdispositivosencontrados.Aparecenatelade
//DispositivosEncontrados.
privateImageicon; //coneparaositensdalistaserverClientList.

privateGaugewaitGauge; //Barradeprogressoutilizadanateladeesperadoservidor.
privateGaugesearchGauge; //Barradeprogressoutilizadanateladebuscapor
//dispositivos.
privateGaugeserviceGauge; //Barradeprogressoutilizadanateladebuscaporservioem
//umdispositivo.

privateFormwaitForm; //FormulrioparamostrarabarradeprogressowaitGauge.
privateFormsearchForm; //FormulrioparamostrarabarradeprogressosearchGauge.
privateFormserviceForm; //FormulrioparamostrarabarradeprogressoserviceGauge.
privateAlertalert; //Alertautilizadoemdiversastelasparaavisarousurio
//casoocorraalgumerro.

privateTextBoxtextBox; //CaixadetextoutilizadanatelaSobre.

privateDisplaydisplay; //Varivelderefernciadateladocelular.
privateDisplayablenextDisplayable; //Varivelauxiliarparaguardaratelaquesermostrada
//apsaexibiodeumalerta.
wm05.indb 31 3/10/2005 15:48:27
32 5 Edio
7. Inicializando os objetos.
1.publicInovaVelhaMIDlet(){
...
2.initComponents();
...
3.}
4.privatevoidinitComponents(){
5.exitCommand=newCommand(Sair,Command.CANCEL,1);
6.backCommand=newCommand(Voltar,Command.BACK,1);
7.cancelCommand=newCommand(Cancelar,Command.CANCEL,1);
8.selectCommand=newCommand(Selecionar,Command.
SCREEN,1);
9.newSearchCommand=newCommand(Novabusca,Command.
SCREEN,1);
10.waitGauge=newGauge(Aguardandoconexo...,
false,Gauge.INDEFINITE,
Gauge.CONTINUOUS_RUNNING);
11.searchGauge=newGauge(Procurandodispositivos...,
false,Gauge.INDEFINITE,
Gauge.CONTINUOUS_RUNNING);
12.serviceGauge=newGauge(Procurandoservio...,
false,Gauge.INDEFINITE,
Gauge.CONTINUOUS_RUNNING);
13.textBox=newTextBox(Sobre,DesenvolvidoporFbio
MesquitaPvoa\n+
Email:fabio.povoa@gmail.com,100,TextField.
UNEDITABLE);
14.textBox.addCommand(backCommand);
15.textBox.setCommandListener(this);

16.searchForm=newForm(Aguarde...);
17.searchForm.append(searchGauge);
18.searchForm.addCommand(cancelCommand);
19.searchForm.setCommandListener(this);
20.waitForm=newForm(Aguarde...);
21.waitForm.append(waitGauge);
22.waitForm.addCommand(cancelCommand);
23.waitForm.setCommandListener(this);

24.serviceForm=newForm(Aguarde...);
25.serviceForm.append(serviceGauge);
26.serviceForm.addCommand(cancelCommand);
27.serviceForm.setCommandListener(this);

28.try{
29.icon=Image.createImage(/img/icone3.png);
30.}catch(IOExceptionex){}

31.serverClientList=newList(Selecioneumaopo,
List.IMPLICIT,newString[]{Servidor,
Cliente,Sobre},newImage[]{icon,
icon,icon});
32.serverClientList.addCommand(selectCommand);
33.serverClientList.addCommand(exitCommand);
34.serverClientList.setCommandListener(this);

35.deviceList=newList(Dispositivosencontrados,
List.IMPLICIT);
36.deviceList.addCommand(selectCommand);
37.deviceList.addCommand(newSearchCommand);
38.deviceList.addCommand(backCommand);
39.deviceList.setCommandListener(this);

40.alert=newAlert(null,Nenhumdispositivofoi
encontrado,null,AlertType.INFO);
41.alert.setTimeout(2000);
42.alert.setCommandListener(this);
43.}
8. Mtodo para tratar as telas de alerta.
privatevoiddisplayAlert(Stringmessage,AlertTypetype,
Displayabledisplayable){
nextDisplayable=displayable;
alert.setString(message);
alert.setType(type);
display.setCurrent(alert);
}
9. Tratamento dos eventos e acionamento de comandos.
publicvoidcommandAction(Commandc,Displayabled){
if(d==serverClientList){
//Tratamentoparaaestomadasnatelainicial
//(servidor/cliente).

if(c==selectCommand||c==
List.SELECT_COMMAND){
switch(serverClientList.getSelectedIndex()){
case0:
//Foiselecionadaaopo
//Servidor.
//Inicia-seoservidoreodeixana
//teladeespera.

...
display.setCurrent(waitForm);
break;

case1:
//FoiselecionadaaopoCliente
//Faz-seabuscapelosdispositivos
//eentomostraalistacom
//osdispositivosencontrados.
...
display.setCurrent(deviceList);
...
break;

case2:
wm05.indb 32 3/10/2005 15:48:28
WebMobile 33
Java
//FoiselecionadaaopoSobre.
display.setCurrent(textBox);
break;
}

}elseif(c==exitCommand){
destroyApp(true);
}

}elseif(d==deviceList){
//Tratamentoparaaestomadasnatelacoma
//listadedispositivosencontrados.

if(c==selectCommand||c==List.SELECT_
COMMAND){
//Ousurioselecionouumdispositivo.
//Faz-seabuscaporserviosnodispositivo
//selecionado.
intindex=deviceList.getSelectedIndex();
...
display.setCurrent(serviceForm);

}elseif(c==newSearchCommand){
//Ousuriosolicitouumanovabusca.
//Provavelmenteporquenofoiencontradoo
//dispositivodesejado.
...
display.setCurrent(searchForm);

}elseif(c==backCommand){
//Ousurioacionouobotoderetorno.
//Voltandotelainicial.
display.setCurrent(serverClientList);
}

}elseif(d==textBox){
//TratamentoparaaestomadasnatelaSobre.
//ComoonicocomandodatelaVoltar,no
//foinecessrioverificarocomando
//acionado.Ouseja,qualqueraotomada
//nestatela,sabe-sequepararetornar
//paraatelainicial.

display.setCurrent(serverClientList);

}elseif(d==waitForm){
//Tratamentoparaaestomadasnatelade
//esperadoServidor.
//ComoonicocomandodatelaCancelar,
//qualqueraotomadanestatela,
//sabe-sequepararetornarparaatela
//inicial.

display.setCurrent(serverClientList);
...

}elseif(d==searchForm||d==serviceForm){
//Tratamentoparacancelamentodebuscade
//dispositivosouservios.
//Ocancelamentofazcomquemtodos
//responsveispelaconexobluetooth
//(inquiryCompletedeserviceSearchCompleted)
//mostremoalertaapropriadoe
//retorneparaatelacorreta.

cancelSearch();

}elseif(d==alert){
//Tratamentoparaoretornodequalquertelade
//alerta.
//OmtododisplayAlert(...)guardaatelaaser
//mostradadepoisdoalertaemnextDisplayable.
//Portanto,aoretornadeumalerta
//(configuradoparasermostradoporum
//perodode2000milisegundos),aprximatela
//entomostrada.

display.setCurrent(nextDisplayable);

}
}
importante notar que a classe GameMenuCanvas no her-
da diretamente da classe Canvas descrita anteriormente, mas
sim da classe proprietria com.nokia.mid.ui.FullCanvas que
por sua vez herda de javax.microedition.lcdui.Canvas, (ler
2). Portanto, a declarao da nossa classe ficou da seguinte
maneira:
2. Desenhando em toda a tela.
Nas especificaes de um dispositivo encontram-se
as informaes sobre o tamanho da tela, que pode
ter, por exemplo, 128 por 128 pixels. Entretanto, a
rea til de desenho no Canvas
menor, conforme pode ser
wm05.indb 33 3/10/2005 15:48:28
3 5 Edio
visto na . impossvel desenhar em toda a tela do
dispositivo utilizando apenas a API do MIDP 1.0. Para resolver
este problema, alguns fabricantes buscaram suas prprias
solues. A Nokia implementa em seus aparelhos a classe
FullCanvas, enquanto que na maioria dos aparelhos da Motorola
o desenvolvedor pode simplesmente ignorar o retorno do mtodo
getHeight para de fato desenhar em toda a tela. Mas deve-se ter
cuidado com o uso de classes proprietrias, pois isto ir reduzir a
quantidade de aparelhos nos quais a aplicao ir funcionar.
Na API MIDP 2.0 encontramos uma soluo mais genrica para este
problema. Utilizando o novo mtodo setFullScreenMode da classe
Canvas pode-se ajustar a exibio para o modo normal ou tela cheia.
Infelizmente este mtodo no funciona adequadamente em todos
os dispositivos e o desenvolvedor ter um trabalho extra na fase de
testes e ajustes da aplicao.
publicclassGameMenuCanvasextendsFullCanvasimplementsRunnable
Implementamos a interface Runnable para podermos fazer uma
pequena animao na tela de espera. Como usurio, sabemos que
uma boa prtica a utilizao de pequenas animaes nas telas
de espera para que o usurio saiba que o aplicativo no est
travado.
A seguir apresentaremos alguns mtodos importantes imple-
mentados na classe GameMenuCanvas. O mtodo abstrato paint()
o principal deles e sua implementao pode ser vista na 11.
Os comentrios no cdigo auxiliam no seu entendimento.
Para pintar qualquer coisa na tela, este mtodo paint() deve
ser chamado atravs do mtodo repaint(), como ser visto mais
adiante. Como este mtodo pinta todas as telas da nossa aplica-
o, um controle de telas deve ser feito, por isso utilizamos a va-
rivel currentScreen para saber qual a tela corrente. Os resultados
dos procedimentos de pintura realizados para cada uma das telas
podem ser vistos nas e .
J o tratamento dos eventos de clique dos botes do celular
implementado no mtodo keyPressed(), mostrado na 12. Este
mtodo semelhante ao mtodo commandAction() utilizado na
implementao em alto nvel, entretanto, o nico parmetro re-
cebido o cdigo da tecla pressionada. Sendo assim, utilizamos a
varivel auxiliar currentScreen, citada anteriormente, juntamente
com o cdigo da tecla pressionada (keyCode) para realizar a ao
desejada. Neste caso, ao final de cada ao devemos repintar a
tela. Para isso fizemos chamadas aos mtodos repaint() e service-
Repaints() (Linhas 82 e 83), este ltimo mtodo chamado por
segurana apenas, pois fora a pintura imediata de qualquer requi-
sio ainda pendente, e caso no haja nenhum pendncia o mtodo
retorna imediatamente sem realizar nenhuma ao.
Para fazer a animao mostrada nas telas de espera precisamos
utilizar uma Thread diferente para que o celular no fique travado
na animao (ler 3). Por isso a nossa classe GameMenuCanvas
implementa a interface Runnable() e, por isso implementamos o
mtodo run() mostrado na 13. Este mtodo faz uma parada
de 200 milisegundos (Linhas 6 a 9), determina qual frame da
animao deve ser mostrado (Linha 10), e ento chama o mtodo
repaint() para pintar a regio da animao (Linha 12) e em segui-
da o mtodo serviceRepaints() (Linha 13). importante ressaltar
que o procedimento realizado nas linhas 14 a 24 serve apenas
para simular o tempo de espera na busca por dispositivos e no
utilizado no cdigo integrado com o jogo Inova Velha.
3. Utilize barras de progresso.
O Gauge, ou barra de progresso, pode ser utilizado para dar feedback
ao usurio sobre algum processamento que est sendo executado
pela aplicao. sempre bom que o usurio seja informado a
respeito do progresso de alguma tarefa, seja a tarefa um clculo
mais demorado ou a resposta de uma conexo.
Os mtodos paint(), keyPressed() e run() so os trs mtodos
mais importantes desta implementao. Alm desses, utilizamos
apenas alguns mtodos auxiliares de controle que podem ser vis-
10. O MIDlet.
1.packagebr.unb.inovamobile.jogodavelha;
2.importjavax.microedition.lcdui.Display;
3.importjavax.microedition.midlet.MIDlet;
4.publicclassInovaVelhaMenuMIDletextendsMIDlet{

//Canvasresponsvelpelomenu
5. GameMenuCanvasgameMenuCanvas;

//Displaydocelular
6. Displaydisplay;
7. publicInovaVelhaMenuMIDlet(){
8. gameMenuCanvas=new
GameMenuCanvas(this);
9. display=Display.getDisplay(this);
10. }

11. protectedvoiddestroyApp(booleanunc){
12. notifyDestroyed();
13. }

14. protectedvoidpauseApp(){
15. }

16. protectedvoidstartApp(){
//ColocaoCanvascomotelacorrente
einiciamostrandoaSplashScreen
17. display.setCurrent(gameMenuCanvas);
18. gameMenuCanvas.displaySplashScreen();
19. }
20.}
wm05.indb 34 3/10/2005 15:48:30
WebMobile 3
Java
11. A implementao do mtodo paint().
1.protectedvoidpaint(Graphicsg){
//Determinaqualatelaatual.
2.switch(currentScreen){

//Pintaatelaprincipal.
3.caseMAIN_MENU:

4.g.setColor(0x000000);//Corpreta.

5.g.drawImage(backgroundImg,0,0,Graphics.TOP|
Graphics.LEFT);
6.g.drawImage(boardImg,0,0,Graphics.TOP|Graphics.
LEFT);
7.g.drawImage(leftArrowImg,9,10,Graphics.TOP|
Graphics.LEFT);
8.g.drawImage(rightArrowImg,this.getWidth()-9,10,
Graphics.TOP|
9.Graphics.RIGHT);

10.g.setFont(fontOption);
11.g.drawString(getCurrentOption(),this.getWidth()/2,10,
Graphics.TOP|
12.Graphics.HCENTER);

13.g.setFont(fontCommand);
14.g.drawString(Selecionar,3,this.getHeight()-1,
Graphics.BOTTOM|
15.Graphics.LEFT);
16.g.drawString(Sair,this.getWidth()-3,this.
getHeight()-1,Graphics.BOTTOM|
17.Graphics.RIGHT);
18.break;

//PintaatelaSobre
19.caseABOUT_MENU:
20.g.drawImage(backgroundImg,0,0,Graphics.TOP|
Graphics.LEFT);

21.g.setFont(fontOption);
22.g.drawString(Sobre,this.getWidth()/2,10,Graphics.
TOP|Graphics.HCENTER);

23.g.setFont(fontCommand);
24.g.drawString(Versooriginaldesenvolvida,this.
getWidth()/2,35,
25.Graphics.TOP|Graphics.HCENTER);
26.g.drawString(porFbioMesquitaPvoa,this.
getWidth()/2,35+
27.1*(fontCommand.getHeight()+2),Graphics.TOP|
Graphics.HCENTER);
28.g.setFont(fontTextBold);
29.g.drawString((fabio.povoa@gmail.com),this.
getWidth()/2,35+
30.2*(fontCommand.getHeight()+2),Graphics.TOP|
Graphics.HCENTER);

31.g.setFont(fontCommand);
32.g.drawString(InterfaceGrficadesenvolvida,this.
getWidth()/2,90,
33.Graphics.TOP|Graphics.HCENTER);
34.g.drawString(porBrunoChavesRochaLima,this.
getWidth()/2,90+
35.1*(fontCommand.getHeight()+2),Graphics.TOP|
Graphics.HCENTER);
36.g.setFont(fontTextBold);
37.g.drawString((brunoc81@gmail.com),this.getWidth()/2,90+
2*(fontCommand.getHeight()+2),Graphics.TOP|
Graphics.HCENTER);
38.g.setFont(fontCommand);
39.g.drawString(eEdgarBarbosadeSouza,this.
getWidth()/2,90+
40.3*(fontCommand.getHeight()+2),Graphics.TOP|
Graphics.HCENTER);
41.g.setFont(fontTextBold);
42.g.drawString((edgar@redes.unb.br),this.getWidth()/2,90+
43.4*(fontCommand.getHeight()+2),Graphics.TOP|
Graphics.HCENTER);

44.g.setFont(fontCommand);
45.g.drawString(Voltar,this.getWidth()-3,this.
getHeight()-1,Graphics.BOTTOM
46.|Graphics.RIGHT);
47.break;

//PintaatelacomalistadeDispositivosEncontrados
49.caseLIST_MENU:
50.g.drawImage(backgroundImg,0,0,Graphics.TOP|
Graphics.LEFT);

51.g.setFont(fontOption);
52.g.drawString(DispositivosEncontrados,this.
getWidth()/2,10,Graphics.TOP|
53.Graphics.HCENTER);

54.g.drawImage(upArrowImg,6,30,Graphics.TOP|Graphics.
LEFT);
55.g.drawImage(downArrowImg,6,this.getHeight()-25,
Graphics.BOTTOM|
56.Graphics.LEFT);

//Procedimentoresponsvelpormostrar5itensdalistaefazer
wm05.indb 35 3/10/2005 15:48:31
3 5 Edio
arolagem
//dessalista.
57.intaux=0;
58.for(inti=firstViewDevice;i<=lastViewDevice;i++){
59.if(currentDevice==i){
60.g.drawImage(selectImg,10,80+aux*(fontList.
getHeight()+4),
61.Graphics.BOTTOM|Graphics.LEFT);
62.g.setFont(fontListSelected);
63.}else{
64.g.setFont(fontList);
65.}
66.g.drawString(dispositivos[i],10+selectImg.
getWidth()+3,80+aux*
67.(fontList.getHeight()+4),Graphics.BOTTOM|
Graphics.LEFT);
68.aux++;
69.}

70.g.setFont(fontCommand);
71.g.drawString(Selecionar,3,this.getHeight()-1,
Graphics.BOTTOM|
72.Graphics.LEFT);
73.g.drawString(Voltar,this.getWidth()-3,this.
getHeight()-1,Graphics.BOTTOM
74.|Graphics.RIGHT);
75.break;

//Pintaastelasdeespera.
76.caseWAIT_SERVICE_MENU:
77.caseWAIT_DEVICE_MENU:
78.caseWAIT_CONNECTION_MENU:
79.g.drawImage(backgroundImg,0,0,Graphics.TOP|
Graphics.LEFT);

80.g.setFont(fontOption);
81.g.drawString(Aguarde...,this.getWidth()/2,10,
Graphics.TOP|
82.Graphics.HCENTER);

83.g.setFont(fontList);
84.g.drawString(gaugeMsg,this.getWidth()/2,getHeight()/2
-2,Graphics.BOTTOM|
85.Graphics.HCENTER);

86.g.setClip(this.getWidth()/2-25,getHeight()/2,50,
36);
87.g.drawImage(gaugeImg,this.getWidth()/2-26-
(gaugeFrame*51),getHeight()/2,
88.Graphics.TOP|Graphics.LEFT);
89.g.setClip(0,0,176,208);

90.g.drawString(Cancelar,this.getWidth()-3,this.
getHeight()-1,
91.Graphics.BOTTOM|Graphics.RIGHT);
92.break;

//PintaaSplashScreencomologotipodaInovaMobile
93.caseSPLASH_INOVA:
94.g.drawImage(splashInovaImg,this.getWidth()/2,this.
getHeight()/2,
95.Graphics.VCENTER|Graphics.HCENTER);
97.break;

//PintaaSplashScreendojogo.
97.caseSPLASH_GAME:
98.g.drawImage(splashGameImg,this.getWidth()/2,this.
getHeight()/2,
99.Graphics.VCENTER|Graphics.HCENTER);

100.g.setFont(fontCommand);
101.g.drawString(Verso1.2,this.getWidth()-3,this.
getHeight()-1,
102.Graphics.BOTTOM|Graphics.RIGHT);
203.break;
104.}
105.}
tos e estudados atravs do cdigo completo disponvel no portal
da Web Mobile.
Concluses
Apresentamos neste artigo uma introduo utilizao das
classes do pacote LCDUI para o de-
senvolvimento de interfaces gr-
ficas em alto e baixo nvel. Acre-
ditamos que cada implementao
tem sua utilidade, uma de fcil
desenvolvimento, maior compati-
bilidade e menos customizvel, e a outra que apresenta uma im-
plementao mais complicada, pode ter menor compatibilidade,
mas que permite criar um visual bastante atraente. Cabe a voc
decidir o que melhor para a sua aplicao.
Sugerimos a leitura da especificao MIDP2.0 JSR118 (http://
jcp.org/aboutJava/communityprocess/final/jsr118/index.html)
para conhecer outros recursos e se aprofundar mais no desenvol-
vimento da interface grfica de suas aplicaes. Ainda em tempo,
deixamos na uma dica muito interessante para utilizao de
paleta de cores.
Esperamos que vocs tenham gostado!
wm05.indb 36 3/10/2005 15:48:32
WebMobile 3
Java
12. A implementao do mtodo keyPressed().
1.publicvoidkeyPressed(intkeyCode){

//Verificaqualatelaqueestsendovisualizada.
2.switch(currentScreen){

//Estnatelaprincipal
3.caseMAIN_MENU:
//Verificaateclapressionada
4.switch(keyCode){
5.caseKEY_LEFT_ARROW:
6.currentOption=(byte)(--currentOption%3);
7.if(currentOption<SERVER_OPTION){
8.currentOption=ABOUT_OPTION;
9.}
10.break;

11.caseKEY_RIGHT_ARROW:
12.currentOption=(byte)(++currentOption%3);
13.break;

14.caseKEY_SOFTKEY2:
15.midlet.destroyApp(true);
16.break;

17.caseKEY_SOFTKEY1:
18.caseKEY_SOFTKEY3:
19.currentScreen=getOptionScreen();
20.if(currentScreen==WAIT_CONNECTION_MENU){
21.gaugeMsg=Aguardandoconexo...;
22.gaugeThread=newThread(this);
23.gaugeThread.start();
24.}elseif(currentScreen==WAIT_DEVICE_MENU){
25.gaugeMsg=Procurandodispositivos...;
26.gaugeThread=newThread(this);
27.gaugeThread.start();
28.}
29.break;
30.}
31.break;

//EstnatelaSobre
32.caseABOUT_MENU:
//Verificaseateclapressionadaacorrespondente
aobotoVoltar.
33.if(keyCode==KEY_SOFTKEY2){
34.currentScreen=MAIN_MENU;
35.}
36.break;

//EstnateladeDispositivosEncontrados
37.caseLIST_MENU:
//Verificaateclapressionadaparafazeranavegao
nalista
38.switch(keyCode){
39.caseKEY_DOWN_ARROW:
40.if((currentDevice+1)<dispositivos.length){
41.currentDevice++;
42.if(currentDevice>lastViewDevice){
43.lastViewDevice++;
44.firstViewDevice++;
45.}
46.}
47.break;

48.caseKEY_UP_ARROW:
49.if((currentDevice-1)>=0){
50.currentDevice--;
51.if(currentDevice<firstViewDevice){
52.firstViewDevice--;
53.lastViewDevice--;
54.}
55.}
56.break;

57.caseKEY_SOFTKEY2:
58.currentScreen=MAIN_MENU;
59.break;

61.caseKEY_SOFTKEY1:
62.caseKEY_SOFTKEY3:
63.currentScreen=WAIT_SERVICE_MENU;
64.gaugeMsg=Procurandoservio...;
65.gaugeThread=newThread(this);
66.gaugeThread.start();
67.break;
68.}
69.break;
//EstnateladeProcuraporServio
70.caseWAIT_SERVICE_MENU:
//Verificaseateclapressionadaacorrespondente
aobotoCancelar.
71.if(keyCode==KEY_SOFTKEY2){
72.currentScreen=LIST_MENU;
73.}
74.break;

//EstnateladeEsperaporConexo
75.caseWAIT_CONNECTION_MENU:
//EstnateladeProcuraporDispositivos
76.caseWAIT_DEVICE_MENU:
//Verificaseateclapressionadaacorrespondente
aobotoCancelar.
77.if(keyCode==KEY_SOFTKEY2){
78.currentScreen=MAIN_MENU;
79.}
80.break;
81.}

//Mandarepintaratela.
82.repaint();
83.serviceRepaints();
84.}
wm05.indb 37 3/10/2005 15:48:32
3 5 Edio
. Tela Sobre, Tela de Espera e Tela de Dispositivos Encontrados.
. SplashScreen1, SplashScreen2 e Tela Principal.
13. A implementao do mtodo run().
1.publicvoidrun(){
//Varivelauxiliardetemporizador
2.inttimer=0;

3.while(currentScreen==WAIT_SERVICE_MENU||
4.currentScreen==WAIT_CONNECTION_MENU||
5.currentScreen==WAIT_DEVICE_MENU){

6.try{
7.Thread.sleep(200);
8.}catch(InterruptedExceptioniex){
9.}

//Calculaoprximoframeaserpintado(animao).
10.gaugeFrame=++gaugeFrame%8;
11.
//Mandarepintarsomentearegiocomaanimao.
12.repaint(this.getWidth()/2-25,getHeight()/2,50,
36);
13.serviceRepaints();

//Simulatempodeesperanabuscapor
dispositivos.
14.if(currentScreen==WAIT_DEVICE_MENU){
15.timer++;
16.if(timer==25){
//SimulaDispositivosencontradoseredireciona
paraatela
//comosdispositivosencontrados.
17.firstViewDevice=0;
18.currentDevice=0;
19.lastViewDevice=Math.min(4,dispositivos.length-
1);
20.currentScreen=LIST_MENU;
21.repaint();
22.serviceRepaints();
23.}
24.}
25.}
26.}
Uma maneira de evitar surpresas ao passar o aplicativo para
o celular testar as cores no prprio aparelho para decidir, por
exemplo, qual o tom de azul que voc quer. Para isso, apresentamos
na 14 um cdigo bastante simples para pintar uma paleta de
cores (visualizada na 9).
Para tornar o aplicativo mais prtico, sugerimos ao leitor que
adicione caixas de texto para entrar
com os valores para Cor Inicial e
Incremento, ao invs de deix-los
definidos como constantes no cdigo
do aplicativo.
Agradecimentos
Gostaramos de agradecer nosso
amigo Fbio Mesquita Pvoa que nos
cedeu o cdigo do jogo InovaVelha e
nos permitiu fazer as alteraes para
a implementao da interface grfica
em baixo nvel.
. Utilizando uma paleta de cores
Ao construir interfaces em baixo nvel, muitas vezes precisamos
trabalhar com as cores e suas tonalidades. Porm, depois de
desenvolver e fazer os testes em emuladores, notamos que ao passar
o aplicativo para o celular, as cores que havamos definidos no esto
mais exatamente como queramos. s vezes o tom da cor que voc
definiu olhando pelo monitor ficou bastante escuro no celular ou at
mesmo o contraste que estava bom j no est mais
adequado para ser visualizado no celular, o que
pode acabar prejudicando o visual de um jogo.
Lembre-se que a tela do celular pequena,
portanto as cores devem ser bem trabalhadas
para no incomodar a vista do usurio.
JSR 11
http://jcp.org/aboutJava/communityprocess/final/
jsr118/index.html
Livro: J2ME in a Nutshell
Autor: Kim Topley OReilly
Forum Nokia: www.forum.nokia.com/
main.html
. Paleta de cores com
vrias tonalidades de azul.
wm05.indb 38 3/10/2005 15:48:35
WebMobile 3
Java
14. Cdigo para mostrar uma Paleta de Cores no celular.
importjavax.microedition.midlet.*;
importjavax.microedition.lcdui.*;
publicclassPaletaCoresMIDletextendsMIDlet{

//Constantesquedefinemapaletadecores.
privatestaticfinalintCOR_INICIAL=0x000032;//Azul
privatestaticfinalintINCREMENTO=0x00000A;//Incrementode
10noAzul
//ComandoSAIR
privateCommandsairCommand;

//Guardaaalturadafontepadro
privateintalturaFonte;

//Paleta:Canvasparapintarascores
privatePaletapaleta;

//Display
privateDisplaydisplay;

publicPaletaCoresMIDlet(){
display=Display.getDisplay(this);

//CriainstnciadocomandoSair.
sairCommand=newCommand(Sair,Command.EXIT,1);

//Criainstnciadapaleta(canvas).
//AdicionaocomandoSaireoCommandListener.
paleta=newPaleta();
paleta.addCommand(sairCommand);
paleta.setCommandListener(paleta);

//Determinaaaltura(empixels)dafontepadro.
alturaFonte=Font.getDefaultFont().getHeight();
}

publicvoidstartApp(){
//ColocaaPaletadecorescomotelacorrente.
display.setCurrent(paleta);
}

publicvoidpauseApp(){
}

publicvoiddestroyApp(booleanunconditional){
//Finalizaoaplicativo.
notifyDestroyed();
}

//ClasseinternaqueherdadeCanvas.
//Responsvelporpintarapaletadecores.
privateclassPaletaextendsCanvasimplementsCommandListener{
publicvoidpaint(Graphicsg){

//Defineacorinicialaserpintada.
intcor=COR_INICIAL;

//Loopparapintarapaletadecores.
for(intaltura=0;altura<getHeight();altura+=
alturaFonte){

//Defineacorcorrenteepintaumretngulo.
g.setColor(cor);
g.fillRect(0,altura,getWidth(),alturaFonte);

//MudaacorparaBranco,pintaabordadoretnguloe
ocdigodacorpintada.
g.setColor(0xFFFFFF);
g.drawRect(0,altura,getWidth()-1,alturaFonte);
g.drawString(0x+Integer.toHexString(cor).
toUpperCase(),getWidth()/2,
altura,Graphics.TOP|Graphics.HCENTER);

//Incrementaacorparaoprximoretngulodapaleta.
cor+=INCREMENTO;
}
}

publicvoidcommandAction(Commandc,Displayabled){

//VerificasefoipressionadoocomandoSair.
if(c==sairCommand){
destroyApp(true);
}
}
}
}
Bruno Chaves Rocha Lima
(brunoc81@gmail.com) faz parte do Grupo Inova
Mobile, desenvolvedor Java com certifcao
SCJP e estuda ASP.NET. Bruno cursa o
ltimo semestre de Engenharia de Redes
de Comunicao na Universidade de Braslia, trabalha com
desenvolvimento de sistemas web na Mirante Web Services
e desenvolve trabalhos com GPS, Bluetooth, J2ME e J2EE.
Edgar Barbosa de Souza
(edgar@redes.unb.br) faz parte do Grupo Inova
Mobile e desenvolvedor Java e C++ com
certifcao SCJP. Edgar est cursando
Engenharia de Redes de Comunicao
na Universidade de Braslia e desenvolvendo software
para simulao e dimensionamento de sistemas de
comunicao.
wm05.indb 39 3/10/2005 15:48:39
0 5 Edio
I
m
p
l
e
m
e
n
t
a
n
d
o

p
e
r
s
i
s
t

n
c
i
a

c
o
m

f
u
x
o
s

e
m

J
2
M
E
N
o artigo anterior sobre persistncia com J2ME, foram apre-
sentadas todas as APIs necessrias para o armazenamento
e recuperao de informaes em um dispositivo mvel.
Porm, a tcnica exposta nesse mesmo artigo tratava apenas da
persistncia de texto puro, onde um registro era manipulado como
uma unidade de informao indivisvel no havendo, pelo menos
de forma natural, a possibilidade de trabalhar com o armazena-
mento de tipos de dados diferentes no mesmo registro.
Nesse artigo, faremos uso de tcnicas de armazenamento e
recuperao que permitiro que um registro contenha tipos de
dados Java diferentes. Assim, valores do tipo inteiro, string e
booleanos podero formar um registro nico em um repositrio
mantido pelo Record Management System (RMS). Os conceitos de
gravao, leitura, navegao, ordenao e filtro sero substan-
cialmente revistos, juntamente com seus respectivos exemplos,
para apresentar a utilizao de fluxos.
Fluxos de entrada e sada
Os fluxos permitem estabelecer canais de comunicao entre
aplicativos e arquivos ou um dispositivo especfico. Quando um
aplicativo precisa interagir com dispositivos de entrada ou sada
ou executar operaes de leitura e escrita em um arquivo, um
fluxo de dados tem que ser aberto para permitir essa comunica-
o. Exemplos reais de fluxos so os objetos System.in e System.
out que so instanciados automaticamente quando da execuo
de um aplicativo Java. O objeto System.in representa o fluxo pa-
dro de entrada, normalmente definido como o teclado. O objeto
System.out representa o fluxo de sada padro de qualquer apli-
cativo Java e permite, por exemplo, o redirecionamento da sua
sada de um dispositivo de vdeo para um arquivo em disco.
Assim, as tarefas de leitura e gravao de registros, realizadas
pelos mtodos do RMS, tambm podem ser vistas como atividades
de fluxo de dados. O ponto importante que esse modelo de fluxo
de dados manipula apenas bytes, na sua forma primria, e para
tal estvamos trabalhando apenas com o tipo string, convertendo
uma string para um array de bytes e vice-versa. exatamente nes-
se ponto que utilizaremos classes de controle de fluxos de dados
para permitir a persistncia de outros tipos de dados.
Para escrever dados, dois fluxos so abertos: um para manipular
tipos de dados Java e outro para, a partir desses dados, gerar um
array de bytes pronto para enviar para o repositrio. No caso da
leitura de dados, basta seguir o processo inverso. Veja na 1
o uso do Modelo 1 de gravao, sem as classes de fluxos (artigo
publicado na edio 3 da Web Mobile) e o Modelo 2 utilizando as
classes de fluxos. A 2 representa visualmente o processo de
leitura no RR com e sem as classes de fluxos, respectivamente
Modelo 1 e Modelo 2.
As classes que implementam os fluxos de entrada e sada
que iremos utilizar nesse artigo so: ByteArrayInputStream,
DataInputStream, ByteArrayOutputStream e DataOutputStream.
Elas esto definidas no pacote java.io que parte da CLDC
por Antonio Eloi de Sousa Jnior
wm05.indb 40 3/10/2005 15:48:41
WebMobile 1
Java Mobile
estende a superclasse abstrata InputStream. Na 2 podem ser
vistos alguns mtodos dessa classe.
No contexto de persistncia de dados, a classe DataOutputStream
complementa a funcionalidade de ByteArrayOutputStream, forne-
cendo uma maneira eficiente de escrever tipos primitivos Java no
seu buffer de sada em um formato portvel entre plataformas.
Assim, dados escritos com DataOutputStream em uma determina-
da plataforma, podem ser lidos com DataInputStream em qualquer
outra.
As 3 e conceituam, respectivamente, alguns mtodos das
classes DataOutputStream e DataInputStream.
Manipulando registros com fluxos
Com os conceitos da seo anterior j possvel construirmos
um primeiro exemplo. Este ir demonstrar o processo de gravao
e leitura de dados utilizando as classes de fluxos j apresentadas.
Observe a 1, mais especificamente o mtodo construtor que,
utilizando um fluxo de sada, escreve dados no RMS e o mtodo
startApp() que, atravs de um fluxo de entrada, ler esses mesmos
dados.
Em primeiro lugar, vamos nos concentrar no mtodo cons-
trutor ExemploRMSF(), onde ocorrem todas as operaes de
escrita de dados no repositrio de registros produto, j devida-
mente criado. Na linha 29 criado um fluxo de sada da classe
ByteArrayOutputStream, baseado em um array de bytes, que con-
ter os dados para posterior armazenamento. Um outro fluxo
criado na linha 31, da classe DataOutputStream, para escrever
tipos de dados Java primitivos direto no array de bytes definido
anteriormente. Com isso, o array de bytes interno mantido em
bFluxo conter dados portveis entre plataformas. Isso significa,
por exemplo, que um valor inteiro gravado pelo fluxo dFluxo ser
lido como um valor inteiro independentemente da forma de repre-
sentao de tipos inteiros da plataforma (16 bits, 32 bits e etc).
Uma vez que os fluxos foram criados, os dados so escritos
de acordo com os seus tipos (linha 33 a 35). O mtodo flush()
1. Dois modelos de gravao no RR.
2. Dois modelos de leitura no RR.
Funcionalidade Mtodo Correspondente
Fecha o fluxo de sada e libera qualquer recurso associado com o mesmo. void close()
Reinicializa o campo count do array de bytes do fluxo de sada para zero, descartando qualquer dado
acumulado no fluxo.
void reset()
Retorna o tamanho atual do buffer de dados. int size()
Cria e retorna um novo array de bytes que representa o contedo do buffer do fluxo. byte[] toByteArray()
1. Alguns mtodos da classe ByteArrayOutputStream.
Funcionalidade Mtodo Correspondente
Fecha o fluxo de entrada e libera qualquer recurso associado com o mesmo. void close()
Reinicializa o buffer do fluxo de entrada, descartando qualquer dado acumulado no fluxo. void reset()
Retorna o nmero de bytes de entrada total que ainda podem ser lidos no fluxo. int available()
2. Alguns mtodos da classe ByteArrayInputStream.
(Configurao de Dispositivo Conectado Limitado). Um dos obje-
tivos da CLDC definir um conjunto mnimo de classes Java que
atendam a uma especificao de uma JVM, de tal forma que su-
porte uma ampla variedade de dispositivos com memria, recursos
de vdeo, conectividade e processamento limitado. Os pacotes de
classes da CLDC esto presentes tambm no J2SE, tornando, por-
tanto, todo o conhecimento adquirido na utilizao delas nesse
ambiente passvel de ser reaproveitado no J2ME.
A classe ByteArrayOutputStream estende a classe abstrata
OutputStream (superclasse de todas as classes que efetuam fluxo
de sada de bytes) e implementa um fluxo de sada, em que os
dados so escritos em um buffer representado por um array de
bytes. Esse buffer cresce automaticamente medida que os dados
so escritos no fluxo. Veja na 1 alguns mtodos da classe
ByteArrayOutputStream.
A classe ByteArrayInputStream mantm um buffer interno de bytes
para serem lidos em um fluxo de entrada. ByteArrayInputStream
wm05.indb 41 3/10/2005 15:48:48
2 5 Edio
1. Exemplo de uso de fluxos para persistir dados
1:/*ExemploRMSF.java
2:*/
3:importjavax.microedition.rms.*;
4:importjavax.microedition.midlet.*;
5:importjavax.microedition.lcdui.*;
6:importjava.io.*;
7:
8:publicclassExemploRMSFextendsMIDletimplements
CommandListener
9:{
10:privateFormFrmRMSF;
11:privateCommandcmSair;
12:
13:privateRecordStorerr=null;
14:
15:publicExemploRMSF()
16:{
17:cmSair=newCommand(Sair,Command.EXIT,1);
18:FrmRMSF=newForm(ExemploFluxos);
19:FrmRMSF.addCommand(cmSair);
//Janelacomapenasumcomando...Sair
20:FrmRMSF.setCommandListener(this);
//Registrandoumreceptordeeventos
21:
22:byte[]Registro;
23:try
24:{
25://Criaorepositrioderegistros
26:rr=RecordStore.openRecordStore(produto,true);
27:
28://Criafluxodesadadebytes
29:ByteArrayOutputStreambFluxo=new
ByteArrayOutputStream();
30://Criafluxoparaescrevertiposdedados//
//primitivosnofluxodebytes
31:DataOutputStreamdFluxo=newDataOutputStream(bFlu
xo);
32:
33:dFluxo.writeInt(1);
//Escrevetipointeironoarraydebytes
34:dFluxo.writeUTF(LONADEFREIO);
//Escrevetipostringnoarraydebytes
35:dFluxo.writeInt(10);
//Escrevetipointeironoarraydebytes
36:
37:dFluxo.flush();//Gravaelimpaobufferdedados
38:
39://Leroarraydebytesmantidopelofluxodesada
40:Registro=bFluxo.toByteArray();
41://Adicionaoregistroapartirdaposioinicial
//0doarraydebytes
42://comtamanhoigualaoseutamanhototal(length)
43:rr.addRecord(Registro,0,Registro.length);
44:
45://Reinicializaofluxodesada
46:bFluxo.reset();
47:
48://Fechandoosfluxos
49:bFluxo.close();
50:dFluxo.close();
51:
Funcionalidade Mtodo Correspondente
Fecha o fluxo de entrada e libera qualquer recurso associado com o mesmo. void close()
L um byte de entrada e retorna true se o byte diferente de zero e false se o byte igual a zero. boolean readBoolean()
L e retorna um byte de entrada. int readByte()
L quatro bytes e retorna um valor inteiro. int readInt()
L e retorna um tipo string codificado no formato UTF-8. String readUTF()
L um caractere de entrada e retorna um valor do tipo char. char readChar()
. Mtodos da classe DataInputStream.
3. Mtodos da classe DataOutputStream.
Funcionalidade Mtodo Correspondente
Fecha o fluxo de sada e libera qualquer recurso associado com o mesmo. void close()
Limpa o buffer associado com o fluxo. void flush()
Escreve um valor booleano no fluxo de sada com o tamanho de 1 byte. void writeBoolean(boolean v)
Escreve um byte no fluxo de sada. void writeByte(int v)
Escreve um valor inteiro no fluxo de sada com o tamanho de 4 bytes. void writeInt(int v)
Escreve um tipo string no fluxo de sada utilizando a codificao UTF-8, de maneira independente de plataforma. void writeUTF(String v)
Escreve um tipo char no fluxo de sada com o tamanho de 2 bytes. void writeChar(int v)
wm05.indb 42 3/10/2005 15:48:49
WebMobile 3
Java Mobile
continuao
52:}
53:catch(Exceptione)
//Tratamentosimplesdeexceesdorms
54:{
55:System.err.println(Erro:+e.toString());
56:}
57:}
58:
59:publicvoidstartApp()
60:{
61:try
62:{
63:
64:
65:byte[]Registro=newbyte[30];
//Paraessecaso30osuficiente
66://Melhorabordagem:alocaodinmica
67://Criandoosfluxos
68:ByteArrayInputStreambFluxo=
newByteArrayInputStream(Registro);
69:DataInputStreamdFluxo=
newDataInputStream(bFluxo);
70:
71://Lendoregistrodorepositrioparaoarray
//debytes
72:rr.getRecord(1,Registro,0);
73:
74://Lendoapartirdofluxo
75:FrmRMSF.append(Codigo:+dFluxo.readInt());
76:FrmRMSF.append(Nome:+dFluxo.readUTF());
77:FrmRMSF.append(Saldo:+dFluxo.readInt());
78:
79://Reinicializaleituranoinciodoarrayde
//bytes
80:bFluxo.reset();
81:
82://Fechandoosfluxos
83:bFluxo.close();
84:dFluxo.close();
85:
86:}
87:catch(Exceptione)
//Tratamentosimplesdeexceesdorms
88:{
89:System.err.println(Erro:+e.toString());
90:}
91:Display.getDisplay(this).setCurrent(FrmRMSF);
92:}
93:
94:publicvoidpauseApp()
95:{
96:}
97:
98:publicvoiddestroyApp(booleanunconditional)
99:{
100:try
101:{
102:rr.closeRecordStore();
//Fechaorepositrioderegistros
103:RecordStore.deleteRecordStore(produto);
//Apagaorepositrioderegistro
104:}
105:catch(Exceptione)
106:{
107:System.err.println(Erro:+e.toString());
108:}
109://Notificaogerenciadordeaplicativosquea
//MIDletpodeserdesligada
110:notifyDestroyed();
111:}
112:
113:publicvoidcommandAction(Commandcm,Displayabledp)
114:{
115:if(cm==cmSair)//Botosairpressionado!
116:destroyApp(true);
117:}
118:
119:}
(linha 37) grava os dados no array de bytes e limpa o buffer as-
sociado com o fluxo dFluxo. importante atentar para a ordem
em que cada tipo de dado gravado (no nosso caso inteiro para o
cdigo do produto, string para a descrio e inteiro para o saldo),
pois a leitura desses dados ter que ser feita exatamente nessa
ordem para garantir um avano correto no array de bytes.
Na linha 40, o mtodo toByteArray() l os dados do fluxo de
bytes para um array de bytes e, por fim, o registro est pronto
para ser gravado no repositrio de registros (linha 43). O mto-
do reset(), utilizado na linha 46, limpa o array interno mantido
por bFluxo, garantindo que qualquer outra operao de gravao
(writeInt(), writeUTF() e etc.) no ser anexada ao array existen-
te e sim tratada como um registro novo.
O mtodo startApp() responsvel por fazer a leitura dos dados
anteriormente gravados. Inicialmente, o array Registro aloca-
do (linha 65) para receber o registro lido a partir do repositrio
(linha 72). Um fluxo ByteArrayInputStream criado, utilizando
o array Registro como buffer de entrada (linha 68). A seguir, um
fluxo DataInputStream criado, utilizando o fluxo bFluxo como
parmetro para o seu construtor. A partir desse momento, os
wm05.indb 43 3/10/2005 15:48:49
5 Edio
dados que antes estavam representados na forma binria, quando
da leitura no repositrio, podem ser recuperados de acordo com
seus tipos primitivos Java atravs dos mtodos de leitura do obje-
to dFluxo (linha 75 a 77). Se precisssemos ler mais algum regis-
tro seria necessrio o uso do mtodo reset() para reposicionar a
leitura no incio do array de bytes do fluxo ByteArrayInputStream.
No o caso do exemplo da 1, mas precisaremos adicionar mais
um registro para melhorar o entendimento dos tpicos a seguir.
Tambm interessante fechar os fluxos para liberar recursos
quando no houver mais a necessidade de trabalhar com eles. Isso
feito na chamada do mtodo close() nas linhas 83 e 84.
A 3 apresenta o exemplo da 1 em funcionamento no
emulador do J2ME Wireless Toolkit.
Navegao com fluxos
Navegar em um repositrio de registros criado a partir do uso
de fluxos de sada requer tambm a utilizao de fluxos de entra-
da para recuperao e apresentao dos dados. At porque esse
mesmo repositrio normalmente mantm registros compostos
onde seus campos tm que ser lidos individualmente. Nesse caso,
a interface RecordEnumeration utilizada praticamente da mesma
forma. A diferena est exatamente na utilizao de fluxos de
entrada para leitura dos campos a partir do array de bytes.
Para tornar o exemplo de enumerao mais elementar, vamos fa-
zer uma alterao no cdigo do mtodo construtor ExemploRMSF()
da 1, incluindo mais um registro no repositrio. Adicione na
linha 47 o bloco de cdigo da 2.
Adicione tambm o mtodo Navegacao() para
a classe ExemploRMSF. Veja a sua im-
plementao na 3. Esse mtodo
responsvel pelo avano por todos
os registros do RR, sempre fazendo uso dos fluxos de entrada para
recuperar os campos.
Conforme pode ser visto na 3, a parcela de cdigo que trata
do uso dos fluxos e da leitura de dados propriamente dita muito
semelhante quela j existente no mtodo startApp().
Resta ainda fazer uma chamada ao mtodo recm declarado,
Navegao(), para conseguir o resultado esperado. Isso ser fei-
to no mtodo startApp(). Substitua o cdigo desse mtodo pelo
apresentado na .
Veja a com o resultado da enumerao nos registros.
Pesquisando com fluxo de dados
A utilizao da interface
RecordFilter para aplicar filtros
de pesquisa em um enumerador
j foi tratada no artigo publica-
do na Web Mobile 3 sobre per-
sistncia de dados. Basicamen-
te, para pesquisar em um RR
que tenha sido criado utilizando
fluxos, modifica-se apenas o
mtodo matches(). interessan-
te relembrar que o mtodo ma-
tches() chamado pelo enume-
rador para cada registro no RR e
este, de acordo com a condio
de filtro, pode incluir ou no o
registro no resultado da pesqui-
sa. Para realizar a sua tarefa, o
mtodo matches() recebe uma
cpia do registro em um array de 3. Exemplo do uso de fluxo.
2. Incluindo mais um registro para melhor exemplificar o uso do RecordEnumeration.
1:dFluxo.writeInt(2);//Escrevetipointeironoarraydebytes
2:dFluxo.writeUTF(AMORTECEDOR);//Escrevetipostringnoarraydebytes
3:dFluxo.writeInt(12);//Escrevetipointeironoarraydebytes
4:dFluxo.flush();//Gravaelimpaobufferdedados
5:
6://Leroarraydebytesmantidopelofluxodesada
7:Registro=bFluxo.toByteArray();
8:
9://Adicionaoregistroapartirdaposiaoinicial0doarraydebytes
10://comtamanhoigualaoseutamanhototal(length)
11:rr.addRecord(Registro,0,Registro.length);
12:
13://Reinicializaofluxodesada
14:bFluxo.reset();
wm05.indb 44 3/10/2005 15:48:52
WebMobile
Java Mobile
bytes. O array de bytes ainda precisa ser convertido no formato
em que foi gravado. Isso feito atravs da criao de um fluxo
ByteArrayInputStream (linha 19 da ) que cria um buffer de
entrada para o array de bytes recebido, e um DataInputStream
(linha 21 da ) que, atravs de outro fluxo de entrada, ler tipos
de dados Java a partir do primeiro fluxo. O fluxo DataInputStream
est preparado para ler os dados no formato em que foram grava-
dos. A classe EfetuaPesquisaDescricao tem o propsito de pesqui-
sar apenas pelo campo descrio do registro, porm necessrio
tambm fazer a leitura do primeiro campo (linha 25 da ) para
forar um posicionamento correto no campo descrio no array
de bytes.
Observe na a declarao completa da classe Efetua
PesquisaDescricao que implementa a interface RecordFilter.
Para realizar uma pesquisa utilizando a classe EfetuaPesquisa
. Exemplo do uso de enumerao com fluxo.
3. Implementao do mtodo Navegao().
1:publicvoidNavegacao()
2:{
3: byte[]Registro=newbyte[30];
4:
5:try
6:{
7://Criandoosfluxos
8:ByteArrayInputStreambFluxo=newByteArrayInput
Stream(Registro);
9:DataInputStreamdFluxo=new
DataInputStream(bFluxo);
10:
11:RecordEnumerationre=rr.enumerateRecords(null,
null,false);
12:while(re.hasNextElement()){
13:rr.getRecord(re.nextRecordId(),Registro,0);
14://Lendoapartirdofluxo
15:FrmRMSF.append(Codigo:+dFluxo.readInt());
16:FrmRMSF.append(Nome:+dFluxo.readUTF());
17:FrmRMSF.append(Saldo:+dFluxo.readInt());
18://Reinicializaleituranoinciodoarrayde
bytes
19:bFluxo.reset();
20:}
21://Fechandoosfluxos
22:bFluxo.close();
23:dFluxo.close();
24:}
25:catch(Exceptione)
26:{
27:System.err.println(Erro:+e.toString());
28:}
29:}
4. Novo mtodo startApp().
1:publicvoidstartApp()
2:{
3:
4:Navegacao();
5:
6:Display.getDisplay(this).setCurrent(FrmRMSF);
7:}
Descricao, vamos declarar um novo mtodo chamado Pesquisa-
Descricao() para a classe principal do nosso exemplo, ExemploR-
MSF. Veja a .
O mtodo PesquisaDescricao() comea alocando uma instncia
da classe EfetuaPesquisaDescricao que implementa a interface
RecordFilter (linha 5 da ). Observe que j na criao do objeto
de pesquisa passado um parmetro que identifica exatamente a
palavra a ser pesquisada no RR. Em seguida criado um enume-
rador (linha 6 da ) que efetuar a pesquisa no RR de acordo
com o parmetro e as regras do objeto pesquisa.
Se como resultado o enumerador retornar pelo menos um re-
gistro, ento a pesquisa foi bem sucedida e existem dados para
apresentar. Exatamente nesse momento necessrio mais uma
vez utilizar os fluxos de entrada para converter o registro retor-
nado para o seu formato original, j que o mtodo nextRecord()
(linha 11 da ) do enumerador retorna o registro como um
array de bytes.
A utilizao dos fluxos de entrada ByteArrayInputStream e
DataInputStream semelhante que foi realizada pelo mtodo
matches() da classe EfetuaPesquisaDescricao (linha 12 da ).
wm05.indb 45 3/10/2005 15:48:56
5 Edio
Atente tambm para o fato de que antes de ler o campo descrio
(linha 18 da ), necessrio fazer a leitura do primeiro campo
com o mtodo readInt() (linha 16 da ) para se posicionar
corretamente no array de bytes.
Agora resta apenas efetuar a pesquisa testando o nosso mto-
do. Para isso, adicione as duas linhas abaixo dentro do mtodo
startApp(), logo aps a chamada ao mtodo Navegacao(). Veja a
apresentando o resultado dessas duas linhas.
PesquisaDescricao(MOLA);
PesquisaDescricao(AMORTECEDOR);
Ordenando registros com fluxo de dados
Ordenar registros uma outra necessidade constante em am-
bientes que mantm persistncia de dados. Quando os registros
de um RR so compostos de mais de um campo, naturalmente,
haver mais opes de ordenao, considerando que cada campo
individualmente ou at mesmo uma combinao de campos po-
dem fazer parte de uma condio de ordenao.
Portanto, assim como no caso de persistncia de texto puro
tratado no artigo anterior, necessrio implementar a interface
RecordComparator para definir o critrio de ordenao do RR. Veja
a declarao da classe OrdemDescricao na .
No nosso exemplo, uma classe foi criada com o propsito de
fornecer ordenao pelo campo descrio, mas com algumas m-
nimas mudanas possvel adicionar tambm o recurso de orde-
nao pelo campo cdigo do
registro do RR. Observe que a
forma de utilizao dos fluxos
de entrada semelhante ao
que foi aplicada no exemplo
da pesquisa de registros no
tpico anterior, inclusive a
necessidade de ler primeiro o
campo cdigo do registro no
fluxo para permitir um avan-
o correto no vetor de bytes
para o campo descrio. A
diferena est no fato do al-
goritmo de ordenao precisar
sempre ler dois registros para
fazer a comparao e defi-
nir sua ordem. Estando com
os dois registros lidos, resta
apenas definir qual vem pri-
meiro atravs do teste com os
5. Implementao da interface RecordFilter que trabalha com fluxos.
1:classEfetuaPesquisaDescricaoimplementsRecordFilter
2:{
3:privateStringpalavra=null;
//Receberdoconstrutorvaloraserpesquisado
4:
5:publicEfetuaPesquisaDescricao(Stringpalavra)
6:{//Convertendoparaminsculaparmetrodoconstrutor
7:this.palavra=palavra.toLowerCase();
8:}
9:
10:/*matchestestarseoarraydebytesdevidamente
convertidoemstring
11:equivalenteaovaloraserpesquisado*/
12:publicbooleanmatches(byte[]campo)
13:{
14:Stringstr=null;
15:
16:try
17:{
18://Fluxodeentradaparaleituradeumarray
//debytes
19:ByteArrayInputStreambFluxo=
newByteArrayInputStream(campo);
20://Fluxodeentradaparaleituradetiposprimitivos
//Javanoarraydebytes
21:DataInputStreamdFluxo=
newDataInputStream(bFluxo);
22:
23://Ocampocdigofoigravadoprimeiro,portantotem
//queserlidoantes
24://daleituradadescrio(avanodaposionoarray)
25:dFluxo.readInt();
26://Leradescriodoproduto
27:str=dFluxo.readUTF().toLowerCase();
//Convertendotudoparaminscula
28:
29:bFluxo.close();
30:dFluxo.close();
31:}
32:catch(Exceptione)
33:{
34:System.err.println(Erro:+e.toString());
35:}
36:
37:if(palavra!=null&&str.indexOf(palavra)!=-1)
38:returntrue;//Oregistrovlido
39:else
40:returnfalse;//Oregistronovlido
41:}
42:}
. Pesquisando pela descrio
do produto (um dos campos do RR).
wm05.indb 46 3/10/2005 15:48:58
WebMobile
Java Mobile
campos EQUIVALENT, FOLLOWS e PRECEDES fornecidos pela inter-
face RecordComparator. Veja a para mais detalhes sobre o
que esses campos representam.
Para utilizar a classe OrdemDescrio, vamos declarar mais um
mtodo chamado NavegacaoOrdemDescricao() classe do nosso
exemplo, ExemploRMSF. Veja a .
O mtodo NavegacaoOrdemDescricao() cria um enumerador
para apresentar os registros do RR na ordem definida pelo ob-
jeto OrdemDescricao. Observe
que o seu cdigo muito seme-
lhante ao mtodo Navegao()
tratado anteriormente nesse ar-
tigo, com a diferena de que foi
utilizado o segundo parmetro
do RecordEnumeration que trata
justamente da condio de orde-
nao do enumerador.
Para chamar o mtodo Nave-
gacaoOrdemDescricao(), vamos
mais uma vez alterar o mtodo
startApp() adicionando a linha
abaixo para testar a navegao
por ordem do campo descrio.
Veja a com o resultado da uti-
lizao do mtodo de ordenao.
NavegacaoOrdemDescricao();
6. Mtodo para realizar pesquisa no RR
utilizando o campo descrio do RR
1:publicvoidPesquisaDescricao(Stringpalavra)
2:{
3:try
4:{
5:EfetuaPesquisaDescricaopesquisa=
newEfetuaPesquisaDescricao(palavra);
6:RecordEnumerationre=
rr.enumerateRecords(pesquisa,null,false);
7:
8://Sepesquisabemsucedida(achoupelomenosum
//registro)
9:if(re.numRecords()>0){
10://Criafluxodeentradadearraydebytesede
//tiposjava
11:ByteArrayInputStreambFluxo=
newByteArrayInputStream(re.nextRecord());
12:DataInputStreamdFluxo=
newDataInputStream(bFluxo);
13:
14://Ocampocdigofoigravadoprimeiro,////
//portantotemqueserlidoantes
15://daleituradadescrio(avanodaposio
//noarray)
16:dFluxo.readInt();
17://Leradescriodoproduto
18:FrmRMSF.append(Encontrado:+dFluxo.readUTF());
19:
20://Liberandorecursos
21:dFluxo.close();
22:bFluxo.close();
23:re.destroy();
24:
25:}else
26:FrmRMSF.append(Noencontrado:+palavra);
27:re.destroy();
28:}
29:catch(Exceptione)
30:{
31:System.err.println(Erro:+e.toString());
32:}
33:}
Concluso
No artigo sobre persistncia publicado na terceira edio da
Web Mobile, tratamos especificamente de armaze-
namento e recuperao de texto puro nos registros
de um repositrio. Essa tcnica tem as suas
vantagens em relao a que est exposta
nesse artigo. A principal delas justamente
a economia de recursos proporcionada
pelo fato de no necessitar do uso de
classes adicionais como as classes de
fluxos de entrada e sada aqui apre-
sentadas. Isso muito importante
quando se trata de um dispositivo de
recursos limitados de memria e pro-
cessamento.
Porm, quando diversas informa-
es devem ser armazenadas em um
mesmo registro, o uso de texto
puro pode exigir mais esforo
em relao definio dos
algoritmos de converso,
concatenao e quebra de
strings. Em operaes de
ordenao, mas espe-
cificamente, traba-
lhar com registro
composto sem o
. Aplicao completa
executando navegao ordenada
pelo campo descrio.
wm05.indb 47 3/10/2005 15:49:00
5 Edio
7. Implementao da interface RecordComparator
para ordenar registros com fluxo
1:classOrdemDescricaoimplementsRecordComparator
2:{
3:publicintcompare(byte[]par1,byte[]par2)
4:{
5: Stringstr1=newString();
6: Stringstr2=newString();
7: ByteArrayInputStreambFluxo;
8: DataInputStreamdFluxo;
9:
10:try
11:{
12://Lendoadescriodoprimeiroregistro
13: //Fluxodeentradaparaleituradeumarray
//debytes
14: bFluxo=newByteArrayInputStream(par1);
15://Fluxodeentradaparaleituradetipos
//primitivosJavanoarraydebytes
16: dFluxo=newDataInputStream(bFluxo);
17: dFluxo.readInt();//Lerocampocdigoprimeiro
18:str1=dFluxo.readUTF();
//Paraaseguirleradescrio
19:
20://Lendoadescriodosegundoregistro
21:bFluxo=newByteArrayInputStream(par2);
22://Fluxodeentradaparaleituradetiposprimitivos
//Javanoarraydebytes
23: dFluxo=newDataInputStream(bFluxo);
24:dFluxo.readInt();//Lerocampocdigoprimeiro
25:str2=dFluxo.readUTF();
//Paraaseguirleradescrio
26:}
27:catch(Exceptione)
28:{
29: System.err.println(Erro:+e.toString());
30:}
31:intresult=str1.compareTo(str2);
32:if(result==0)
33:returnRecordComparator.EQUIVALENT;
34:elseif(result<0)
35:returnRecordComparator.PRECEDES;
36:else
37:returnRecordComparator.FOLLOWS;
38:}
39:}
8. Mtodo NavegacaoOrdenada()
1:publicvoidNavegacaoOrdemDescricao()
2:{
3:FrmRMSF.append(===================================);
4:FrmRMSF.append(NavegacaoOrdemDescrio);
5:
6:byte[]Registro=newbyte[30];
//Tamanhosuficienteparaoregistro
7:
8:try
9:{
10://Criandoosfluxos
11:ByteArrayInputStreambFluxo=
newByteArrayInputStream(Registro);
12:DataInputStreamdFluxo=
newDataInputStream(bFluxo);
13:
14://Criaobjetoresponsvelpelaordenaopordescrio
15:OrdemDescricaoordem=newOrdemDescricao();
16:RecordEnumerationre=
rr.enumerateRecords(null,ordem,false);
17:while(re.hasNextElement()){
18:
19:rr.getRecord(re.nextRecordId(),Registro,0);
//Lendoregistro
20://Lendoapartirdofluxo
21:FrmRMSF.append(Codigo:+dFluxo.readInt());
22:FrmRMSF.append(Nome:+dFluxo.readUTF());
23:FrmRMSF.append(Saldo:+dFluxo.readInt());
24://Reinicializaleituranoinciodoarrayde
//bytes
25:bFluxo.reset();
26:}
27://Liberandorecursos
28:bFluxo.close();
29:dFluxo.close();
30:re.destroy();
31:}
32:catch(Exceptione)
33:{
34:System.err.println(Erro:+e.toString());
35:}
36:}
wm05.indb 48 3/10/2005 15:49:00
WebMobile
Java Mobile
uso de fluxos trar dificuldades de codificao desnecessrias, considerando que no
modelo utilizando fluxos, conforme exposto nesse artigo, o cdigo fica mais simples e
objetivo.
A utilizao dos fluxos de entrada e sada fornece um meio interessante de tornar a
persistncia em dispositivos mveis mais semelhante com o modelo utilizado na com-
putao em desktops. O modelo de registro composto de campos que podem armazenar
informaes diversas e especficas mais intuitivo. Alm disso, se o desenvolvedor j
tiver experincia com Java, o fato das classes que tratam dos fluxos j estarem presen-
tes tanto no J2ME quanto no J2SE diminui a curva de aprendizagem para trabalhar com
persistncia no mundo mobile.
Antonio Eloi de Sousa Jnior (eloijr@uol.com.br) est cursando o
ltimo ano do curso de Sistemas de Informao na Faculdade de
Imperatriz (FACIMP). Trabalha a mais de 10 anos desenvolvendo
softwares para desktop nas reas de automao comercial,
industrial e engenharia forestal. H cerca de um ano descobriu
J2ME como uma grande soluo para computao mvel.
Extensa e detalhada documentao sobre o pacote java.io.
http://developer.classpath.org/doc/java/io/
Especifcao da linguagem Java para o pacote java.io.
http://sunsite.nstu.ru/java-stuff/langspec-1.0/javaio.doc.html
Portal brasileiro especializado em desenvolvimentos para dispositivo.
www.microd.info
MIDP APIs for Wireless Applications Apostila introdutria sobre MIDP.
http://java.sun.com/products/midp/midp-wirelessapps-wp.pdf
Core J2ME: John W. Muchow
Primeiro livro lanado na lngua portuguesa sobre programao J2ME. Alm disso, um
excelente material sobre o assunto.
Java Como Programar: Harvey M. Deitel & Paul J. Deitel
Excelente livro que aborda desde programao orientada a objetos, java bsico
e tambm tpicos avanados de Java.
Valor Descrio
EQUIVALENT Os registros so equivalentes.
FOLLOWS O mtodo compare() estabelece que o primeiro parmetro vir aps o segundo.
PRECEDES O mtodo compare() estabelece que o primeiro parmetro precede o segundo.
. Campos da interface RecordComparator.
1terco_LM.ai 27.06.05 11:51:13
wm05.indb 49 3/10/2005 15:49:04
0 5 Edio
Desenvolvendo
Web Services
seguros na
plataforma
.NET
Confgurando e
autenticando
com WSE 2.0
E
xistem algumas tcnicas para evitar possveis invases em
aplicativos com o objetivo de assegurar a confiabilidade
das informaes disponveis em diversos nveis de siste-
mas. Entretanto, notvel que a grande maioria dos desenvolve-
dores no se preocupam com segurana. Essa tarefa normalmente
atribuda ao departamento de infra-estrutura da empresa.
Em meados de 2001, a Microsoft lanou no mercado de desen-
volvimento de software a tecnologia .NET, que vem colaborando
com a evoluo de todo o ciclo de criao de aplicativos para
qualquer necessidade. Em meio a toda essa evoluo, foi anun-
ciada a possibilidade de criao de XML Web Services utilizando
como base o .NET Framework.
XML Web Services, ou servios web, a tecnologia mais in-
teressante para trocar informaes pela internet. Eles permitem
que diferentes empresas, mesmo utilizando distintas tecnologias
e plataformas, conectem-se de maneira padro, e executem pro-
cedimentos remotos sobre o protocolo http. A segurana com web
services algo que tambm deve ser colocado em pauta, j que os
web services so servios pblicos que qualquer cliente pode con-
sumi-lo. Nesse artigo vamos entender quais tcnicas devem ser
utilizadas para garantir a segurana de web services, objetivando
restringir o acesso e execuo de mtodos.
Criando o web service
A criao de web services se torna uma tarefa muito simples
quando se utiliza o Visual Studio .NET. Para esse artigo utilizare-
mos o Visual Studio .NET 2003.
Com o Visual Studio .NET aberto, vamos iniciar a criao do web
service. Selecione o Menu File, aponte para New | Project, selecio-
ne a linguagem C#, o template ASP .NET Web Service, e informe o
nome do projeto conforme mostra a 1.
1. Criao do projeto do tipo web service.
por Andrey Sanches
wm05.indb 50 3/10/2005 15:49:08
WebMobile 1
.NET Web
Seguindo o mesmo conceito de projetos ASP.NET Web
Application, o arquivo de configurao (web.config) e o arquivo
global ASA (global.asax) sero criados respeitando os mesmos
conceitos e caractersticas de um web site.
O arquivo Service1.asmx representa o web service que dispo-
nibilizar os servios para as aplicaes. Tecle F7 para alternar
para o arquivo de cdigo C# (Service1.asmx.cs) e iniciarmos a
codificao.
Por facilidade, o Visual Studio cria um WebMethod padro, o
famoso HelloWorld. Exclua esse WebMethod e crie o WebMethod
getCustomer() que retornar uma listagem de clientes do banco
de dados NorthWind atravs de um objeto do tipo DataSet. Codi-
fique o WebMethod conforme a 1.
importante lembrar que, inicialmente, o web service est
aberto para qualquer aplicao que tentar consumi-lo. Isso pode
ser um problema quando se trata de informaes sigilosas e
que de maneira alguma devem ser visualizadas por aplicaes
desconhecidas.
Para solucionar o problema de segurana, utilizaremos o WSE
(Web Service Enhancement). Esta uma tecnologia que utiliza os
protocolos WS-Security (ler 1) com objetivo de prover seguran-
a aos web services pblicos. As mensagens so acompanhadas de
credenciais que determinam o tipo da autenticao e dados para
validao para garantir que a aplicao consumidora conhecida
e tem permisso de consumir o servio.
1. WS-Secutiry
WS-Security um protocolo que prov um mecanismo eficiente de
segurana para as mensagens trocadas entre aplicaes consumidoras
e web services.
Instalando e configurando o WSE 2.0
Antes de iniciar a instalao do WSE, necessrio fazer o
download (gratuito) do instalador atravs da url: www.microsoft.
com/downloads/details.aspx?FamilyId=FC5F06C5-821F-41D3-
A4FE-6C7B56423841&displaylang=en.
Aps o download, execute o arquivo (Microsoft WSE 2.0 SP2.
msi) para iniciar o processo de instalao. Clique Next na pri-
meira tela Welcome, em seguida o sistema questiona sobre o
1. Criao do WebMethod para retorno de clientes
usingSystem;
usingSystem.Collections;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Diagnostics;
usingSystem.Web;
usingSystem.Web.Services;
usingSystem.Data.SqlClient;
[WebMethod]
publicDataSetgetCustomers()
{
//validaoenviodostokensdeseguranaedoobjeto
//context
Seguranca.validarLogin(RequestSoapContext.Current);

//criaoobjetodotipoSqlConnectionparaconexocomo
//bancodedados
SqlConnectionconn=newSqlConnection(Server=(local);Data
base=NorthWind;UserID=seulogin;Password=suasenha;Trusted_
Connection=False);

try
{
//abreaconexocomobanco
conn.Open();
}
catch(SqlExceptionex)
{
//disparaumaexceoparaaaplicaoque
//estconsumindooWebService
thrownewException(Ocorreuumerroaoabrirobancode
dados,adescriodoerro+ex.Message);
}

//criaoobjetodotipoSqlCommandconfigurandoa
//SELECTqueserusadapararetornar
//osdadosdobancodedados
SqlCommandcommand=newSqlCommand(
SELECTCompanyName,ContactName
fromCustomers,conn);
//criaoobjetodotipoSqlDataAdapterquefar
//opreenchimentodoDataSet
SqlDataAdapteradap=newSqlDataAdapter(command);
//criaoDataSetpararetornodosdados
DataSetdataset=newDataSet();
//preencheoDataSetcomosdadosdocliente
adap.Fill(dataset,Clientes);
//retornaosdadosparaaaplicaoconsumidora
returndataset;
}
wm05.indb 51 3/10/2005 15:49:10
2 5 Edio
termo de responsabilidade License Agreement, leia e aceite-o
(ou no). Na prxima tela, Setup Type, voc dever informar o
tipo de instalao. Se estiver instalando no servidor web de produ-
o, escolha a instalao Administrator que contm os Runtime
Files (arquivos e assemblies necessrios para executar o WSE 2.0)
e ferramentas de administrao. Se voc estiver instalando como
um desenvolvedor, escolha a opo Visual Studio Developer.
Esta opo instalar todas as ferramentas, inclusive o plug-in
para o Visual Studio .NET afim de facilitar a criao do web service
seguro utilizando os recursos de segurana do WSE 2.0. Aps a
seleo, clique Next e finalize a instalao.
Com o WSE 2.0 j instalado, necessrio configurar o web
service para utilizar os servios de segurana. Para isso, alterne
para o Visual Studio .NET e
clique com o boto direito do
mouse no projeto WSSeguro e
selecione WSE Settings 2.0
conforme mostra a 2.
Selecionando a opo ci-
tada na 2, ser aberta
uma segunda tela de con-
figurao que habilitar o
WSE para o web service em
questo. Habilite as opes
Enable this project for Web
Services Enhancements
e Enable Microsoft Web
Services Enhancements Soap
Extensions conforme mostra
a 3. Isto far com que
sejam adicionadas ao arquivo
de configurao (web.config)
as diretivas necessrias para
o web service utilizar os servios de segurana que o WSE disponi-
biliza conforme mostra a 2. Fazendo uma breve descrio sobre
as demais guias dessa tela, temos que:
na guia Security possvel encontrar as configuraes
Wizards (inclusive a configurao de Tokens Manager que fize-
mos manualmente no web.config) e configuraes para Certi-
ficado X.509.
a guia Routing nos possibilita o uso dos recursos de WSE
em outra mquina no caso de uma aplicao distribuda.
a guia Customized Filters nos auxilia no redirecionamento
de mensagens criando filtros para processamento/modificao.
Por default essa opo desabilitada.
em Policy possvel habilitar as opes para Poltica
de Segurana e exigncias para o WSE. Por exemplo, um web
service pode requerer que as mensagens encaminhadas sejam
autenticas utilizando certificado digital X.509.
a opo Diagnostics habilita o trace de mensagens para
os arquivos configurados no input file e output file. O trace ar-
mazena informaes de trafego de mensagens e detalhamento
de exceptions geradas pelo WSE.
Nesse momento, o web service est quase pronto para utilizar
o WSE. Ainda necessrio referenciar as dlls para utilizao das
classes e mtodos que provm a segurana para o web service.
Para isso, clique com o boto direito do mouse novamente no pro-
jeto e selecione Add Reference. Para adicionar a referencia ne-
cessrio localiz-la no caminho de instalao do WSE. Para isso,
clique na opo Browse, localize a dll na pasta C:\Arquivos
de programas\Microsoft WSE\v2.0\Microsoft.Web.Services2.dll e
confirme clicando OK como mostra a .
Pronto, j temos todo o ambiente instalado e configu-
rado para utilizar os servios de segurana do WSE. Vamos
agora iniciar a codificao necessria para suportar e vali-
dar chamadas restritas de WebMethods a partir de aplicaes
consumidoras.
2. Tags para configurao do WSE acrescentadas ao web.
config do web service
<?xmlversion=1.0encoding=utf-8?>
<configuration>
<configSections>
<sectionname=microsoft.web.services2
type=Microsoft.Web.Services2.Configuration.
WebServicesConfiguration,Microsoft.Web.Services2,
Version=2.0.0.0,Culture=neutral,
PublicKeyToken=31bf3856ad364e35/>
</configSections>
<system.web>
2. Habilitando o WSE para o web
service a partir do Visual Studio .NET.
3. Habilitando o WSE para o projeto web service.
wm05.indb 52 3/10/2005 15:49:12
WebMobile 3
.NET Web
Implementando a segurana no web service
Por padro, os web services utilizam a segurana definida pelo
IIS (Internet Information Service). Alm dessa segurana, ne-
cessrio se preocupar com quem deve utilizar e manipular o ser-
vio. Uma das formas de autenticao existentes se d atravs de
tokens de segurana que encapsulam informaes de quem est
acessando o web service. Por meio do token, possvel enviar
dados de identificao como login e senha e validar as informa-
es no web service, assegurando dessa forma a confiabilidade da
aplicao consumidora.
Existem vrias formas de garantir a segurana do seu web
service, so elas:
UsernameTokenManager: Nesse modo, possvel recuperar
o login/senha enviados pela aplicao consumidora e valid-
los de uma forma mais personalizada. Por exemplo, possvel
consultar os dados em uma base de dados, em arquivos XML ou
at mesmo utilizando a segurana padro do ASP.NET atravs
do web.config.
Assinaturas de mtodos: A assinatura de mtodos nas
mensagens tambm pode ser uma excelente forma de validar
o acesso externo ao web service. As assinaturas dos mtodos
so enviados junto aos tokens de segurana, e na chamada do
WebMethod feita a validao das assinaturas.
Tokens X.0: Esse protocolo de assinaturas utiliza a segu-
rana dos certificados X.509 instalados e configurados na mqui-
na (servidor) onde o web service est localizado. Ele possibilita a
criptografia de mensagens enviadas aos web services objetivando
assegurar o transporte da informao enviada nos Tokens.
Nesse artigo, vamos utilizar o mtodo UsernameTokenManager
que o mais utilizado para segurana nos web services. Utili-
zaremos uma validao simblica do login/senha para de-
monstrar o que deve ser feito para utilizar o recurso de
UsernameTokenManager.
Iniciando ento a codificao do mdulo de
segurana, clique com o boto direito do mouse
no projeto WSSeguro, aponte para Add e
selecione Add Class. Nomeie a classe para
Seguranca.cs e clique OK para confirmar.
Codifique a classe conforme a 3.
Como podem observar, o mtodo
AuthenticateToken reescreve o mesmo
mtodo de sua baseclass para que seja
possvel implementar uma validao custo-
mizvel. Atravs do objeto Token (parmetro
do mtodo) possvel recuperar informaes
diversas do token, inclusive login/senha por in-
termdio das propriedades Username e Password.
Coloquei (comentado no mtodo) algumas possveis for-
mas de validao para se customizar a autenticidade da aplica-
o consumidora. Sugeri tambm algumas formas de validao
. Adicionando a referncia para a dll do WSE 2.0.
wm05.indb 53 3/10/2005 15:49:16
5 Edio
3. Classe responsvel pela validao da segurana
usingSystem;
usingMicrosoft.Web.Services2.Security.Tokens;
usingMicrosoft.Web.Services2;
using System.Security.Permissions;
using System.Web.Services.Protocols;
[SecurityPermissionAttribute(SecurityAction.Demand,
Flags=SecurityPermissionFlag.UnmanagedCode)]
publicclassSeguranca: UsernameTokenManager
{
publicSeguranca()
{

}

protectedoverridestringAuthenticateToken(UsernameTokentoken)
{

//token.Username=>retornaousurioenviadopelaaplicaoconsumidora
//token.Password=>retornaasenhaenviadapelaaplicaoconsumidora

//OPESPARAVALIDAO
//1.Validarlogin/senhaembancodedados
//2.Validarlogin/senhaemarquivoXML
//3.ValidarutilizandoosrecursosdeseguranadecredentialsdoASP.NET

//essemtododevetercomoretornoasenhadousurioparaqueoWSEfaaa
//validaocomoquefoienviadopelaaplicaoconsumidora.

//retornaasenhadousurio
returnWM5;
}
publicstaticvoidvalidarLogin(SoapContextcontext)
{
if(context==null)
{
thrownewException(OobjetoContextnofoienviado.);
}
if(context.Security.Tokens.Count==0)
{
thrownewSoapException(
Ostokensdesegurananoforamenviados.,SoapException.ClientFaultCode);
}
}
}
wm05.indb 54 3/10/2005 15:49:17
WebMobile
.NET Web
. Criando o projeto da aplicao que consumir o web service seguro.
como: (1) validao do login/senha atravs de uma tabela de
um banco de dados, (2) em arquivos XML ou at mesmo (3)
utilizando as prprias credenciais do ASP.NET validando o login/
senha no web.config. Deixei ao seu critrio a escolha do mtodo
de validao j que esse no o ponto chave do artigo. Qual-
quer um desses mtodos ou at outros mtodos poderiam ser
utilizados, sempre se preocupando com o retorno (string), que
a senha do usurio para que o WSE faa a validao internamen-
te e permita ou negue o acesso ao mtodo do web service.
Note que na 3 foi necessrio utilizar alguns namespaces.
Sem a utilizao desses, o Visual Studio .NET informar erro de
compilao.
Ainda necessrio configurar o web.config para assumir como
mtodo de autenticao o UsernameTokenManager. Para isso, con-
figure o web.config (ao final do arquivo) conforme mostra a .
Note que na 2 informamos ao web.config sobre a seo mi-
crosoft.web.services2 e agora estamos detalhando o que essa
seo corresponde. O atributo type representa o tipo que ser
convertido para que o TokenManager saiba qual Assembly/Classe
ser executada. Isso quer dizer que ser feito (internamente pelo
WSE) o uso de reflection para instanciar a classe e executar os
seus devidos mtodos em tempo de execuo. O WSE tambm
necessita da XSD (ler 2) disponvel contendo as assinaturas
dos mtodos internos. Caso seu servidor no tenha acesso
internet, baixe o arquivo (.xsd) em http://docs.oasis-open.org/
wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd, salve
o resultado em C:\InetPub\wwwroot\WSSeguro.xsd e no atribu-
to <xmlns:wsse> do securityTokenManager altere o cominho para
http://localhost/WSSeguro.xsd.
Agora que j temos o ambiente completo para a segurana do
web service, vamos consumi-lo.
2. XSD
XSD (XML Schema Definition) define a estrutura e tipo de dados
de documentos XML. Ela define os elementos, atributos e tipagem
dos dados mantendo a compatibilidade com o World Wide Web
Consortium (W3C).
Consumindo o web service seguro
Para demonstrar a segurana ao acesso de web services a par-
tir de aplicaes consumidoras, vamos criar uma aplicao do
tipo Windows Application. Para isso, clique com o boto direito
do mouse na solution do Visual Studio .NET, aponte para Add
e escolha New Project. Na janela de criao do projeto, sele-
cione o Project Type (Visual C# Projects), Templates (Windows
Application) e escolha OK conforme mostra a .
Aps confirmao, o Visual Studio .NET criar o projeto e, au-
tomaticamente, o Formulrio (Form1.cs) inicial.
4. Configurando o web.config para assumir o mtodo UsernameTokenManager
<webServices>
<soapExtensionTypes>
<addtype=Microsoft.Web.Services2.WebServicesExtension,Microsoft.Web.Services2,
Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35priority=1group=0/>
</soapExtensionTypes>
</webServices>
</system.web>
<microsoft.web.services2>
<security>
<securityTokenManagerqname=wsse:UsernameToken
type=WSSeguro.Seguranca,WSSeguro
xmlns:wsse=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd/>
</security>
</microsoft.web.services2>
</configuration>
wm05.indb 55 3/10/2005 15:49:20
5 Edio
Form
Text: Acesso ao Web Service Seguro
Name: frmClientes
BackColor: Control
DataGrid Name: dtgClientes
Boto
Text: Carregar Dados do Web Service Seguro
Name: btCarregar
1. Configurao dos controles.
. Adicionando a referncia para o web service seguro.
. Selecionando o controle
DataGrid.
. Design do formulrio para acessar o web service.
Vamos iniciar adicionando a referncia para o web service. Cli-
que com o boto direito do mouse no Projeto ConsomeWSSeguro
e aponte para Add Web Reference. Na tela que ir abrir, informe
a URL do web service seguro http://localhost/WSSeguro/Service1.
asmx e clique GO. O sistema localizar o mtodo getCustomers()
e solicitar um nome para a referncia do web service. Escolha
WSSeguro e clique no boto Add Reference conforme mostra
a .
Com a referncia adicionada, precisaremos fazer agora o aces-
so ao mtodo para que este retorne o DataSet de Clientes. Para
isso, arraste da ToolBox (veja ) o controle DataGrid para o
Form1, ajuste o layout conforme e ajuste as propriedades
conforme a 1.
Antes de codificar o acesso ao web service, necessrio refe-
renciar o assembly do WSE. Para isso, clique com o boto direito
do mouse novamente no projeto e selecione Add Reference.
Para adicionar a referencia, ne-
cessrio localiz-la no caminho
de instalao do WSE. Para isso,
clique na opo Browse, loca-
lize a dll na pasta C:\Arquivos
de programas\Microsoft WSE\
v2.0\Microsoft.Web.Services2.dll
e confirme clicando OK como
mostra a .
5. Namespaces necessrios para acessar as classes de
autenticao do WSE 2.0
usingSystem;
usingSystem.Drawing;
usingSystem.Collections;
usingSystem.ComponentModel;
usingSystem.Windows.Forms;
usingSystem.Data;
usingMicrosoft.Web.Services2.Security.Tokens;
usingMicrosoft.Web.Services2;
Com a referncia criada, importe os namespaces necessrios no
Formulrio (Form1.cs) conforme mostra a .
Continuando a codificao, clique duas vezes no boto btCarregar
e codifique o evento Click como mostra a .
Note que na estamos criando uma instncia do web ser-
vice a partir da classe Service1Wse. Essa classe foi criada aps
habilitar os servios do WSE no web service. Ela disponibiliza os
mtodos necessrios para incluso do Token no Context do web
service. Em seguida criamos um objeto do tipo UsernameToken,
que foi instanciado enviando login/senha com a opo SendHa-
shed. Esse terceiro parmetro do construtor da classe Userna-
meToken representa a forma com que os dados sero enviados
ao web service, no caso utilizado a senha ser enviada utilizando
o algoritmo de criptografia Hash . Em seguida invocamos o
mtodo Add da collection Tokens para envio do token ins-
wm05.indb 56 3/10/2005 15:49:23
WebMobile
.NET Web
. Listagem de clientes aps validao dos tokens de segurana.
Andrey Sanches (andrey.sanches@gmail.com)
Analista de Sistemas na Atos Origin Brasil
SP (www.atosorigin.com.br) e trabalha com
desenvolvimento de sistemas na tecnologia
.NET desde sua verso beta. MCP (Microsoft
Certifeld Professional), auxilia a comunidade .net como
Co-lder no grupo de usurios codifcando.net SP
(www.codicando.net) , palestrante Microsoft em diversos
eventos do meio, escreve artigos parar diversos sites/revistas
como Portal Web Mobile e MSDN Magazine. Ele
acredita que a segurana dos aplicativos deve ser
uma atribuio no somente dos profssionais de
infra-estrutura, mas tambm um cuidado especial
dos desenvolvedores de software. The Spoke:
br.thespoke.net/MyBlog/andreysanches/MyBlog.aspx.
6. Preenchendo o DataGrid a partir do acesso seguro ao web service
privatevoidbtClientes_Click(objectsender,System.EventArgse)
{
//instnciaoWebService,utilizandoaclasseService1Wse
WSSeguro.Service1WsewsSeguro=newConsomeWSSeguro.WSSeguro.Service1Wse();

//criaumobjetoparaenviodoToken
UsernameTokentok=newUsernameToken(andreysanches,WM5,PasswordOption.SendHashed);
//enviaparaowebservicesegurootokenparavalidaoatravsdoSoapContextdoWebService
wsSeguro.RequestSoapContext.Security.Tokens.Add(tok);

//fazachamadadomtodopararetornodosclientes
DataSetmyCustomers=wsSeguro.getCustomers();
//carregaagridcomosdadosseousurio(tokenenviadoevalidado)tempermissopara
//acessaroWebService
dtgClientes.DataSource=myCustomers.Tables[0];
}
10. Erro (exception) acessando o web service sem
enviar os tokens de segurana.
tanciado anteriormente. Nesse momento, estamos incluindo o
token no Context da mensagem para o web service. Depois, s
necessrio fazer a chamada para o WebMethod corresponde e
retornar a listagem de Clientes em formato DataSet, que por sua
vez ser associada ao DataSource do DataGrid. A mostra a
listagem de Clientes aps validao do token. J a 10 mostra
a exception gerada a partir de uma aplicao tentando acessar o
web service sem enviar os tokens de segurana.
Concluso
Esse artigo teve como objetivo demonstrar algumas
das tcnicas de segurana com web services trabalhan-
do especificamente com o WSE 2.0. de suma importn-
cia a preocupao com segurana nas transaes utilizando
web services.
wm05.indb 57 3/10/2005 15:49:26
5 Edio
ASP.NET
Aumentando
a performance
de suas
aplicaes
web
N
esta ltima parte de uma srie onde estamos discutindo um
importante tema no desenvolvimento web (performance),
vamos conhecer os diversos objetos disponveis no ASP.NET
que possibilitam o gerenciamento de estado e sesso, incluindo
Session, ViewState e Cache. No final deste artigo, tambm vere-
mos um importante recurso do ASP.NET que permite a definio
de um servidor de estado (State Server) que poder aumentar con-
sideravelmente a escalabilidade e disponibilidade de suas solu-
es web.
Vou supor aqui que o leitor no possui experincia ainda com
o tratamento de sesso em aplicaes web, de forma que iniciare-
mos pelo bsico, com um exemplo bem simples. Aproveitaremos
para examinar o modelo de execuo do ASP.NET e porque preci-
samos gerenciar estado/sesso nesse contexto. Alm disso, voc
aprender quando deve utilizar cada um dos objetos disponveis
no ASP.NET de acordo com o problema proposto.
Windows Forms (Desktop) x ASP.NET Web Forms (Web)
Para entendermos o funcionamento bsico do porqu de existir
o tratamento de estado/sesso em aplicaes ASP.NET (e aplica-
es web como um todo), vamos fazer um exemplo prtico e em
cima dele aplicar as tcnicas disponveis. Esta ser uma aplica-
o que frequentemente utilizo ao iniciar palestras e treinamen-
tos sobre desenvolvimento ASP.NET, pois demonstra claramente
a quebra de paradigma Windows Forms vs. Web e o modelo de
execuo do ASP.NET.
Esse entendimento inicial funda-
mental para que possamos prosse-
guir nossos estudos neste artigo,
principalmente se voc est vindo
(leia-se migrando) de um am-
biente desktop. Caso esteja apenas
iniciando no desenvolvimento web,
importantssimo que compreenda
desde o princpio como o ASP.NET geren-
cia requisies HTTP e seu modelo de execuo,
para evitar problemas futuros.
Para comear, vamos criar uma aplicao
Windows Forms tpica. A seguir, vamos fazer exa-
tamente a mesma aplicao com ASP.NET Web Forms,
usando os mesmos controles e o mesmo cdigo, e
voc ver que, apesar dela funcionar perfeitamente em
ambiente Windows, no funciona em ambiente web.
Voc pode utilizar o Visual Studio .NET 2003 para criar
estes exemplos, vou tomar o cuidado de usar apenas o
recursos disponveis no .NET Framework 1.1 (apesar de
que teremos grandes novidades relacionadas ao assunto
na verso 2.0, abordadas em futuras oportunidades). Aqui
vou utilizar o Visual C# 2005 Express Edition Beta 2 para criar
a aplicao Windows Forms e o Visual Web Developer 2005 Express
Edition Beta 2 para criar a aplicao web.
Parte III Session,
ViewState, Cache e
State Server
por Guinter Pauli
wm05.indb 58 3/10/2005 15:49:27
WebMobile
.NET Web
No Visual C# Express clique em File>New Project e a seguir es-
colha a opo Windows Application ( 1). D um nome para a
aplicao usando a opo Name.
No formulrio principal, a partir da Toolbox, coloque dois con-
troles TextBox e dois Buttons, ajustando-os conforme mostrado
na 2.
O cdigo para o evento Click de cada um dos botes mostrado
na 1. Observe que declaramos uma varivel privada chamada
str, do tipo string. O cdigo simples: quando o boto Gravar for
clicado, o valor digitado no TextBox1 guardado em str. A seguir,
quando o segundo boto (Ler) for clicado, recuperamos o valor
armazenado em memria (varivel str) e exibimos no TextBox2.
Execute a aplicao clicando em ou pressionando F5. Digite
um valor no primeiro TextBox, clique em Gravar e a seguir em Ler.
O texto ser mostrado agora em TextBox2, tendo passado pela
varivel str durante o pressionamento dos botes ( 3).
Vamos agora construir a verso web da mesma aplicao.
No Visual Web Developer 2005 Express clique em File>New Web
Site. Escolha uma localizao HTTP para o Web Site (opo
Location) e linguagem como C# (opo Language). D o endereo
http://localhost/MyWebSite para a aplicao (veja a ).
2. Formulrio principal da aplicao Windows Forms.
3. Formulrio principal da aplicao
Windows Forms.
1. Criando uma aplicao Windows Forms no Visual C# 2005 Express Edition Beta 2.
. Criando uma aplicao ASP.NET no Visual Web Developer 2005 Express
Edition Beta 2.
Observe que, apesar de ser possvel utilizar o servidor web inte-
grado, usaremos o IIS para nossos testes.
Na parte inferior do editor, clique na aba Design e a partir da
Toolbox arraste para o formulrio dois controles TextBox e dois
Buttons. Ajuste-os conforme mostrado na .
Utilize a 2 (que anlogo ao cdigo Desktop da 1) para
codificar o evento Click de ambos os Buttons, declarando tambm
a varivel privada str do tipo string.
Execute a aplicao clicando em ou pressionando F5. Digite
um valor no primeiro TextBox, clique em Gravar e a seguir em Ler.
Se tudo deu certo (ou seria errado?), o texto no ser mostrado
no TextBox2, conforme comprova a .
Tomando por base esse exemplo, podemos agora co-
nhecer um pouco sobre o modelo de execuo ASP.NET e
a seguir fazer uso das tcnicas de tratamento de sesso,
cache e estado.
Modelo de execuo ASP.NET
e aplicaes state-less
A web um ambiente state-less. Cada requisio
tratada pelo servidor ASP.NET como se fosse uma
nova solicitao, de forma que nada armazenado
na memria do servidor aps o envio da pgina HTML
para o browser. Isso feito por uma questo bvia:
performance.
Lembro-me da poca que comecei a desenvolver para
web, ainda nos tempos do CGI (lendo variveis de am-
biente e enviando HTML dinmico para o browser com
wm05.indb 59 3/10/2005 15:49:32
0 5 Edio
O modelo de execuo de aplicaes Web / ASP.NET bastante di-
ferente do modelo desktop e voc precisa estar ciente das limitaes
impostas pelo HTML e HTTP. Por exemplo, como voc gerencia requi-
sies e faz tratamento de estado/sesso em uma aplicao Windows
Forms? Espere a, ns no precisamos fazer isso em ambiente Desktop!
Esse um problema que s existe em ambiente web.
O ASP.NET precisa liberar recursos aps o processamento
de cada requisio HTTP, da o problema da quebra de para-
digma conforme comprovamos no exemplo anterior. Algumas
vezes precisamos armazenar um objeto no servidor para que
possa ser recuperado em futuras requisies. O ASP.NET ofe-
rece vrios recursos para armazenar dados em cache e sesso,
como veremos a partir de agora em nosso exemplo. sua res-
ponsabilidade detectar qual o melhor que se adapta ao proble-
ma que voc precisa resolver.
Usando Session
muito simples armazenar um objeto em sesso usando
ASP.NET atravs do objeto Session. As informaes ficaro
persistidas na memria do servidor e so exclusivas para cada
usurio. Ou seja, se guardarmos uma string ou um DataSet em
sesso, apenas o usurio que acessou a pgina poder utilizar
essas informaes.
Session bastante usado, por exemplo, em aplicaes de
loja virtual, como carrinhos de compra. Cada usurio tem sua
prpria lista de produtos, que fica armazenada na memria do
servidor at que a compra seja finalizada. Como a sesso
nica para cada usurio, uma pessoa no pode ter acesso aos
produtos da outra, claro. As informaes so persistidas entre
requisies.
Quando o usurio envia uma nova requisio HTTP (adiciona
um novo produto ao carrinho, por exemplo), o ASP.NET deve
ser capaz de buscar no servidor a respectiva sesso ativa para
aquele usurio. Para isso, no momento que o usurio inicia uma
sesso no servidor, o ASP.NET envia um cookie para o browser,
. Aplicao web no funciona como a aplicao desktop.
1. Evento Click dos botes.
privatestringstr;
privatevoidbtnGravar_Click(objectsender,EventArgs
e)
{
str=textBox1.Text;
}
privatevoidbtnLer_Click(objectsender,EventArgse)
{
textBox2.Text=str;
}
2. Evento Click dos botes.
privatestringstr;
protectedvoidButton1_Click(objectsender,EventArgse)
{
str=TextBox1.Text;
}
protectedvoidButton2_Click(objectsender,EventArgse)
{
TextBox2.Text=str;
}
. Formulrio principal da aplicao ASP.NET Web Forms.
WriteLn). Cada usurio que conectava recebia um novo proces-
so no servidor. Sem dvida essa no uma boa soluo quan-
do precisamos garantir a escalabilidade mesmo com milhares de
conexes simultneas. Por que o modelo state-less resolve isso?
Experimente abrir 10 mil instncias de uma aplicao qualquer na
sua mquina e voc entender o que eu quero dizer.
wm05.indb 60 3/10/2005 15:49:34
WebMobile 1
.NET Web
chamado _ASP.NET_SessionID, que enviado de volta ao servidor
a cada nova requisio, garantindo que todas as solicitaes HTTP
vindas do mesmo usurio sejam refletidas na sua respectiva sesso
(em uma operao chamada tracking). Um SessionID basica-
mente uma chave nica que identifica a sesso no servidor, como
jg0cia45ulaqas3uyero3za2.
Em nosso exemplo, vamos adaptar o cdigo para que guarde
a varivel str em memria (Session), de forma que possamos re-
cuperar seu valor entre requisies. Veja como esse processo
simples na 3.
Execute novamente a aplicao, digite um valor no primeiro
TextBox, clique no boto Gravar e a seguir no boto Ler. Observe
que o valor ser agora mostrado no segundo TextBox, pois foi
mantido em sesso. Com um pouco de cdigo e quase sem esfor-
o, conseguimos resolver o problema imposto pela mudana do
paradigma Desktop x Web, graas ao ASP.NET.
Para comprovar que cada usurio possui sua prpria sesso no
servidor, faa um teste em nosso exemplo: execute a aplicao,
coloque um valor em sesso (boto Gravar) e abra outro browser,
acessando a mesma URL. Clique apenas no boto Ler e observe
que nada acontece, pois um usurio no pode acessar a sesso
do outro usurio.
Trace
Vamos fazer um teste para verificar como essa varivel foi colo-
cada em sesso. Abra o arquivo ASPX e adicione o atributo Trace =
true na diretiva Page, como mostrado a seguir. Voc pode fazer
o mesmo selecionando o objeto Document na janela de proprieda-
des e ajustando o atributo diretamente.
<%@PageLanguage=C#AutoEventWireup=trueCodeFile=Default.aspx.cs
Inherits=_DefaultTrace=true%>
Execute novamente a aplicao e coloque a varivel na sesso.
Observe que o ASP.NET gera informaes completas de Trace dire-
tamente na pgina, como: uso de memria, controles, cabealhos
HTTP, variveis de ambiente etc. Isso ideal para monitorarmos
uma aplicao ASP.NET em produo quando no temos a disposi-
o a IDE do VS, Debugger etc. A mostra o SessionId gerado
para nossa sesso e tambm a varivel str, do tipo System.
String, com o valor Ol Mundo.
claro, este exemplo simples, apenas estamos colocando
uma string em sesso. Mas nada impede que voc coloque outros
objetos em memria, como DataSets. A sintaxe exatamente a
mesma, veja como simples:
Session[MeuDataSet]=DataSet1;
Se voc lembrar, fizemos vrios exemplos nas partes anteriores
deste artigo, onde colocamos informaes do banco de dados em
memria (usando DataSets) para otimizar consultas.
Sesses Cookieless
Como sabemos, alguns browsers no suportam cookies.
Com isso, o ASP.NET no ser capaz de fazer o tracking do
SessionId. Nesse caso, voc pode facilmente configurar o ele-
mento SessionState do Web.Config indicando que no queremos
usar cookies, como mostrado na . Para abrir esse arquivo,
basta dar um duplo clique sobre ele no Solution Explorer.
Voc pode usar o Intellisense para construir elementos e
atributos do Web.Config, bastando pressionar Ctrl+Space.
Aqui estamos configurando o atributo cookieless como true, o
que diz ao ASP.NET para no fazer o tracking da sesso atravs
de cookies. Execute a aplicao novamente e veja que agora o
SessionId ser passado na prpria URL gerada, como no exemplo
a seguir:
http://localhost/MyWebSite/(S(shpxub45qn5m3gabokylqgbk))/
Default.aspx
Observe tambm que configuramos o timeout da sesso para
3. Colocando variveis em sesso.
protectedvoidButton1_Click(objectsender,EventArgse)
{
Session[str]=TextBox1.Text;
}
protectedvoidButton2_Click(objectsender,EventArgse)
{
TextBox2.Text=Session[str]asstring;
{
. Trace de pgina indicando informaes sobre a sesso.
wm05.indb 61 3/10/2005 15:49:37
2 5 Edio
10 segundos. Ou seja, se o usurio no fizer novas re-
quisies HTTP para servidor nesse perodo de tempo,
o ASP.NET libera os recursos alocados, garantido a per-
formance.
Usando ViewState
Lembre-se que quando armazenamos variveis em
sesso, estamos fazendo uso de recursos do servidor. Se uma apli-
cao ASP.NET vai ter uma grande demanda de usurios, alocar
muitos objetos em memria pode degradar a performance.
Como alternativa ao Session, para armazenar variveis que
precisam ser persistidas entre requisies, podemos fazer uso do
ViewState. O ViewState j utilizado por controles ASP.NET para
automaticamente manterem seu estado entre requisies HTTP,
mas tambm podemos us-lo para guardar nossos prprios obje-
tos. Veja na como simples adaptar nosso exemplo para usar
o ViewState, basta trocar Session por ViewState.
Execute a aplicao e faa um teste. Observe que o valor pode
ser gravado e recuperado, pois persistiu entre requisies, seme-
lhante ao que acontecia no exemplo com Session. A grande dife-
rena que nossa varivel no ficou armazenada na memria do
servidor, ela foi enviada ao browser juntamente com o ViewState
dos controles ASP.NET.
Para ver o ViewState em ao, aps a pgina ser carrega no
browser e um valor ser guardado (boto Gravar), no Internet
Explorer clique em Exibir>Cdigo Fonte ( ). Observe que temos
um Hidden Field chamado __VIEWSTATE, que contm informa-
es sobre o estado dos controles e tambm de nossa varivel str.
Quando a pgina for submetida de volta ao servidor (postback),
o ASP.NET se encarrega de recuperar o estado de nossa pgina e
assim podemos normalmente obter o valor de str, como se fosse
uma aplicao desktop.
Vale lembrar que o ViewState feito por pgina. Ou seja, se voc
precisar manter o estado de uma varivel e recuperar em outro
formulrio, utilize outro meio, como Session ou mesmo Cookies.
Usando Cache
Em algumas situaes, no entanto, necessrio que todos os
usurios enxerguem a mesma varivel no servidor. Imagine por
exemplo, que quisssemos colocar um resultset em memria, atra-
vs de um DataSet, para otimizar consultas ao banco de dados.
Por exemplo, listar em um DropDownList os nomes dos depar-
tamentos da empresa. Usando Session, cada usurio teria uma
cpia do DataSet em memria, o que afetaria a performance da
soluo.
Nesse caso, voc pode fazer uso do objeto Cache. Veja como
simples adaptar nosso exemplo para fazer uso desse objeto ( ).
Basta substituir o ViewState por Cache.
Para comprovar que todos os usurios acessam o mesmo objeto
Cache (diferente de Session), execute a aplicao e grave um valor
(boto Gravar). Abra outro browser, acessando a mesma URL e
sem gravar nada clique no boto Ler (veja o resultado na ).
O usurio ser capaz de acessar a varivel armazenada pelo outro
usurio (ler 1).
1. Cache e expirao
O ASP.NET tambm possibilita criar mecanismos de dependncia de cache
e expirao. Para mais informaes, consulte o endereo: msdn.microsoft.
com/msdnmag/issues/04/07/cuttingedge/default.aspx.
Uma grande novidade no ASP.NET 2.0 que agora podemos vincular
uma cache a uma tabela do banco, por exemplo, para ser refeita
quando uma informao modificada. Apesar de ser bvio, isso no
era suportado diretamente na verso 1.1, existia apenas dependncia
de arquivo e outras formas mais rudimentares.
State Server
Como j comentamos, quando guardamos uma varivel em ses-
so (objeto Session), ela fica armazenada na memria do servidor
web. Ou seja, as informaes residem no mesmo processo do ser-
vidor ASP.NET.
4. Sesses Cookieless.
...
<system.web>
<sessionState
cookieless=true
timeout=10
/>
...
5. Usando ViewState.
protectedvoidButton1_Click(objectsender,EventArgse)
{
ViewState[str]=TextBox1.Text;
}
protectedvoidButton2_Click(objectsender,EventArgse)
{
TextBox2.Text=ViewState[str]asstring;
}
. Usando ViewState.
wm05.indb 62 3/10/2005 15:49:39
WebMobile 3
.NET Web
Para comprovar que isso realmente verdade, vamos fazer um
teste: adapte o cdigo do nosso exemplo para usar novamen-
te o objeto Session (apenas troque o Cache por Session no
cdigo). Agora execute a aplicao e coloque uma varivel em
sesso (boto Gravar). Abra o gerenciador de tarefa de Windows,
localize o processo aspnet_wp.exe e finalize-o. Automaticamente,
o ASP.NET vai levantar o processo novamente. Agora clique no
boto Ler e comprove que nossa varivel que estava em sesso
foi perdida.
Ou seja, se por algum motivo o servidor ou esse proces-
so for reiniciado, ou acontecer um crash no servidor, to-
das as informaes guardadas para cada usurio em sesso
sero perdidas. Alm disso, lembre-se que o ASP.NET reini-
cia a aplicao quando modificamos alguma configurao
no Web.Config (procedimento que muito comum de ser
feito em servidores de produo). Por exemplo, altere o
6. Usando Cache.
protectedvoidButton1_Click(
objectsender,EventArgse)
{
Cache[str]=TextBox1.Text;
}
protectedvoidButton2_Click(
objectsender,EventArgse)
{
TextBox2.Text=Cache[str]asstring;
}
7. Configurando o StateServer.
<sessionState
mode=StateServer
stateConnectionString=
tcpip=127.0.0.1:42424
/>
timeout da sesso para 20 e comprove que o servidor derruba
todas as sesses!
Imagine que voc o desenvolvedor de uma loja virtual de
uma grande empresa. Calcule o tamanho do prejuzo se, de uma
hora para outra, todos os usurios conectados fazendo compras
tiverem seus carrinhos esvaziados por um problema ou ajuste de
configurao no sistema!
O ASP.NET resolve esse problema de forma bastante elegante e
simples. Podemos instruir o ASP.NET para que no armazene infor-
maes de sesso no processo aspnet_wp.exe, mas em um proces-
so dedicado. Para fazer um teste, altere o elemento SessionState
do Web.Config como mostrado na .
Aqui indicamos no atributo mode que faremos uso de um
StateServer. O atributo stateConnectionString indica o endereo
do servidor de estado. Abra o Painel de Controle>Ferramentas
Administrativas>Servios. Localize o servio ASP.NET State Service
e inicie-o ( 10).
Agora repita o mesmo teste que fizemos anteriormente. Exe-
cute a aplicao, coloque uma varivel em sesso, derrube o
aspnet_wp.exe e volte ao browser. Clicando em Ler, verificamos
. Objetos colocados em Cache podem ser acessados por outros usurios.
wm05.indb 63 3/10/2005 15:49:43
5 Edio
que o valor da varivel da sesso no foi perdido, pois as sesses
residem agora em um processo diferente do usado pelo servidor
web. Voc pode verificar esse processo em execuo atravs do ge-
renciador de tarefas do Windows, ele se chama aspnet_state.exe.
Um outro motivo para voc usar um servidor de estado em
outro processo (out-of-process) quando a soluo vai utilizar
mltiplos servidores ASP.NET para a mesma aplicao (Web
Farms), por exemplo, em grandes sites de comrcio eletrnico.
Em um ambiente como esse, cada requisio pode ser manipulada
por um servidor diferente para aumento de performance.
Por exemplo, considere trs servidores chamados Server1,
Server2 e Server3 sendo utilizados em uma empresa para atender
uma demanda grande de usurios de uma aplicao de comrcio
eletrnico. Um usurio acessa aplicao e direcionado para o
Server1. Ele compra um produto e coloca no carrinho (sesso). Ao
comprar o segundo produto, a requisio pode ser tratada pelo
segundo servidor (Server2), para efeitos de balanceamento de car-
ga e performance. Como cada servidor armazena informaes de
sesso em seu prprio processo, cada produto vai residir em um
servidor e com isso o carrinho vai falhar.
A soluo selecionar um servidor dedicado e orientar todos os
servidores para usarem o mesmo StateServer, que pode ser uma m-
quina exclusiva, com mais memria, por exemplo. Para isso, basta
apontar o stateConnectionString para o endereo IP do StateServer.
Sesses em banco de dados
At agora quando falamos em sesso estamos obrigatoriamente
falando de memria. Uma alternativa usar o SQL Server para
persistir informaes de sesso, que pode garantir que mesmo
havendo a queda do servidor, informaes fiquem persistidas. Essa
tcnica tambm pode ser usada para centralizar o State Server.
Em nosso exemplo, modifique o Web.Config como mostrado na .
Com isso, dizemos ao ASP.NET para usar o SQL Server como
servidor de estado, residindo no endereo especificado em
sqlConnectionString, onde tambm preciso informar as creden-
ciais de acesso e outras informaes necessrias conexo.
A seguir, precisamos configurar o SQL Server para armazenar as
informaes de sesso. Para isso, basta executar o seguinte script
no Query Analyzer:
10. Iniciando o ASP.NET State Service.
8. Utilizando o SQL Server para
persistir informaes de sesso.
<sessionState
mode=SQLServer
sqlConnectionString=
datasource=127.0.0.1;userid=sa;password=
cookieless=false
timeout=20
/>
C:\WINDOWS\Microsoft.NET\Framework\(versao)\
InstallSqlState.sql
Voc pode agora executar normalmente nossa apli-
cao de teste e verificar que as informaes de ses-
so sero armazenadas no mais em memria, mas no
banco de dados.
Concluses
Neste artigo conhecemos um pouco sobre os objetos
envolvidos no tratamento e gerenciamento de sesso e estado.
Atravs de um exemplo simples e prtico, fizemos um tour pelos
recursos oferecidos pelo ASP.NET. Sabendo utilizar esses objetos
com sabedoria e identificando qual deles usar em determinada
situao, vai com certeza garantir a performance de sua soluo
web, o retorno do seu investimento e a satisfao do seu cliente
(e dos usurios!). Um grande abrao e at a prxima!
Guinther Pauli autor de mais de 100
artigos publicados e do livro Delphi
Programao para Banco de Dados e Web.
Bacharel em Sistemas de Informao pelo Centro
Universitrio Franciscano (Unifra, Santa Maria
RS). desenvolvedor 5 estrelas Microsoft, MCP,
MCAD e MCSD.NET. Detm quatro certifcaes ofciais Borland:
Delphi Advanced pela Borland dos Estados Unidos, Delphi Web
Development Certifed, Kylix Product Certifed e Delphi Product
Certifed. J ministrou palestras para mais de 5 mil pessoas em
todo o pas. Editor Geral da revista ClubeDelphi (www.devmedia.
com.br/clubedelphi) e Editor Tcnico da Revista Web
Mobile Magazine (www.devmedia.com.br/webmobile).
Colunista dos portais ClubeDelphi, MSDN Magazine
e Web Mobile Magazine. Pode ser contatado pelos
endereos guinther_pauli@hotmail.com ou guinther@
devmedia.com.br.
wm05.indb 64 3/10/2005 15:49:46
WebMobile
.NET Web
wm05.indb 65 3/10/2005 15:49:48
5 Edio
Desenvolvendo
aplicaes
para Pocket PC
e Smartphone
para Windows
Mobile .0 no
Visual Studio
200
A
Microsoft lanou recentemente a verso 5.0 do seu sistema
operacional para dispositivos mveis, Windows Mobile, com
diversos novos recursos para esses dispositivos.
Cada vez mais presentes no mercado corporativo, a utilizao
de dispositivos mveis j uma realidade, e some-se a isso um
avano cada vez maior de hardware e software. Em pouco tempo
esses dispositivos esto mais acessveis e com recursos muito
interessantes beneficiando e flexibilizando as aplicaes. Desen-
volver aplicaes para Pocket PC e Smartphones pode se tornar
um grande diferencial do seu produto.
Para o desenvolvimento de aplicaes para a nova verso deste
sistema operacional, necessria a utilizao do Visual Studio
2005, que a ferramenta de desenvolvimento da Microsoft para
desenvolvimento de aplicaes na plataforma .Net (que ter a
verso final lanada brevemente).
Como forma de descrevemos a utilizao desta ferramenta
para desenvolvimento de aplicaes utilizando o Pocket PC ou
o Smartphone, desenvolveremos neste artigo um sistema para
controle de reserva em um restaurante, onde indicaremos a data
e horrio desejados, e o sistema ser responsvel pelo gerencia-
mento dessas reservas.
Ao final do artigo ficar muito claro a facilidade e produtivi-
dade que temos disponvel hoje com o Visual Studio 2005 para
o desenvolvimento de aplicaes para dispositivos mveis. Vale
destacar a utilizao de duas linguagens de programao: Visual
Basic .Net e C#.
Ambiente para desenvolvimento das aplicaes
Para iniciarmos o desenvolvimento de aplicaes para o Windows
Mobile 5.0, necessrio que o Visual Studio 2005 (beta 2) e o
pacote complementar (SDK) para desenvolvimento no Windows
Mobile 5.0 sejam instalados. Para baixar o pacote, visite o site:
http://msdn.microsoft.com/mobility/windowsmobile/downloads/
default.aspx.
Aps a instalao deste pacote, sero adicionadas no Visual
Studio 2005 diversas funcionalidades onde a produtividade e no-
vos controles tiveram uma ateno maior, alm de um acesso
fcil a recursos como: acessar os dados dos contatos do Outlook
Mobile, controle sobre comandos telefnicos, entre outras APIs
disponveis.
Estudo de caso
Ao longo do artigo, utilizaremos uma aplicao para controle de
reservas de restaurantes como estudo de caso para demonstrao
da utilizao do Visual Studio 2005 durante o desenvolvimento
de aplicaes para Windows Mobile 5.0. Este sistema ser res-
ponsvel pelo gerenciamento de restaurantes, novas reservas e,
cancelamento de reservas; para flexibilizar e organizar as filas
em restaurantes. Essa aplicao utilizar Pocket PC ou Smarphone
como interface com o usurio e toda a regra de negcio estar
centralizada em um nico local.
por Alexandre Fernandes Chaud Tarifa
e Jos Antonio Leal de Farias
wm05.indb 66 3/10/2005 15:49:51
WebMobile
.NET Mobile
A aplicao ser baseada em um centralizador da regra de ne-
gcio, neste caso um web service utilizando Visual Basic .Net.
A opo por web service a melhor neste caso, pois a regra
de negcio ficar disponvel na web e duas aplicaes distintas
(Pocket PC e Smartphone) vo utilizar esses recursos. Caso exista
a necessidade, esse servio tambm poder ser consumido por
uma aplicao Web (Asp.Net) ou Windows Forms. As aplicaes
Pocket PC e Smartphone sero desenvolvidas em C#.
Construindo a aplicao
O primeiro passo a ser executado neste exemplo ser a criao
do seu banco de dados. Isto no ser detalhado por no ser o foco
principal do artigo. Com isso, crie as tabelas no SQL Server 2000
(ou outro de sua preferncia), conforme apresentado na 1.
Toda a manipulao dos dados com os comandos insert, update,
delete e select estaro centralizadas no web service. Aps a cria-
o do banco de dados, podemos iniciar o desenvolvimento do
web service. Para isso, abra o Visual Studio 2005 e clique em
File New Web Site no menu. Uma nova janela de seleo de
projeto aberta ( 2), selecione o tipo de aplicao Asp.Net
Web Service. Especifique o nome WSFuraFila e a linguagem Visual
Basic.Net, em seguida clique em OK.
Aps a criao do projeto, mostraremos agora um novo recurso
disponibilizado pelo Visual Studio 2005. uma nova forma de
projetar um web service, onde tudo o que feito no diagrama
transformado automaticamente em cdigo.
Para isso, na janela Solution Explorer (Ctrl + Alt + L), que a
janela que organiza todos os elementos do projeto, clique sobre
o cone View Class Diagram. O diagrama aberto j com o service
criado. O prximo passo ser projetar a estrutura do web service.
Utilizando a janela Class Detail ( 3), configuramos todos os
mtodos contidos no web service alterando suas propriedades.
O interessante deste novo recurso que alm dos mtodos, j
possvel criar todos os parmetros esperados para esses mtodos.
Para o nosso estudo de caso, crie os mtodos e parmetros con-
forme a . Esses mtodos sero utilizados durante a criao da
aplicao, sendo responsveis pela regra de negcio do sistema,
conforme citado na seo Estudo de Caso.
Com o diagrama montado, no Solution Explorer abra a pasta
App_Code e d um duplo clique em Service.vb. Note que todo o
modelo j est codificado, ou seja, o nico trabalho que restou
ser o de implementar os mtodos.
1. Tabelas do sistema.
2. Criao de um novo projeto.
3. Diagrama com todos os mtodos do web ser vice.
. Todos os parmetros dos mtodos do web service.
wm05.indb 67 3/10/2005 15:49:55
5 Edio
1. Referncias aos namespaces
ImportsSystem.Web
ImportsSystem.Web.Services
ImportsSystem.Web.Services.Protocols
ImportsSystem.Data.SqlClient
2. String de conexo
DimStringConexaoAsString=Integrated
Security=SSPI;PersistSecurityInfo=False;InitialCatalog=
dbRestaurante;DataSource=SeuDataSource
No topo da classe, adicione todas as referncias necessrias.
Por default, somente alguns namespaces esto adicionados
classe. Conforme a necessidade, adicionamos a referncia aos
namespaces ( 1).
Declare uma varivel para receber a string de conexo. Esta
ser responsvel pela configurao da conexo com o banco de
dados, conforme descrito na 2, para centralizar em um nico
local o valor que ser utilizado em toda a aplicao (ler 1).
1. String de conexo no arquivo Web Config.
Quando a aplicao for colocada em produo ou em um servidor
para testes, adicione a string de conexo no arquivo Web Config, que
um arquivo de configurao criado automaticamente pelo Visual
Studio 2005 dentro do diretrio de sua aplicao, onde somente a
aplicao consegue acessar os valores. Existem diversas regras de
segurana para o armazenamento de valores no pblicos. Verifique
dentro de sua infra-estrutura se uma prtica segura colocar valores
pblicos em arquivo de configurao, o ideal colocar valores
criptografados.
Todos os mtodos acessam informaes no banco de dados. Os
principais mtodos sero mostrados e comentados no artigo. Para
ter o cdigo completo faa o download da aplicao no portal
Web Mobile (www.portalwebmobile.com.br).
A 3 descreve o mtodo FazReserva, que responsvel por
inserir os valores de uma reserva no banco de dados, alm de
retornar todas as reservas j existentes do usurio passado pelo
parmetro (verificar detalhes nos comentrios do cdigo).
J o mtodo CancelaReserva
( ) cancela uma reserva
especificada pelo parmetro
e faz o delete no banco de
dados (verificar detalhes nos
comentrios do cdigo).
Agora que voc j tem o
servio implementado,
hora de torn-lo acessvel
atravs de um dispositivo
mvel. Neste artigo voc
ir fazer duas verses do
mesmo programa, uma
para PocketPC e ou-
tra para Smartphone.
Comece com a do
PocketPC. No Visual
Studio 2005, sele-
cione o menu File/
New/Project e a
janela da se
abrir.
O cdigo exibido neste artigo feito em C#, mas no h di-
ficuldade em faz-lo utilizando o VB.NET, se preferir. Selecione
Visual C#, e em Smart Device selecione PocketPC Magneto
(Magneto o codinome do Windows Mobile 5.0). Selecione
Device Application, informe o nome do projeto (FuraFilaPPC)
e em seguida clique OK (ver ). O Visual Studio ficar com
a aparncia apresentada na .
O primeiro passo adicionar a referncia ao web service. No
Solution Explorer, clique com o boto direito do mouse sobre
References Add Web References. Na URL digite o caminho do
web service: http://(IP Local):1147/FuraFila/Service.asmx (o ar-
quivo Service.asmx se encontra dentro do diretrio de seu proje-
to). Note que o servidor web de desenvolvimento que vem junto
com o Visual Studio 2005 executado em uma porta diferente da
do IIS. Na Web Reference Name coloque ServicoRemoto e clique
em Add Reference, como na .
Como o objetivo dessa aplicao apenas fazer a reserva, no
seu formulrio ser preciso somente um DataGrid para visualizar
os restaurantes disponveis, um controle para a seleo de data,
um para a hora e outro para dizer de quanto tempo ser a reserva.
Inicialmente, selecione o formulrio e troque a propriedade Text
para FuraFila Mobile.
Por default, um menu j vem adicionado no formulrio, selecio-
ne o controle e crie um menu simples, conforme a .
Note que os menus do PocketPC agora so extremamente pareci-
dos com os menus da verso do Windows Mobile para Smartphone.
Essa apenas uma das mudanas mais visveis desta nova verso
do Windows Mobile que procura ter a mesma usabilidade, seja em
PocketPCs, seja em Smartphones.
Adicione agora um DataGrid, um DateTimePicker, um Combobox,
um PictureBox e um NumericUpDown e alguns Labels, de forma
que a interface fique como a da .
Renomeie o DateTimerPicker para dtpData, o Combobox
para cbbHora, o DataGrid para dgdRestaurantes e o
NumericUpDown para nudDuracao. O DateTimePicker deve ter a
propriedade DateFormat setado para Short. Adicione algumas ho-
ras nos itens do ComboBox (02:00,03:00, etc). O PictureBox
wm05.indb 68 3/10/2005 15:49:59
WebMobile
.NET Mobile
3. Mtodo FazReserva
<WebMethod()>_
PublicFunctionFazReserva(ByValInicioAsDate,ByVal
FimAsDate,ByValidRestauranteAsInteger,ByValidUsuario
AsInteger)AsData.DataSet
CriaumaConexocomoBancodeDados
DimConnAsNewSqlConnection
WithConn
.ConnectionString=StringConexao
EndWith
Try
AbreaconexocomoBancodeDados
Conn.Open()
CriaoComandoparaoSQL
DimcmdAsNewSqlCommand
Withcmd
.CommandText=insertintotblReserva
(resCodigo,usuCodigo,revInicio,revFim)values
(&idRestaurante&,&idUsuario&,
&Inicio&,&Fim&)
.CommandType=Data.CommandType.Text
.Connection=Conn
EndWith
ExecutaoComando
cmd.ExecuteNonQuery()
Retornaosdadosdetodasasreservasdo
usurio

Withcmd
.CommandText=selectresCodigo,revInicio,
revFimfromtblReservawhereusuCodigo=
&idUsuario&
.CommandType=Data.CommandType.Text
.Connection=Conn
EndWith
CriaoDataAdaptereexecutaoSelect
DimdaAsNewSqlDataAdapter
da.SelectCommand=cmd
DimdsAsNewData.DataSet
CarregaoDataSet
da.Fill(ds)
Returnds
CatchexAsException
GeraaException
ThrowNewSystem.Exception(ex.Message)
Finally
IfConn.State=Data.ConnectionState.OpenThen
Conn.Close()
EndIf
Conn.Dispose()
EndTry
EndFunction
4. Mtodo CancelaReserva
<WebMethod()>_
PublicFunctionCancelaReserva(ByValidReservaAsInteger)
AsBoolean
DimConnAsNewSqlConnection
WithConn
.ConnectionString=StringConexao
EndWith
Try
AbreaconexocomoBancodeDados
Conn.Open()
DimcmdAsNewSqlCommand
Withcmd
.CommandText=
deletefromtblReservawhererevCodigo=
&idReserva&
.CommandType=Data.CommandType.Text
.Connection=Conn
EndWith
ExecutaoComandoSQL
cmd.ExecuteNonQuery()
ReturnTrue
CatchexAsException
GeraaException
ThrowNewSystem.Exception(ex.Message)
ReturnFalse
Finally
IfConn.State=Data.ConnectionState.OpenThen
Conn.Close()
EndIf
Conn.Dispose()
EndTry
EndFunction
wm05.indb 69 3/10/2005 15:50:01
0 5 Edio
pode ter uma imagem de sua preferncia, mas o tamanho dela
dever ser de 64x64 pixels.
Vale ressaltar que, desde o Windows Mobile 2003 SE, as apli-
caes agora devem suportar o modo paisagem de execuo,
onde se usa o PocketPC de lado. Antes era complicado criar
uma aplicao com esse suporte devido a problemas no emulador.
Agora podemos rotacionar a tela no prprio emulador utilizando
seu menu de contexto, e verificar em tempo de design como nossa
interface se comporta neste modo (veja a 10). Para facilitar
ainda mais, os controles podem ser ancorados a partes espec-
ficas do formulrio, atravs da propriedade anchor (ver 11).
O uso da propriedade anchor faz com que os controles ajustem
seu tamanho e posio automaticamente com relao borda do
formulrio.
. Criando o projeto para PocketPC.
. O IDE para PocketPC.
. Adicionando a referncia ao web service.
. Menu da aplicao. . A interface do programa.
10. FuraFilaPPC no modo paisagem.
wm05.indb 70 3/10/2005 15:50:05
WebMobile 1
.NET Mobile
Agora vamos programar. Primeiro modifique o construtor do
formulrio com o cdigo apresentado na . Esse cdigo cria o
objeto que faz referncia ao web service e cria tambm o estilo do
DataGrid, informando quais colunas queremos exibir na interface.
Logo aps criado um DataSet com os dados obtidos atravs do
web service e ento o DataGrid exibe esses dados na interface.
Agora d um duplo clique no item de menu Atualizar restau-
rantes e insira o cdigo apresentado na .
Essa chamada ao web service ir retornar um DataSet com as
informaes dos restaurantes disponveis e ir armazen-lo local-
mente no dispositivo. sempre bom procurar manter alguma par-
te dos dados localmente para que no seja necessrio conectar-se
a uma rede mvel (e muitas vezes cara) o tempo todo, por isso o
contedo do DataSet salvo no arquivo restaurantes.xml para uso
posterior pela aplicao. O uso aqui do formato xml no se deve
por algum requisito mais forte, apenas por convenincia, j que
o objeto DataSet pode trabalhar com este formato nativamente,
poupando nosso trabalho.
Agora d um duplo clique no item de menu Sair e insira o
cdigo a seguir que ir fechar a aplicao:
Close();
Depois que o usurio escolher o restaurante e o horrio, o
momento de realizar o pedido da reserva. D um duplo clique no
item de menu Reservar e digite o cdigo apresentado na .
Nesse cdigo, obtemos o restaurante selecionado no DataGrid,
enviamos ao web service os dados da reserva preenchidos pelo
usurio e exibimos como resultado uma mensagem confirmando
ou no a reserva.
Agora execute o programa no emulador pressionando F5
( 12). Note que j so exibidos alguns restaurantes que esta-
vam cadastrados previamente no banco de dados.
Observe que grande parte do nosso programa foi feita sem
escrever cdigo algum. Os novos recursos do Visual Studio 2005 tor-
naram a produtividade ainda maior. Para mostrar isso, vamos criar
tambm uma verso deste mesmo programa para o Smartphone.
11. Usando a propriedade Anchor.
5. Inicializando o formulrio
///<summary>
///Webservice
///</summary>
ServicoRemoto.ServiceobjService;
///<summary>
///DataSetcomosrestaurantes
///</summary>
DataSetdsRestaurantes;
publicForm1()
{
InitializeComponent();
//CriaarefernciaaoWebService
objService=newServicoRemoto.Service();
//CriaoestiloparaoDataGrid
DataGridTableStyledtsStyle=newDataGridTableStyle();
dtsStyle.MappingName=tblRestaurante;
DataGridTextBoxColumndgcColuna=new
DataGridTextBoxColumn();
dgcColuna.HeaderText=Restaurantes;
dgcColuna.MappingName=resDescricao;
dgcColuna.Width=225;
dtsStyle.GridColumnStyles.Add(dgcColuna);
dgdRestaurantes.TableStyles.Add(dtsStyle);
//Carregaosrestaurantesquejesto
//nodispositivo
dsRestaurantes=newDataSet();
try
{
dsRestaurantes.ReadXml(restaurantes.xml);
dgdRestaurantes.DataSource=dsRestaurantes.
Tables[0];
}
catch
{
//Nofaznada
}
}
6. Atualizando a lista de restaurantes
dsRestaurantes=objService.ObtemRestaurantes();
dgdRestaurantes.DataSource=dsRestaurantes.Tables[0];
dsRestaurantes.WriteXml(restaurantes.xml);
wm05.indb 71 3/10/2005 15:50:08
2 5 Edio
Aplicao no Smartphone
Inicialmente v em File/New/Project e selecione Smartphone
Magneto Device Application. O nome do projeto ser
FuriaFilaSP(SP de Smartphone). O IDE do Visual Studio ficar
conforme apresentado na 13, bastante parecido com o do
PocketPC.
Adicione a referncia ao web service da mesma maneira como
foi feita anteriormente ( ).
Crie o menu tambm da mesma forma como foi feito com a ver-
so para PocketPC ( ). Adicione o DataGrid (sim, o DataGrid
agora suportado pelo SmartPhone tambm), DateTimePicker,
etc, tambm da mesma maneira como foi feito para o PocketPC
( ). Adicione tambm o mesmo cdigo que fizemos para o
PocketPC ( , e ).
Voc pode estar se perguntando: Mas tudo a mesma
coisa?. Sim! No h porque pensar ou programar diferen-
te s porque o dispositivo mudou! O maior avano do
Windows Mobile 5.0 foi minimizar ao mximo as di-
ferenas entre os dispositivos. Aproveite isso.
Ao final, voc ter sua aplicao disponvel
tambm para Smartphones, como na
1. Simples, no? Ela funciona exata-
mente igual verso do PocketPC,
apenas espremida dentro da
pequena tela do celular.
7. Efetuando a reserva
//Obtemoidentificadordorestaurante
intiRestauranteId;
DataGridCelldgcResaturante=dgdRestaurantes.CurrentCell;
iRestauranteId=Convert.ToInt32(dsRestaurantes.Tables[0].Rows[dgcResaturante.RowNumber][resCodigo]);
//obtemadata/horainicial
DateTimedtInicio=dtpInicio.Value;
dtInicio.AddHours(Convert.ToDouble(cbHora.Text[0]+cbHora.Text[1]));
dtInicio.AddMinutes(Convert.ToDouble(cbHora.Text[3]+cbHora.Text[4]));
//Fazareserva
try
{
DataSetdsReserva=objService.FazReserva(dtInicio,dtInicio.AddHours(nupDuracao.Value),iRestauranteId);
MessageBox.Show(Reservafeita!+dsReserva.Tables[0].Rows[0][status].ToString(),Dadosdareserva);
}
catch
{
MessageBox.Show(Reservanopodefeita!,Erronareserva);
}
12. O programa rodando no emulador.
Visual Studio 2005 e o Windows Mobile SDK
Na prtica, o Visual Studio 2005 por si s no modifica ou
melhora o cdigo que voc escreve, mas ele facilita a forma como
voc escreve e testa sua aplicao para Smartphone e PocketPC.
Os emuladores antigos (legados) agora rodam uma verso do
Windows Mobile 2003 SE compilado para CPUs x86, porm eles
foram bastante melhorados, principalmente na parte de conexo.
Agora possvel compartilhar uma pasta com o computador e
acess-la no dispositivo como se fosse um carto de memria.
Isso um recurso extremamen-
te bem vindo, principalmente
quando necessrio copiar
arquivos entre o emulador e o
desktop.
Mas nos novos emuladores
esto as verdadeiras novidades.
Agora eles rodam uma verso
ARM do Windows Mobile 5.0,
exatamente igual aos encon-
trados nos dispositivos reais.
Isso significa que a aparncia
e o comportamento do seu
software rodando no emula-
dor ser exatamente igual ao
comportamento encontrado
wm05.indb 72 3/10/2005 15:50:10
WebMobile 3
.NET Mobile
13. O IDE para Smartphone.
no dispositivo real. Alm disso, pode-se conectar o emulador ao
ActiveSync, que um software utilizado para a sincronizao do
dispositivo mvel com um computador PC, e instalar programas
nativos ARM direto no emulador.
Concluso
Com todos esses avanos do Visual Studio 2005, o fu-
turo do desenvolvimento de aplicaes para dispositi-
vos mveis que utilizam o sistema operacional Windows
Mobile parece rico e cheio de oportunidades. As faci-
lidades so enormes e a qualidade final da soluo
excelente, mesmo para desenvolvedores menos expe-
rientes. Alm dos recursos de desenvolvimento, o Visual
Studio traz recursos ino-
vadores tornando-o uma
ferramenta completa para
grande parte das etapas
no desenvolvimento de
uma aplicao.
Um outro destaque
desta ferramenta a sua
simplicidade no desen-
volvimento de aplicaes
para diferentes dispositi-
vos (neste artigo criamos
uma mesma aplicao que
funciona em PocketPC e
Smartphone). Caso voc
deseje baixar o cdigo
completo da aplicao
desenvolvida neste artigo,
acesso o portal Web Mobile
(www.portalwebmobile.
com.br).
Jos Antonio Leal de Farias
(jalf@infocon.com.br) bacharel em cincias da
computao pela UFCG e atualmente
Gerente de Pesquisa e Desenvolvimento
da Light Infocon S.A. programador
profssional nas linguagens C++ e C# e lder do grupo de
usurios CGSharp e adora Smartphones! Veja seu blog
em http://br.thespoke.net/MyBlog/Jalf/MyBlog.aspx.
1. FuriFilaSP rodando
no emulador.
Alexandre Fernandes Chaud Tarifa
(alexandretarifa@yahoo.com.br), MVP (Most
Valuable Professional) e MCAD (Microsoft Certifed
Application Developer), ministra palestras
e treinamentos na Empresa DotNet
Sistemas (www.dotnetsistemas.com.br), Bacharel em
Cincia da Computao pela UMESP e ps-graduando na
Universidade Federal de So Carlos. Lder do grupo de
usurios Codifcando.net So Paulo (sp.codifcando.net).
wm05.indb 73 3/10/2005 15:50:15
5 Edio
Desenvolvimento
C++ para
Symbian
OS
Como funciona
o sistema de
interface com
o usurio
por Eduardo Peixoto e Renato Iida
O
Symbian OS um sistema operacional projetado especifica-
mente para o ambiente mvel, preenchendo os requisitos
dos aparelhos das geraes 2.5 e 3 de celulares. Ele com-
posto por uma kernel multi-tarefa, suporte integrado telefonia,
protocolos de comunicao, gerenciamento de dados, suporte a
grficos avanado, interface com o usurio de baixo nvel e uma
variedade de algoritmos para aplicaes. Esse sistema operacio-
nal muito utilizado em aparelhos mais poderosos, os chamados
smartphones e communicators. Todas essas caractersticas tornam
este assunto bastante rico e com diversas formas de ser explorado
e tema desta srie de artigos.
No primeiro artigo foram introduzidos alguns conceitos princi-
pais sobre o sistema operacional Symbian e sua linguagem de pro-
gramao, que foi convencionado chamar de Symbian C++. Neste
artigo daremos continuidade a este tema, mostrando a estrutura
de uma aplicao com interface grfica e montando uma aplica-
o que troca contedo dinmico na tela.
Este artigo foi organizado em quatro partes. A primeira mostra
a estrutura de arquivos que qualquer tipo de aplicativo que uti-
liza GUI precisa ter. Os itens que abordam esse primeiro tpico
iniciam em Arquitetura de uma Aplicao e vo at Inicializa-
o de uma Aplicao. A segunda parte mostra que existem trs
tipos de arquitetura de aplicativos com interface com o usurio,
suas vantagens e desvantagens. O item que aborda esse tpico
Design da Arquitetura da Aplicao. A terceira parte um
exemplo para demonstrar os conceitos de uma arquitetura tradi-
cional e seus elementos. Nessa parte so mostrados os arquivos
complementares primeira parte do artigo e suas funes que,
juntos, criam uma aplicao grfica funcional para um celular
Srie 60. Por ltimo, na seo Gerando o projeto mostrado
o que muda do projeto do exemplo do artigo Desenvolvimento
C++ para Symbian OS: Introduo programao em Symbian C++
publicado na edio 4 da Web Mobile, quando o projeto consiste
de uma aplicao com interface grfica.
Introduo
Apresentar o contedo de forma visual torna mais agradvel a
experincia para o usurio, permitindo a ele associar funes e
comandos a elementos na tela.
Para demonstrar o desenvolvimento de uma aplicao
utilizando estas interfaces grficas, ns iremos seguir a
aplicao apresentada no artigo Desenvolvimento C++ para
Leitura Obrigatria
Web Mobile
Artigo Desenvolvimento C++ para Symbian OS: Introduo
programao em Symbian C++
wm05.indb 74 3/10/2005 15:50:16
WebMobile
Tecnologias
Symbian OS: Introduo programao em Symbian C++, publi-
cado na edio 4 da Web Mobile. No entanto, ser necessrio
ampliar a infra-estrutura de arquivos e classes mostrada na apli-
cao original.
No artigo anterior foram discutidos os fundamentos do Symbian
OS, bem como as principais diferenas de sua linguagem de pro-
gramao nativa, o Symbian C++, para o C++ para desktops. Foi
apresentada tambm a sintaxe dos arquivos de compilao de
um projeto em Symbian (definies de componentes, bld.inf e
especificaes de projeto, .mmp). O exemplo usado foi de uma
aplicao em console, similar a uma aplicao em linha de co-
mando para DOS. Neste artigo, iremos demonstrar uma aplicao
com interface grfica, similar s aplicaes comumente encontra-
das para celular.
Para o desenvolvimento de aplicaes com interface grfica no
Symbian, funcionalidades que em outras plataformas de desenvol-
vimento podem ser agrupadas em um nico arquivo ou classe so
separadas desde a concepo. Alguns exemplos dessas funciona-
lidades so o ponto de entrada da aplicao, o gerenciamento de
arquivos de persistncia, a lgica da aplicao, o gerenciamento
de eventos e as interfaces grficas. Isso facilita os desenvolve-
dores na tarefa de separar a lgica de um programa de sua parte
visual. No entanto, infelizmente, isso torna o entendimento de
uma aplicao grfica em Symbian mais difcil.
Arquitetura de uma aplicao
As aplicaes com interface grfica em Symbian devem apre-
sentar as seguintes funcionalidades:
Exibir graficamente informaes para o usurio e permitir
interatividade;
Responder a eventos iniciados pelo usurio;
Responder a eventos iniciados pelo sistema;
Ter a capacidade de salvar e recuperar os dados da aplicao;
Identificar-se unicamente para o sistema operacional;
Exibir informaes sobre a aplicao para o sistema
operacional.
Existe um ncleo bsico de classes que formam a aplica-
o, e algumas classes do sistema operacional que este ncleo
deve herdar de forma a obter as funcionalidades bsicas para
o funcionamento da aplicao. As classes que compem a ar-
quitetura da aplicao que provem estas funcionalidades so
divididas nessas categorias: Application, Document, AppUI e
View.
A classe Application tem uma funo fixa e bem defini-
da. Ela serve somente como ponto de entrada da aplicao,
e disponibiliza informaes sobre a aplicao para o siste-
ma operacional, como o cone e o nome da aplicao que
deve aparecer no gerenciador de aplicativos, e o UID (Unique
Identifier Number o nmero pelo qual as aplicaes Symbian
so identificadas) da aplicao. Esta classe tem um papel es-
ttico ela no se envolve com os dados da aplicao ou com
a sua lgica.
A classe de Document prov um contexto para a persistncia
dos dados da aplicao. Esta classe contm mtodos para instan-
ciar a classe de AppUI.
A classe de AppUI um recipiente para vrias notificaes vin-
das do sistema operacional, como eventos de teclado ou de siste-
ma. Esta classe ir gerenciar a forma como a aplicao ir tratar
esses eventos, despachando para o View que deveria receber a
notificao desse evento (por exemplo, a tela de formulrio a
tela que deveria ser avisada de que o usurio finalizou o preen-
chimento desse formulrio).
Um View um conceito que significa a representao dos da-
dos da aplicao na tela. O View no uma categoria de classe de
forma restrita. Existem essencialmente trs formas diferentes de
se fazer o View no Srie 60, como ser mostrado na continuidade
do artigo na seo Design da Arquitetura da Aplicao.
O framework do sistema operacional
O framework do sistema operacional a maneira pela qual uma
aplicao interage com o prprio sistema operacional. Quando
esse sistema operacional deseja finalizar uma aplicao, por
exemplo, ele se comunica com ela por meio deste framework. Ele
formado por um conjunto de classes ncleo (core classes) que
formam a base para todas as aplicaes. Estas classes formam a
estrutura necessria, e tambm encapsulam a comunicao entre
a aplicao e o sistema operacional.
O diagrama da 1 mostra quatro camadas de classes do
framework, simplificado para facilitar o entendimento.
A primeira camada dividida em dois componentes fun-
damentais: o AppArc (Application Architecture arquitetura
da aplicao) e o CONE (CONtrol Environment ambiente de
controle).
1. Diagramas das classes ncleo.
wm05.indb 75 3/10/2005 15:50:23
5 Edio
1. Implementao comum da classe Application.
1.//EstenmerodeveseromesmoencontradonocampoUID3doarquivo.mmp
2.staticconstTUidKUidMinhaApp={0x10005B91};
3.//Criaumdocumentodaaplicao,eretornaumponteiroparaele.
4.CApaDocument*CMinhaAppApplication::CreateDocumentL(){
5.CApaDocument*document=CMinhaAppDocument::NewL(*this);
6.returndocument;
7.}
8.//RetornaoUIDdaaplicao.
9.TUidCMinhaAppApplication::AppDllUid()const{
10.returnKUidMinhaApp;
11.}
As classes no AppArc provem a estrutura bsica da aplicao e
os mecanismos para retornar ao sistema as informaes sobre essa
aplicao e sobre os dados persistentes. Este um componente
do Symbian OS, e suas classes tm o nome iniciado com o prefixo
*Apa, como em CApaApplication.
As classes no componente CONE provem os mecanismos bsi-
cos para gerenciar a entrada do usurio e criar a interface grfica.
Este tambm um componente do Symbian OS, e suas classes tm
o nome iniciado por *Coe, como em CCoeControl.
A segunda camada de classes pertence ao componente Uikon,
tambm chamado Eikon. Este componente contm as implemen-
taes de interfaces grficas que so independentes de platafor-
ma dos diversos recursos do Symbian OS. As classes desse compo-
nente tm o nome iniciado por *Eik, como em CEikApplication.
A terceira camada de classes uma implementao das interfaces
grficas especfica do Uikon para o Srie 60, e chamada Avkon. A
escolha de qual implementao (Avkon ou Uikon) suas classes deve-
ro derivar ser explicada mais adiante no artigo, na seo Design
da Arquitetura da Aplicao. As classes pertencentes a este compo-
nente tm o nome iniciado por *Akn, como em CAknApplication.
A quarta camada a camada especfica da aplicao, e demons-
tra como voc poderia derivar as classes de modo a construir sua
prpria aplicao.
A maior parte das classes na primeira camada so abstratas, de-
finindo apenas as interfaces com o framework que sero utilizadas.
A segunda camada adiciona implementaes comuns ao Symbian
OS, enquanto a terceira adiciona implementaes especficas
para o Srie 60. Por fim, a quarta adiciona as implementaes
especficas da sua aplicao.
As classes que compem a infra-estrutura da aplicao
Application, Document, AppUI e AppView sero mais detalhadas
a seguir.
Classe Application
A classe da aplicao deve derivar de CEikApplication (ou de
uma outra classe que deriva desta, por exemplo,
CAknApplication 1). Existem duas funes que
devem ser implementadas por esta classe. A primeira
funo, CreateDocumentL() ( 1 linha 4), utili-
zada para criar um documento e, por isso, dever re-
tornar um objeto do tipo CApaDocument. A segunda
funo, AppDllUID() (linha 9), dever identificar a
aplicao, retornando seu UID. Uma implementao
comum dessas funes aparece na 1.
Na linha 2, definida uma constante esttica
KUidMinhaApp, que deve conter estritamente o mes-
mo valor encontrado no arquivo mmp da aplicao
(de especificaes de projeto). Esse valor retorna-
do pela funo AppDllUid() (linha 9), identificando
a aplicao para o sistema operacional. Essa identi-
ficao importante para que o sistema operacional
possa relacionar arquivos sua aplicao. A outra
funo definida, CreateDocumentL() (linha 4), utilizada para
criar um documento padro.
A grande maioria das aplicaes Symbian que utilizam GUI im-
plementam essas funes de forma semelhante como feito acima.
Note que esta no uma imposio nossa uma imposio do
framework. Essas funes devem estar definidas na sua aplicao
e devem realizar estas aes. Este o comportamento esperado
pelo sistema operacional de qualquer aplicao Symbian.
Classe Document
A classe do documento deve derivar de CEikDocument (ou de
uma classe que deriva desta, como, CAknDocument 1). Em
geral, esta classe instancia a lgica da aplicao e cria um objeto
do tipo AppUI por uma chamada ao mtodo CreateAppUiL(). O
AppUI necessrio para manipular os eventos de sistema.
Neste momento o cdigo comea a se tornar mais especfico
para cada aplicao. O cdigo descrito nas 1 e 2 so obriga-
trios e possuem uma funo muito bem-definida, sendo pouco
flexveis. Eles devem obedecer a um comportamento especfico,
no sendo permitido desvios deste comportamento.
Em uma aplicao que gerencia e modifica dados persistentes,
a classe Document a classe que essencialmente representa a
persistncia no programa, sendo responsvel por conter os mto-
dos para criar, abrir e modificar os arquivos de dados.
Um trecho do cdigo desta classe pode ser visto na 2. Este
cdigo apenas cria um objeto da classe AppUI e retorna um pon-
teiro para ele.
Classe AppUI
A classe AppUI deve derivar de CEikAppUI (ou de alguma classe
que deriva desta, como CAknAppUI 1), que por sua vez deri-
va de CCoeAppUI, que pertence ao controle do ambiente (CONtrol
Environment CONE). neste ponto que a ao de GUI efetiva-
mente se inicia, tendo esta classe duas tarefas principais:
Capturar os comandos para a aplicao;
wm05.indb 76 3/10/2005 15:50:25
WebMobile
Tecnologias
Distribuir os eventos de teclas para os vrios views da
aplicao.
A maior parte das funes dessa classe no puramente abs-
trata (virtual pela linguagem C++, porm o termo abstrata
mais esclarecedor), apenas tendo suas implementaes vazias.
Isso significa que o programador no precisa implementar todas
essas funes, ele apenas precisa implementar aquelas que ele vai
realmente utilizar.
Algumas das funes importantes implementas nesta classe so
brevemente discutidas abaixo:
HandleKeyEvent(): chamada quando um evento de tecla
pressionada ocorre;
HandleForegroundEventL(): chamada quando a aplicao
perde o foco (vai para o background) ou obtm o foco nova-
mente;
HandleCommandL(): chamada quando um comando se-
lecionado;
HandleSystemEventL(): chamada quando um evento de sis-
tema gerado;
HandleApplicationSpecificEventL(): notificao de eventos
customizveis que voc pode definir.
Alm disso, esta classe responsvel por criar e gerenciar os
applications views.
Classe AppView
O application view deriva do CONE CCoeControl (ou qualquer
classe que deriva desta). De acordo com a forma como a arquite-
tura da aplicao est sendo projetada, uma classe diferente po-
der fazer o papel do AppView, mas o AppView sempre est ligado
classe que efetivamente desenha informaes na tela.
Inicializao de uma aplicao
Neste tpico iremos mostrar os principais passos que o sistema
operacional executa desde o momento em que voc seleciona uma
aplicao para ser executada at o momento em que esta aplicao
est efetivamente executando na tela (o primeiro momento em que
ela se desenha na tela). Os passos so apresentados na 2.
Descrevendo o diagrama da 2:
PASSO 1: Toda aplicao com GUI para srie 60 deve imple-
mentar a funo global E32Dll(). Esta ser a primeira funo que
ser chamada pelo sistema operacional quando ocorre a tentativa
de executar a aplicao. Ela chamada de ponto de entrada do
DLL (DLL entry point) e deve estar presente na sua aplicao.
PASSO 2: O segundo passo quando o framework do sistema
operacional chama a funo NewApplication(), que efetivamen-
te cria o objeto da aplicao, retornando um ponteiro para o
sistema operacional. Esta funo deve ser exportada pela apli-
cao. O cdigo dessas duas funes pode ser visto na 3.
PASSO 3: Uma vez criado o objeto da aplicao, o framework
chama a funo AppDllUid, encontrada na classe Application da
sua aplicao (no nosso exemplo, CMinhaAppApplication), que
retorna o UID3 da aplicao ( ).
O valor retornado deve ser o mesmo encontrado no arquivo
.mmp (de especificaes de projeto) da aplicao, e usado pelo
sistema operacional para determinar se j existe uma instncia
dessa aplicao sendo executada.
PASSO : O prximo passo a chamada ao mto-
2. Implementao comum da classe Document.
//CriaumobjetoAppUIeretornaumponteiroparaele.
CEikAppUi*CMinhaAppDocument::CreateAppUiL(){
CEikAppUi*appUi=new(ELeave)CMinhaAppUi;
returnappUi;
}
3. Mtodos para inicializao da aplicao.
//Pontodeentradadaaplicao.
//Retornaquetudoestcorreto.
GLDEF_CTIntE32Dll(TDllReason){
returnKErrNone;
}
//Criaumobjetodaaplicaoeretornaumponteiropara
ele.
EXPORT_CCApaApplication*NewApplication(){
return(newCMinhaApplication);
}
4. Mtodos para inicializao da aplicao.
//RetornaoUIDdaaplicao.
TUidCMinhaAppApplication::AppDllUid()const{
returnKUidMinhaApp;
}
2. Seqncia de inicializao de uma aplicao.
wm05.indb 77 3/10/2005 15:50:30
5 Edio
do CreateDocumentL() existente na classe Application
(CMinhaAppApplication, no exemplo). Este mtodo retor-
na para o framework um ponteiro para um objeto do tipo
CApaDocument, que aponta para o objeto da classe Document
(CMinhaAppDocument, que estende CAknDocument ver
1). Note na linha 2 da que um ponteiro para a classe
Application passado para a classe Document para que esta
seja capaz de chamar o mtodo AppDllUid() para descobrir
o UID3 da aplicao e gerenciar os arquivos que so dessa
aplicao.
PASSO : Agora o framework usa este ponteiro para criar
o objeto AppUI (no nosso caso, CMinhaAppUI), chamando o
mtodo CreateAppUiL() ( ).
Dessa forma, o framework tem ponteiros para os objetos prin-
cipais da aplicao Application, Document e AppUI, que foram
obtidos atravs de uma estrutura especfica na qual a aplicao
foi construda. Estes ponteiros possibilitam ao framework chamar
funes dessas classes:
para descobrir a UID3 e identificar a aplicao, no caso da
Application;
abrir ou modificar um documento, no caso da Document;
ou repassar um evento do sistema, no caso da AppUI.
Esses ponteiros podem ser usados pelo framework para contro-
lar a aplicao, repassando eventos especficos do sistema para
a aplicao.
Design da arquitetura da aplicao
Alm do ncleo bsico descrito anteriormente, existe o design
da arquitetura do programa. Em srie 60 existem trs formas
diferentes de implementar isso:
Arquitetura tradicional;
Arquitetura baseada em caixas de dilogo;
Arquitetura Avkon de troca de Views.
A principal diferena entre eles a forma como manipulam os
eventos e como feita a troca de Views dentro do programa, alm
de mudar a implementao desse View.
Na arquitetura tradicional, o elemento de View herda direta-
mente de CCoeControl, que funciona como uma tela em branco
que pode ser desenhada conforme a sua necessidade. Essa classe
comumente chamada Container. Isso permite uma grande fle-
xibilidade, entretanto, fazer qualquer coisa mais elaborada re-
quer muitas linhas de cdigo, o que inviabiliza certas aplicaes.
Em termos do gerenciamento de eventos, o AppUI responsvel
por gerenciar os eventos iniciados pelo usurio, ativando cada
Container de acordo com a lgica da aplicao.
Na arquitetura baseada em caixas de dilogo, o AppUI ainda a
classe que possui os controles. A diferena que estes controles
herdam de uma srie de classes especficas (que por sua vez her-
dam de CCoeControl) que implementam funcionalidades como lis-
tas, formulrios, entre outros elementos grficos pr-programados
pelo sistema operacional. A vantagem que podemos obter mais
funcionalidades com menos linhas de cdigos, com uma aparncia
padro do sistema operacional. A desvantagem que essa aborda-
gem no tem a flexibilidade da arquitetura tradicional.
A arquitetura Avkon de troca de views especfica do Avkon
(e, portanto, especfica para a plataforma Srie 60) e foi criada
principalmente para ser utilizada com aplicaes com mltiplas
telas e mltiplas mudanas de tela. De forma similar estrutura
tradicional, ainda existe a idia do Container, mas existe outra
classe entre o Container e o AppUI, que faz o papel de AppView
e herda de CAknViewAppUI. Essa classe responsvel por ativar/
desativar os Containers, de acordo com comandos vindos do
AppUI, de forma que apenas um view esteja ativo no momento.
O CAknViewAppUI tambm responsvel por criar e destruir as
views, e normalmente o faz de forma que os views que no este-
jam ativos sejam destrudos, para economizar memria.
Arquitetura tradicional
Para ilustrar o uso da arquitetura tradicional foi criado um
exemplo simples que escreve Hello na tela e quando o usurio
escolher no menu o comando next, a mensagem trocado por
World e o item do menu trocado para back. A tela inicial do
programa no emulador apresentada na 3.
O menu da tela inicial mostrado na .
Se for selecionado o comando next com a softbutton da es-
querda (ver 1), a tela que vai ser visualizada a da .
Alem disso, o menu da tela final mostrado na . E se o coman-
do back for selecionado o programa volta para a tela da 3.
1. SoftButton
Geralmente, os celulares possuem teclas cujas funes podem ser
5. Mtodo para instanciar a classe Document. Este
fragmento encontra-se na classe Application.
//Criaumdocumentodaaplicao,eretornaumponteiro
paraele.
1.CApaDocument*CMinhaAppApplication::CreateDocumentL(){
2.CApaDocument*document=CMinhaAppDocument::
NewL(*this);
3.returndocument;
4.}
6. Mtodo para instanciar a classe AppUI. Este fragmento
encontra-se na classe Document.
//CriaumobjetoAppUIeretornaumponteiroparaele.
CEikAppUi*CMinhaAppDocument::CreateAppUiL(){
CEikAppUi*appUi=new(ELeave)CMinhaAppUi;
returnappUi;
}
wm05.indb 78 3/10/2005 15:50:33
WebMobile
Tecnologias
definidas pelo programador. Essas
teclas so denominadas softbuttons.
Os aparelhos Srie 60, abordados nesse
artigo, possuem trs softbuttons
(esquerda,direita e meio). Elas so
mostradas em destaque na 3.
Alguns exemplos de funes definidas
so: aceitar, cancelar, sair ou ativar.
Alm das classes mostradas an-
teriormente, existem ainda outros
elementos que compem a aplica-
o, como o arquivo de recursos, os
arquivos de internacionalizao, e
os arquivos de definio de compo-
nentes e especificaes de projeto.
Esses elementos sero explicados
usando o prprio cdigo da aplica-
o criada.
Arquivo de recursos
O arquivo de recursos um arquivo texto com a extenso .rss e
usado para especificar elementos visveis para o usurio. Outra
funo especificar layout de elementos como menus, caixa de
dilogos e outros. A sintaxe similar a de um arquivo C++ , mas
no idntico. Os comentrios so no mesmo formato e as decla-
raes de pr-processamento como #include, #define, #if,#else e
#endif so aceitas. O arquivo dividido em cabealho e corpo.
O cabealho do arquivo de recurso do exemplo HelloWorld
mostrado na . Primeiro (linha 1) o campo NAME que um
identificador de quatro letras que no deve ser igual a outro ar-
quivo de recurso do programa ou do sistema. A rea de include
(linhas 2 a 8) funciona como em um arquivo C ou C++. O campo
RSS_SIGNATURE (linha 9) pode ser deixado em branco pois seu
contedo ignorado, mas ele deve existir no arquivo para no
causar um erro de compilao. Na linha 10, o recurso define o
documento default usado pela aplicao. obrigatrio estar no
cabealho, mesmo estando vazio.
Definir um menu utilizando o arquivo de recurso
Para definir o menu apresentado nas e e quais itens apa-
recem nesse menu, utilizado o
recurso denominado MENU_BAR
mostrado na .
Normalmente, um MENU_BAR
contm um nico MENU_TITLE.
Ele especifica o ttulo do menu
e o nome do recurso que vai de-
finir os itens do menu. No Srie
60, o item txt que define o titulo
no utilizado e pode ser dei-
xado em branco. O MENU_PANE
contm os itens do menu como
mostra a .
Nesse menu existem dois itens. O primeiro avana e o outro volta
tela. O MENU_ITEM tem dois campos, o nome no campo txt e
o ID do comando. Os comandos so definidos em arquivos sepa-
rados com a terminao .hrh (mostrado na 10). Alm disso,
necessrio associar esse menu tela que vai ser mostrada ao usu-
rio. Isso feito pelo recurso EIK_APP_INFO como mostra a 11.
Para no haver conflitos com os IDs dos comandos do sistema,
recomendvel que os IDs definidos pelo usurio comecem em
0x6000 como mostrado na 10.
Manuseando os comandos
Os menus so criados nos arquivos .rss mas as aes so toma-
das pelas funes:
HandleCommandL(), nas classes CAknAppUI ou derivadas
de CAknView() e;
ProcessCommandL(), nas classes derivadas de CAknDialog().
A 12 mostra um exemplo de implementao de como mani-
pular os eventos do menu mostrado nas e . A implementao
3. Tela Inicial do exemplo.
. Menu da Tela Inicial do exemplo. . Tela Final do exemplo.
. Menu da Tela Final do
exemplo.
7. Cabealho do Arquivo de Recurso (HelloWorld.rss).
//Identificadordorecurso
1.NAMEHWRD
//INCLUDES
2.#include<avkon.loc>
3.#include<avkon.rsg>
4.#include<avkon.rh>
5.#include<avkon.mbg>
6.#include<eikon.rh>
7.#includeHelloWorld.hrh
8.#includeHelloWorld.loc
9.RESOURCERSS_SIGNATURE{}
10.RESOURCETBUF{buf=;}
wm05.indb 79 3/10/2005 15:50:36
0 5 Edio
basicamente apenas um switch que usa os IDs como parmetro e
encontra-se na classe AppUI da aplicao. Alm dos dois itens do
menu, que so acionados pela softbutton da esquerda, neces-
srio manipular o evento de sada que gerado pelo softbutton
da direita (EAknSoftkeyExit). Outro evento que obrigatrio ser
manipulado o EEikCmdExit, que o evento gerado pelo sistema
operacional quando ele deseja fechar a aplicao.
A ao EHelloWorldProximo muda o texto mostrado na tela e
muda o valor da flag que define quais itens do menu devem apa-
recer. De forma similar, o EHelloWorldVoltar faz a mesma coisa
mas com diferentes valores para as duas aes. A implementao
da funo MudaTexto explicada no item Funo para Mudar o
Texto, descrita na continuidade do artigo.
Menus dinmicos
Outra funcionalidade dos menus a possibilidade de dinamica-
mente os itens serem escondidos ou mostrados. A 13 mostra
como foi feito para esconder o item back da tela da ,
esconder o next da tela da e como foi usada a varivel
10. Arquivo de definio dos IDs dos comandos
do menu (HelloWorld.hrh).
#ifndef__HELLOWORLD_HRH__
#define__HELLOWORLD_HRH__
enumTHelloWorldCommandIds
{
EHelloWorldProximo=0x6000,
EHelloWorldVoltar=0x6001
};
#endif//__HELLOWORLD_HRH__
11. Associao do menu tela do usurio (HelloWorld.rss).
RESOURCEEIK_APP_INFO
{
menubar=r_helloworld_menubar;
cba=R_AVKON_SOFTKEYS_OPTIONS_EXIT;
}
8. Declarao do menu no arquivo de recurso
(HelloWorld.rss).
RESOURCEMENU_BARr_helloworld_menubar
{
titles=
{
MENU_TITLE
{
txt=;//
menu_pane=r_helloworld_menu;
}
};
}
9. Definio dos itens do menu (HelloWorld.rss).
RESOURCEMENU_PANEr_helloworld_menu
{
items=
{
MENU_ITEM
{
command=EHelloWorldProximo;
txt=COMMAND_NEXT;
},
MENU_ITEM
{
command=EHelloWorldVoltar;
txt=COMMAND_BACK;
}
};
}
flag da 12 para controlar isso. O parmetro aResourceId de
entrada deve ser usado para saber qual recurso (no caso o menu)
deve ser alterado. A funo SetItemDimmed() responsvel por
definir a visibilidade dos itens e tem dois parmetros de entrada.
O primeiro o ID do comando que vai selecionado e o segundo
um booleano que deve ser ETrue para esconder o item e EFalse
para mostrar o item.
String no arquivo de recurso e internacionalizao
A forma mais recomendada de inserir textos na sua aplicao
j utilizando a conhecida tcnica de internacionalizao.
As lnguas disponveis devem ser agrupadas em um arquivo .loc e
deve ser includo no cabealho do arquivo de recursos como mos-
trado na (#include HelloWorld.loc). Dentro do arquivo .loc
colocado um include para um arquivo tipo .lxx onde xx o cdigo
de dois dgitos da linguagem definido no arquivo e32std.h. Um
exemplo de arquivo .loc mostrado na 1.
Os textos em ingls do arquivo HelloWorld.l01 so mostrados
na 1.
Para utilizar essas strings definidas no arquivo HelloWorld.l01 den-
tro do aplicativo, necessrio criar um recurso denominado TBUF no
arquivo de recursos e a sintaxe mostrada o trecho da 1.
Para chamar dentro do aplicativo esse r_label_text, deve
ser usado caixa alta em todo o nome como mostra o trecho
do HelloWorldAppUi.cpp do parmetro de entrada da funo
MudaTexto() nas linhas 13 e 19 da 12.
O texto do menu pode ser usado diretamente como mostrado na
e no necessrio criar um recurso TBUF.
wm05.indb 80 3/10/2005 15:50:40
WebMobile 1
Tecnologias
Funo para mudar o texto
A funo para mudar o texto apresentado na tela da 3 para
o que est na descrita na 1.
Basicamente, ele usa o ID de um recurso de texto fornecido
como parmetro de entrada (mostrado com mais detalhes no item
de internacionalizao), cria um objeto para converter o recurso
em uma string (linhas 3 e 4) que pode ser usado pelo objeto
iLabel, que responsvel por mostrar o texto na tela (linhas 5 e
6). Depois deve usar a funo SizeChanged() (linha 7) para mudar
o tamanho que deve ter esse iLabel na tela.
Gerando o projeto
Para gerar o projeto, inicialmente necessrio o arquivo de
definio de componentes, bld.inf. Este arquivo no tem nenhu-
ma mudana com relao ao descrito para a aplicao em texto. O
cdigo pode ser visto na 1.
Este arquivo apenas aponta para o arquivo de especificaes de
projeto (mmp). O cdigo do arquivo mmp pode ser visto na 1.
Este arquivo foi explicado no artigo anterior, para uma apli-
cao baseada em console. fcil ver que esta aplicao inclui
mais arquivos de cdigo fonte e bibliotecas, alm de arquivos de
recursos.
Com relao ao alvo (target) (linha 1) e ao tipo de alvo
(targettype) (linha 2), ambos denotam uma application (app).
Isso define que esta aplicao tem uma interface grfica, definin-
do o nmero do UID1.
O campo UID (linha 3) tem dois nmeros: o primeiro,
0x100039CE, indica que esta uma aplicao app com interface
grfica, e o segundo o UID3 da aplicao, que define unicamente
esta aplicao Symbian. O valor usado para o UID3, 0x012233ED,
foi escolhido dentro da gama de nmeros de teste este o
12. Cdigo para manipular os eventos do menu
(HelloWorldAppUi.cpp).
1.voidCHelloWorldAppUi::HandleCommandL(TIntaCommand)
2. {
3. switch(aCommand)
4. {
5.caseEEikCmdExit:
6.caseEAknSoftkeyExit:
7. {
8. Exit();
9. break;
10. }
11.caseEHelloWorldProximo:
12.{
13.iAppContainer->MudaTexto(R_LABEL_TEXT2);
14.flag=1;
15. break;
16.}
17.caseEHelloWorldVoltar:
18.{
19.iAppContainer->MudaTexto(R_LABEL_TEXT);
20.flag=0;
21.break;
22.}
23. }
13. Cdigo para criar um menu dinmico (HelloWorldAppUi.cpp).
voidCHelloWorldAppUi::DynInitMenuPaneL(
TIntaResourceId,CEikMenuPane*aMenuPane)
{
if(aResourceId==R_HELLOWORLD_MENU)
{
if(flag==0)
{
aMenuPane->SetItemDimmed(
EHelloWorldProximo,EFalse);
aMenuPane->SetItemDimmed(
EHelloWorldVoltar,ETrue);
}
else
{
aMenuPane->SetItemDimmed(
EHelloWorldProximo,ETrue);
aMenuPane->SetItemDimmed(
EHelloWorldVoltar,EFalse);
}
}
}
14. Arquivo com as strings para cada lngua (HelloWorld.loc).
/arquivodelinguagemdoinglsbritnico
#ifdefLANGUAGE_01
#includeHelloWorld.l01
#endif
//arquivodelinguagemdoportugusdoBrasil
#ifdefLANGUAGE_76
#includeHelloWorld.l76
#endif
15. Texto da lngua inglesa para a aplicao (HelloWorld.l01).
/textodaAplicao
#defineLABEL_TEXTHello
#defineLABEL_TEXT2World
//textodoMenu.
#defineCOMMAND_NEXTNext
#defineCOMMAND_BACKBack
wm05.indb 81 3/10/2005 15:50:42
2 5 Edio
18. Cdigo do arquivo bld.inf.
PRJ_MMPFILES
HelloWorld.mmp
19. Cdigo do arquivo HelloWorld.mmp.
1.TARGETHelloWorld.app
2.TARGETTYPEapp
3.UID0x100039CE0x101FDA4D
4.TARGETPATH\system\apps\HelloWorld
5.SOURCEPATH..\src
6.SOURCEHelloWorldApplication.cpp
7.SOURCEHelloWorldAppUi.cpp
8.SOURCEHelloWorldDocument.cpp
9.SOURCEHelloWorldContainer.cpp
10.LANG01
11.RESOURCE..\data\HelloWorld.rss
12.RESOURCE..\data\HelloWorld_caption.rss
13.USERINCLUDE.
14.USERINCLUDE..\src
15.SYSTEMINCLUDE\epoc32\include
16.LIBRARYeuser.libapparc.libcone.libeikcore.lib
17.LIBRARYeikcoctl.libavkon.libcommonengine.lib
18.AIFHelloWorld.aif..\aifHelloWorldAif.rssc12
context_pane_icon.bmpcontext_pane_icon_mask.bmplist_
icon.bmplist_icon_mask.bmp
Renato Faria Iida (eduardopfs@
gmail.com) tambm faz parte do grupo
Inova Mobile. engenheiro eletricista
e desenvolvedor especializado em
aplicaes para dispositivos mveis.
Eduardo Peixoto Fernandes da Silva
(renatoiida@gmail.com) faz parte do grupo
Inova Mobile da Universidade de Braslia,
e mestrando de Engenharia Eltrica,
com tema em Sistemas Operacionais para
aparelhos celulares. Desenvolve aplicativos para celular
h 3 anos.
16. Inserindo uma string como recurso (HelloWorld.rss).
RESOURCETBUFr_label_text
{
buf=LABEL_TEXT;
}
17. Funo para mudar o texto na tela (HelloWorldContainer.cpp).
1.voidCHelloWorldContainer::MudaTexto(TIntbuffer)
2.{
3. HBufC*labelText;
4. labelText=StringLoader::LoadLC(buffer);
5. iLabel->SetTextL(*labelText);
6. CleanupStack::PopAndDestroy(labelText);
7. SizeChanged();
8.}
valor que deveria ser pedido para a Symbian caso esta fosse uma
aplicao comercial.
O outro campo diferente o campo LANG (linha 10), este foi
explicado em internacionalizao. O ltimo campo diferente o
campo AIF (linha 18) de Application Information (informaes
da aplicao). Este define onde estaro os arquivos usados em
tempo de execuo, como cones e imagens.
Por fim, para compilar o cdigo necessrio executar os mes-
mos passos mostrados no artigo anterior.
Concluso
Pode ser observado que o desenvolvimento de uma aplicao
com interface grfica em Symbian um pouco complexo, tendo
que se atentar para vrios detalhes de implementao. Entretan-
to, desenvolver em Symbian pode valer a pena, pois uma apli-
cao Symbian nativa para o ambiente no qual ela ir rodar.
Isso significa que a aplicao ter um acesso facilitado a vrias
funcionalidades do aparelho, tais como cmera, caixas de som,
microfones, etc. Alm disso, a aplicao nativa mais rpida que
outras aplicaes.
O objetivo deste artigo no foi apresentar todas as formas
possibilidades de desenvolvimento de aplicaes com interface
grfica em Symbian, mas introduzir o leitor a esse mundo, permi-
tindo que se tenha um conhecimento mnimo sobre os conceitos
envolvidos nessas aplicaes e a partir disso ter a possibilidade
de explorar com mais segurana o que est sendo feito.
wm05.indb 82 3/10/2005 15:50:46
wm05.indb 83 3/10/2005 15:50:55
BV`Z>iBdW^aZ
lll#[dgjb#cd`^V#Xdb
0 logoIipo hokia e marca regisIrada da hokia CorporaIion, Finlndia.
Aprenda como Iazer aplica(es e gerar negcios com a lder mundial de celulares - a hokia. ParIicipe do Workshop Fo-
rum hokia que aconIecer duranIe a FuIurecom em Florianpolis, 8rasil, de Z4 a Z7 de 0uIubro de ZOO5. Esse workshop
graIuiIo dar um panorama das plaIaIormas hokia, suas Iecnologias, esIraIegias de negcio, porIIlio de produIos e
oporIunidades de negcios.
Ldg`h]de;dgjbCd`^V
hoIel Ha|esIic Palace
Av. 8eira Har horIe, Z746
CenIro - Florianpolis - SC
uarIa-Ieira, Z6 de 0uIubro de ZOO5
0as 3:OOh s 7:OOh
K^h^iZ"cdhcV;jijgZXdb!cdhiVcYYVCd`^V#
8gZhXVXdbd;dgjbCd`^V
0 Forum hokia e uma comunidade global Iocada na cria(o de oporIunidades de negcios renIveis e susIenIveis para
desenvolvedores de Iecnologias mveis. EnIre e Ienha acesso a vrios recursos para consIruir e colocar no mercado suas
aplica(es mobile de Iorma mais Icil e rpida.
5aranIa sua inscri(o no seguinIe endere(o:
]iieh/$$b`iddah#[dgjb#cd`^V#Xdb$
User hame: '+&%%*
Password [em maisculas}: ;JIJG:8DB
wm05.indb 84 3/10/2005 15:50:58