WirelessBR

WirelessBr é um site brasileiro, independente, sem vínculos com empresas ou organizações, sem finalidade  comercial,  feito por voluntários, para divulgação de tecnologia em telecomunicações 

Tutorial de programação J2ME 
Parte 2  
Plataforma Java 2 Micro Edição (J2ME)

Texto original de Lamont Adams, Special to CNETAsia
Tradução: Renato Martins (*)

Diga "alô" ao J2ME: Um tutorial de programação
Say hello to J2ME: A programming tutorial 

Dê o primeiro passo em direção a aprender como programar em Java 2, plataforma de Micro Edição (J2ME) com a famosa aplicação "Hello World" 

Java 2, Micro Edição (J2ME) dá aos desenvolvedores Java a oportunidade de aproveitar suas habilidades em programação numa grande variedade de dispositivos móveis, como telefones celulares, PDAs, etc.. Sem sombra de dúvida, dispositivos móveis são diversos em suas capacidades e poder de processamento. J2ME cria uma camada de abstração, minimizando estas diferenças ao definir configurações e interfaces, as quais, juntas, provêem uma plataforma completa e uma Interface para Programação de Aplicativos (API). Estas APIs possibilitam o desenvolvimento de aplicativos em qualquer dispositivo que possua suporte a estas. 
A Configuração Limitada de Dispositivos Conectados (Connected Limited Device Configuration - CLDC) e o Perfil de Informações para Dispositivos Móveis (Mobile Information Device Profile - MIDP) combinados estão presentes na maioria de dispositivos móveis de baixo custo, como PDAs, telefones celulares e pagers two-way. Neste artigo, você terá a possibilidade de começar a aprender J2ME ao construir um pequeno aplicativo de teste.

Hello World!
O processo de fazer uma build, instalar, e rodar um aplicativo MIDP é bem diferente daquele utilizado normalmente em aplicativos Java. Isto é um tópico diferente, que virá num artigo futuro. Por enquanto, você terá de se contentar em examinar a estrutura de nosso aplicativo teste. Logo abaixo encontra-se o código para um aplicativo "Hello World" e logo abaixo a figura mostrando o resultado. 

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class HelloJ2ME extends MIDlet implements CommandListener
{
 private Display display;
 private TextField caixaDeTextoHello;
 private Command comandoDeSaida;
 private Form formularioPrincipal;
 public HelloJ2ME()
 {
  // Armazenar ponteiro para o objeto “Display”, passando a 
  // instância deste aplicativo
  display = Display.getDisplay(this);
  //Criar o formulário principal (janela)
 formularioPrincipal = new Form("HelloJ2ME");
  //Criar o botão de comadno de saída do aplicativo
 comandoDeSaida = new Command("Exit", Command.SCREEN,1);
  //Create a single-line text field 15 characters long
  //with the label "Text"
 caixaDeTextoHello = new TextField("Text","Hello World!",15,TextField.ANY);
  //Adicionar os comandos do nosso aplicativo e
  //o nosso método que tratará dos comandos
  // Adicionar o comando de saída à nossa janela 
  formularioPrincipal.addCommand(comandoDeSaida);
  // Adicionar a caixa de texto contendo o texto “Hello World”
  // à nossa janela
  formularioPrincipal.append(caixaDeTextoHello);
  // Registrar o método que tratará os comandos
  // com o sistema
  formularioPrincipal.setCommandListener(this); 
 }
 public void startApp()
 {
  // Setar meu formulário principal como 
  // o objeto ativo. Em outras palavras: nossa
  // janela é a que aparece na tela!
  display.setCurrent(formularioPrincipal);
 }
 // Método que trata o comando de pausa vindo do sistema
 public void pauseApp()
 {
        /*aplicativo está sendo pausado*/ 
 }
 // Método que destroi o nosso aplicativo
 // O sistema chama este método quando precisa
 public void destroyApp(boolean incondicional)
 {
         /*nosso aplicativo está terminando aqui*/
 }
 public void commandAction(Command comando, Displayable s)
 {
  // Alguém clicou na janela
  // Vamos checar se clicaram no comando de saída
  if (comando == comandoDeSaida)
  {
     // Clicaram no comando de saída!
     // Temos de terminar nosso aplicativo manualmente
     // chamando o método “destroyApp”, passando argumento
     // booleano “falso”
     destroyApp(false);
     // Agora temos de notificar o gerente que nosso aplicativo
     // foi terminado
     notifyDestroyed();
  }
 }
}

