 | A Plataforma S60, eSWT, Java ME e os MIDlets
Nesta seção, você vai se ambientar. Primeiro você vai adquirir um pouco de conhecimento sobre a plataforma S60 e o eSWT,
antes de examinar a implementação do Java Platform, Micro Edition e MIDlet.
Arquitetura da Plataforma S60
A plataforma S60, antes conhecida como Series 60, é uma plataforma de aplicativo para telefones móveis avançados
ou telefones inteligentes. Ela é executada no S.O. Symbian, um sistema operacional empregado em vários telefones
móveis. Desenvolvida principalmente pela Nokia, a S60 está licenciada para vários outros fornecedores de telefones móveis,
como Samsung, Panasonic e LG. Observe que, embora a S60 em si não seja um software livre, houve uma iniciativa recente de
transformar o S.O. Symbian em software livre.
A S60 consiste em um conjunto de aplicativos padrão, em uma estrutura de interface com o usuário e em componentes de middleware. Os
aplicativos incluem telefonia, sistema de mensagens, navegação na Web, multimídia, gerenciamento de informações pessoais,
aplicativos para escritório, gerenciamento de dispositivo remoto e muito mais. O design flexível e as bibliotecas padrão
incluídas permitem que a S60 suporte o desenvolvimento de extensões e aplicativos de terceiros. A Figura 1 mostra uma
visão geral arquitetural de alto nível da Plataforma S60.
Figura 1. Arquitetura da Plataforma S60
Fornecedores de software podem utilizar uma variedade de linguagens de programação e tecnologias para desenvolver
aplicativos para a plataforma S60. Além de C/C++, você pode utilizar o Java Mobile Information Device Profile (MIDP)
V2.0 e também Python, Adobe Flash e outras tecnologias de navegador da Web avançadas para criar widgets da Web. A
plataforma S60 facilita a interoperabilidade do fornecedor empregando inúmeras especificações abertas desenvolvidas
por Open Mobile Alliance (OMA), como OMA Multimedia Messaging e OMA Digital Rights Management (DRM).
Cada release da plataforma S60 é nomeado como uma edição. Além disso, pequenos upgrades em uma edição, bem upgrades
específicos de um dispositivo, são publicados como pacotes de recursos. Atualmente, o release mais recente da plataforma
S60 é a quinta edição. Entretanto, a terceira edição com Feature Pack 2 é o primeiro release que suporta eSWT. Ela também
está disponível em vários outros telefones móveis. Normalmente, novas edições são instaladas apenas em telefones móveis
recém-liberados; dispositivos existentes não são atualizados para a edição mais recente. Entretanto, o upgrade para um
pacote de recursos mais novo pode ser possível. Além disso, este tutorial utiliza a terceira edição do FP2 como plataforma
de implementação de destino.
Aplicativos Remotos Java, o Jeito Eclipse
Provavelmente, o Eclipse é mais conhecido como Ambiente de Desenvolvimento Integrado (IDE) de primeira classe. Entretanto,
o IDE do Eclipse abrange inúmeras tecnologias reutilizáveis. Algumas dessas tecnologias são ferramentas, como Java Development
Tools (JDT) e Plug-in Development Environment (PDE). Outras são tecnologias de tempo de execução, como Equinox Framework
(implementação de tempo de execução OSGi do Eclipse) e Standard Widget Toolkit (SWT). De fato, é o SWT que fornece ao
Eclipse sua aparência e seu comportamento nativos.
O SWT é considerado uma alternativa para o Swing do Java, uma estrutura de GUI que é uma parte padrão do Java. O SWT foi
desenvolvimento em um momento no qual o Swing não era considerado uma tecnologia de GUI adequada para um IDE avançado. O
recurso peculiar do SWT é que ele é essencialmente um wrapper do Java em torno do kit de ferramentas do widget nativo do
sistema operacional. Essa abordagem não só confere ao aplicativo baseado em SWT a aparência e o comportamento de aplicativos
(não Java) nativos, mas também impulsiona seu desempenho, já que as bibliotecas de widget nativas provavelmente são otimizadas
para o sistema operacional de destino dos mesmos.
Dentro do eSWT
A versão integrada do SWT, ou eSWT, é o SWT essencialmente adaptado para uso em ambientes limitados por recursos. O eSWT
implementa um subconjunto da API do SWT, bem como extensões remotas projetadas para uso em dispositivos remotos.
O conceito central de SWT (e eSWT) é o widget. Um widget é a menor unidade de uma interface com o usuário. Janelas, diálogos, botões, barras
de ferramentas, menus, itens de menu, tabelas, árvores e tabela e itens de árvore são todos widgets. Widgets que são capazes
de receber eventos são chamados controles. Por exemplo, janelas, diálogos, botões, tabelas e árvores são todos controles. Entretanto,
menus e itens árvore e tabela não são.
A maioria dos widgets do SWT é suportada diretamente por seu sistema operacional nativo equivalente. Ou seja, os
desenhos, os eventos, o comportamento e a lógico do widget são delegados a uma biblioteca nativa que, por sua vez,
utiliza a API nativa do sistema operacional de destino. Widgets indisponíveis em uma determinada plataforma são
"emulados", ou desenhados de modo customizado. Como resultado, o SWT só é suportado em plataformas para as quais
existe uma implementação do SWT específica para a plataforma. Entretanto, como o SWT mantém cuidadosamente sua API
e sua compatibilidade comportamental entre plataformas e versões, muitas vezes é possível reutilizar componentes da
UI baseados no SWT que são desenvolvidos para uma plataforma em uma ou mais outras plataformas.
Uma UI típica baseada no SWT é composta de uma árvore de widgets. Cada widget deve ser contido por seu pai (exceto para
o widget de nível superior, que não precisa ter um pai). No nível superior, geralmente existe um shell, que representa uma
janela. O cliente da janela é representado por um composto, que é o filho do shell da janela. O composto contém outros
controles, como rótulos, controles e texto e botões. Compostos utilizam classes de Layout
para controlar o posicionamento de seus filhos. Controles são capazes de responder a eventos do usuário e do S.O. Cada
tipo de controle documenta quais eventos ele suporta. Clientes podem registrar listeners para controles para eventos
específicos. Por exemplo, um KeyListener pode ser registrado com um controle para receber um KeyEvent sempre
que o controle receber entrada do teclado do usuário. Clientes podem até interceptar o PaintEvent
do controle para desenhar diretamente na superfície da tela do controle. Entretanto, normalmente isso não é necessário,
já que a aparência nativa do widget é aquilo que é desejado. Um tipo de controle utilizado para desenhos customizados é
o Canvas, que, ao contrário, não possui uma representação visual nativa. Ao responder ao PaintEvent
do controle, o implementador pode utilizar inúmeras APIs de primitivas gráficas (por exemplo, para desenhar linhas, texto, etc.) fornecidas
pela classe Graphical Context (GC), um exemplo do que está disponível a partir do PaintEvent.
Como cada widget do SWT representa um recurso de S.O. raro, a API requer que você descarte o widget assim que ele deixar
de ser necessário. Portanto, você deve se lembrar de chamar o método dispose() do widget no
momento apropriado. Se você não fizer isso, provavelmente o resultado será uma fuga de recursos. Recursos que não são
widget, como cores e fontes, também devem ser descartados quando não forem mais utilizados.
Todas as operações do widget — criação de widgets, processamento de evento e descarte — são executadas no contexto
de uma exibição. A exibição é o ponto de entrada do tempo de execução no SWT. Um aplicativo típico baseado em SWT cria uma
única instância da exibição, constrói a UI desejada e implementa o que é chamado de loop de eventos da UI. Esse loop de
eventos sonda continuamente a exibição de mensagens do S.O. recebidas e as despacha para os destinatários-alvo (isto é,
os controles) até que recebam instrução para parar. O encadeamento que executa essa função é chamado encadeamento de
exibição. Todas as interações do SWT devem ocorrer nesse encadeamento. Se outro encadeamento quiser interagir com o SWT
de qualquer forma (com algumas exceções), ele deverá postar um Runnable (para executar a função desejada) no encadeamento
utilizando os métodos syncExec(Runnable) e asyncExec(Runnable) da
exibição. Esses pedidos são enfileirados e processados no loop de eventos da exibição.
 |