O resultado: 


Com certeza, não é de impressionar, eu sei, mas bons exemplos raramente são. Como você pode ver, nosso exemplo J2ME estende ao aplicativo a classe base MIDP através da classe MIDlet e importa dois namespaces: javax.microedition.midlet e javax.microedition.lcdui. Um inclui a classe base MIDIlet para o nosso aplicativo, enquanto o outro provê a interface gráfica (Graphical User Interface - GUI), respectivamente.

A classe MIDlet provê três métodos abstratos que são usados pela aplicação. Estes métodos são chamados à partir do gerenciador de aplicações do dispositivo, e é usado para comunicar com os aplicativos que estão rodando. O método "startApp" é chamado imediatamente depois do construtor e cada vez que um aplicativo é ativado (está visível). Isto implica que este método não é chamado somente ao aplicativo ser iniciado. Uma aplicação pode fazer a transição entre os estados de ativa e inativa muitas vezes durante o tempo em que está sendo rodada, portanto você deve evitar colocar código de inicialização que só pode ser rodado uma única vez. Um bom exemplo é o código utilizado para inicializar a GUI, que deve ser colocado no construtor ao invés desse método. 

O método "destroyApp" é chamado pelo gerencaidor de aplicativos para indicar que uma aplicação está prestes à ser terminada. Não como o método "startApp", este método será chamado uma única vez durante o tempo de execução de uma aplicativo, portanto é recomendado o uso de "código de limpeza" aqui. De fato, por causa do fato da MIDP não incluir em sua funcionalidade a capacidade de finalizar seus objetos, você terá de terá de fazer "a limpeza" aqui mesmo. Ao mesmo tempo, entretanto, um dispositivo móvel típico é bem menos estável que uma plataforma típica de desenvolvimento e será constantemente desligado e/ou reinicializado pelo usuário. Portanto, você não pode contar com a execução de "destroyApp" toda as vezes.

O método abstrato remanescente, "pauseApp", pode ser considerado um tanto quanto esquisito quando analisado pela primeira vez. Este método é utilizado para notificar o aplicativo que está rodando está para ser pausado porque o usuário acabou de começar a rodar um outro aplicativo ou está utilizando uma função do dispositivo que prevenirá seu aplicativo de continuar rodando. Por causa do fato da maioria dos dispositivos móveis não terem poder de processamento para estarem realmente "multitasking"(executando várias funções ao mesmo tempo), este método provavelmente será chamado com uma certa freqüência. Você também deve manter em mente que os recursos sendo utilizados pelo seu aplicativo devem ser liberados neste momento. Quando a sua aplicação volta à rodar, o método "startApp" será chamado pelo gerenciador de aplicativos. 

Comunicando com o gerenciador de aplicações (application manager)

Claramente, toda comunicação tem que acontecer em ambas direções, ou seja, ir e vir, para ser eficiente. Aplicações MIDP não são exceção nenhuma. O MIDlet provê um conjunto de métodos que você pode usar para comunicar-se com o gerenciador de aplicações: 
· NotifyDestroyed fala ao gerenciador que a sua aplicação quer ser terminada. Ao chamar este método, o resultado não será ter o método "destroyApp" ser executado, portanto você terá de chamá-lo manualmente.
· NotifyPaused notifica o gerenciador que a sua aplicação quer ser pausada.
· ResumeRequest solicita que o gerenciador volte a rodar a sua aplicação, se este estiver pausada. 
· GetAppProperty busca as informações de configuração de uma aplicação. Tal informação pode ser acessada através do fornecimento de um manifesto ou um arquivo de descrição de um aplicativo (application descriptor file). Em outras palavras, este método dá acesso a um arquivo de inicialização privada. 

Gerenciando a interface

O pacote javax.microedition.lcdui contém os elementos de interface gráfica utilizados por aplicativos MIDP.

Conheça a família

Há basicamente três famílias de componentes GUI definidos no pacote "lcdui", que são agrupados baseados em suas classes base: Componentes de tela; Componentes de item; e Componentes diversos de display. 

Componentes de tela 

Os componentes de tela são descendentes da classe abstrata "Screen" e provêem os widgets de interface gráfica em forma de janela. O objeto "Form" (formulário) usado no exemplo "HelloJ2ME" é um descendente da classe "Screen", que contém e forma controles de interface gráfica. Outros componentes de "Screen" incluem alertas (Alert), caixas de diálogo (dialog box), listas (List) e caixas de texto (TextBox), sendo esta última uma forma de entrada de texto que suporta múltiplas linhas.

Componentes de item 

Os componentes de item são controles tradicionais, como o campo de texto "Hello World!" na nossa aplicação exemplo. Estes controles todos são descendentes da classe "Item". Esta classe provê uma API uniforme para colocar-se etiquetas de nome, tratamento de eventos, e exibição de controles. ChoiceGroup, DateField, Gauge, ImageItem e StringItem são outros componentes da classe Item. 

Componentes diversos de display 

Todos os componentes diversos de display são, na sua grande maioria, descendentes da classe de hierarquia mais alta e abstrata "Displayable". Este grupo inclui componentes como a classe "Command", que integra os botões de comando; "Ticker", que integra as caixas de texto rolantes; "Graphics", que exibe os gráficos; e "Choice", que é uma interface de manipulação de seleções pré-definidas, que, por sua vez, não se encaixam em qualquer outra categoria.

Esta figura ilustra a hierarquia destes componentes. 


Os membros do pacote "lcdui" 


Toda a parafernália gráfica é gerenciada por um objeto "Display", à partir do qual, cada aplicação tem acesso à uma única e privada instancia. Esta instancia pode ser obtida através do método estático "Display.getDisplay". É de costume manter uma única referência à esta instância em uma variável, da mesma maneira que é feita no construtor do nosso exemplo "HelloJ2ME". Além dos métodos para concentrar o foco da tela em um elemento em particular (setCurrent) e descobrir qual o elemento com o foco (getCurrent), a classe "Display " também expõe vários outros métodos muito úteis para obtenção de informação sobre as capacidades do display do dispositivo. Entre estas capacidades estão a detecção de suporte à cores (isColor) e quantas cores são suportadas (numColors). 

Coisas para lembrar-se 

Vamos terminar este tutorial com uma curta lista de coisas para manter em mente ao desenvolver aplicações em Java para uma plataforma móvel. Primeiro, você terá que lidar com uma biblioteca de classes bem limitada: sem refletir, JNI, ou, como mencionado antes, suporte à finalizações. Segundo, você terá que lidar com altíssimas restrições quanto ao uso de memória, já que a maioria dos dispositivos rodando MIDP terá menos de 100K de memória dinâmica disponíveis. Como resultado, você terá de ser bem cuidadoso com a memória utilizada pelos algoritmos que costuma usar. Finalmente, tenha em mente que qualquer conectividade com redes será limitada em largura de banda e, provavelmente, esporádica. 

Fim da tradução.


(*) Renato Passarinho Martins (renatopmartins@yahoo.com), tem 27 anos e formou-se em Engenharia Elétrica no Instituto Nacional de Telecomunicações de Santa Rita do Sapucaí (INATEL) em Dezembro de 1998. Já trabalhou como instrutor de telefonia celular do centro de treinamento da Promon/Nortel. Também trabalhou como engenheiro de RF para a Agilent Technologies, prestando serviços de otimização para a Lucent Technologies na digitalização do sistema de telefonia celular da Teslesp Celular na área da grande São Paulo. Depois trabalhou por três anos na Motorola como engenheiro de desenvolvimento de software. Entre os produtos que colaborou no desenvolvimento estão toda a família digital de telefones StarTac, v60, v120 e t270. Hoje  trabalha para um líder mundial de desenvolvimento de software para computadores pessoais e sistemas embarcados diversos.

 

Anterior                    Home WirelessBR               Próxima