eSWT e Java ME
Ao desenvolver software para dispositivos remotos, você deve estar ciente dos limitadores de recurso normalmente existentes
no software integrado. Aplicativos remotos Java não são uma exceção. Além de pequenas telas com diferentes graus de resolução
e suporte de cores, os aplicativos integrados devem lidar com memórias pequenas, energia de bateria e processamento limitados,
além de dispositivos de entrada limitados.
O Java Platform, Micro Edition (Java ME) está disponível em várias configurações com base nos recursos da plataforma de destino. Esses
destinos impõem limites sobre serviços de tempo de execução disponíveis, APIs e níveis de linguagem. Uma configuração representa uma Java
Virtual Machine (JVM) e um conjunto de APIs comuns para uma classe de dispositivos. Um perfil é um conjunto de APIs específico de uma
configuração que aborda uma classe limitada de dispositivos da mesma categoria. A Connected Limited Device Configuration (CLDC) com
Mobile Information Device Profile (MIDP) é a configuração implementada com mais frequência em telefones móveis. Ela destina-se às
plataformas que só podem aceitar de 128 a 512 KB para a execução de processos Java. A Figura 2 ilustra onde a CLDC e o MIDP se encaixam
na pilha arquitetural de um Mobile Information Device (MID).
Figura 2. Arquitetura do MID com CLDC e MIDP
Uma diferença notável entre o eSWT e as versões de desktop do SWT é que enquanto o primeiro se satisfaz apenas com
CLDC/MIDP, o segundo requer, pelo menos, uma Java Connected Device Configuration (CDC) V1.0 com Foundation Profile (FP)
V1.0. A CDC destina-se a ambientes com pelo menos 2 MB de RAM e 2,5 MB de ROM disponíveis para Java. Isso possibilita a
implementação do eSWT em uma variedade muito maior de dispositivos remotos, o que normalmente fornece suporte para Java
CLDC/MIDP, mas não CDC/FP. Exigir CDC/FP como ambiente de tempo de execução mínimo suportado é o que também impede o eRCP
de ser executado na S60. Além disso, aplicativos baseados em S60 podem utilizar eSWT, mas não o eRCP num todo. A Figura 3
descreve a arquitetura de alto nível do eSWT e sua posição em relação à plataforma nativa subjacente, Java CLDC/MIDP, e
aplicativos remotos (MIDlets).
Figura 3. eSWT na Pilha Java CLDC/MIDP
Outras implicações do desenvolvimento para CLDC envolvem o conjunto limitado de APIs. Enquanto a CDC é projetada para
ter compatibilidade de API com Java 2, Standard Edition (J2SE) V1.3.1 (pelo menos em termos de API de tempo de execução
básico), a CLDC fornece apenas um subconjunto de API muito menor (por exemplo, Coletas Java não estão disponíveis em CLDC). Além
disso, a migração desses aplicativos J2SE para CLDC costuma envolver muito esforço. Felizmente, a API do SWT é projetada
de uma maneira que não faz referência a classes ou interfaces que estão indisponíveis na CLDC.
MIDlets
Devido aos limitadores da plataforma de destino, os aplicativos gravados para o perfil do MIDP devem ser estruturados
como componentes cujo tempo de vida é gerenciado pela estrutura. O ponto de entrada para um aplicativo MIDP é um MIDlet. Um MIDlet é
uma classe que estende a classe abstrata javax.microedition.midlet.MIDlet. A subclasse concreta
do MIDlet deve implementar três métodos abstratos: startApp(), pauseApp()
e destroyApp(boolean). Esses métodos são chamados pela estrutura em diferentes pontos do tempo
de vida do MIDlet. Além disso, o MIDlet deve fornecer um construtor sem argumento público. A Listagem 1 mostra uma
implementação do esqueleto do MIDlet.
Listagem 1. Implementação do Esqueleto do MIDlet
package org.eclipse.eswt.sudoku;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class Sudoku extends MIDlet {
protected void startApp() throws MIDletStateChangeException {
// Stub de método gerado automaticamente TODO
}
protected void pauseApp() {
// Stub de método gerado automaticamente TODO
}
protected void destroyApp(boolean unconditionally)
throws MIDletStateChangeException {
// Stub de método gerado automaticamente TODO
}
}
|
Quando o MIDlet é construído pela primeira vez, ele encontra-se no estado pausado. Quando o software de gerenciamento de
aplicativo do host decide iniciar o MIDlet, ele chama seu método startApp(). Neste ponto, o
aplicativo se torna ativo. Depois o gerenciador de aplicativos pode optar por pausar o MIDlet, e nesse ponto ele vai chamar
seu método pauseApp(). Quando pausado, o aplicativo libera quaisquer recursos temporários e se
torna passivo. Tanto no estado ativo quanto pausado, o aplicativo pode receber uma chamada para destroyApp(boolean),
pedindo que ele pare de trabalhar. O argumento booleano indica se o pedido é incondicional. Ao terminar, o aplicativo deve
se tornar passivo e liberar quaisquer recursos do sistema adquiridos.
A classe abstrata MIDlet fornece métodos que permitem ao extensor verificar suas permissões
(checkPermission(String)), recuperar propriedades do aplicativo do software de gerenciamento (getAppProperty(String))
e notificar o gerenciador sobre mudanças de estado, como ser retomado (notifyResumed()) ou destruído (notifyDestroyed()). O MIDlet também pode emitir pedidos para a plataforma para acessar URLs arbitrárias (platformRequest(String));
a forma como essas URLs são tratadas é dependente de plataforma. Finalmente, o MIDlet pode solicitar sua ativação quando
no estado pausado (por exemplo, ao receber alguns eventos externos) chamando resumeRequest().
MIDlets normalmente são empacotados em arquivos JAR. Entretanto, um JAR do MIDlet deve conter entradas especiais em seu
manifesto (META-INF/MANIFEST.MF), que descreve os MIDlets contidos no JAR. Os atributos obrigatórios incluem o nome do
MIDlet (MIDlet-Name), sua versão (MIDlet-Version) e seu fornecedor (MIDlet-Vendor). Outros atributos condicionalmente
obrigatórios incluem o nome de classe para cada MIDlet no JAR (MIDlet-<n> em que "n"
começa em 1 e aumenta em um para cada MIDlet adicional), a configuração de Java ME necessária (MicroEdition-Configuration)
e seu perfil (MicroEdition-Profile). Esses atributos são condicionalmente obrigatórios porque podem ser fornecidos em um
Java Application Descriptor (JAD) externo.
O arquivo JAD é um arquivo de texto opcional que acompanha o arquivo JAR do MIDlet. Ele é utilizado pela plataforma de
destino para determinar se o JAR que ele acompanha contém MIDlets compatíveis; o JAR real é transferido por download
somente se todos os pré-requisitos forem atendidos. O arquivo JAD suporta os mesmos atributos que o manifesto JAR do
MIDlet. Além de um MIDlet-Name, MIDlet-Version e MIDlet-Vendor correspondentes, o arquivo JAD deve conter a URL
(MIDlet-Jar-URL) e o tamanho (MIDlet-Jar-Size) do arquivo JAR que ele descreve.
|  |