primeiro-MIDlet

Olá pessoal. Depois de um tempo sem escrever para o blog estou de volta dando continuidade a série sobre o desenvolvimento para dispositivos móveis com Java ME. Para entender melhor, sugiro ver os links “Java ME: Uma Introdução” e “Preparando ambiente para desenvolvimento de aplicações Java ME no Ubuntu“.

Bem, já está na hora de começarmos a programar um pouquinho, não é mesmo? Então vamos lá.

Primeiro, abra o Eclipse e crie um novo MIDlet Project com o nome “Meu MIDlet” (caso apareça um erro, siga os passos da seção “Eclipse IDE” em “Preparando ambiente para desenvolvimento de aplicações Java ME no Ubuntu“) e clique em Finish. Caso o Eclipse pergunte se você deseja mudar para a Java ME Perspective, diga que sim e uma nova perspectiva será aberta automaticamente.

Novo MIDlet Project

Novo MIDlet Project

Uma tela como a seguinte será aberta:

Java ME Perspective

Java ME Perspective

Salve e feche a tela do Application Descriptor (não será preciso mudar nada nele por enquanto).

Clique no botão para adicionar um novo pacote Java com o nome myMIDLet. Clique com o botão direito em cima do pacote recém-criado e vá em New -> Other -> Java ME -> Java ME MIDlet. Clique em Next, coloque o nome da MIDlet de MyMIDlet e então clique em Finish (não desmarque nada).

Um novo MIDlet

Um novo MIDlet

O código inicial da nossa MIDlet deve estar como este:

import javax.microedition.midlet.MIDlet;

public class MyMIDlet extends MIDlet
{
	public MyMIDlet()
	{

	}

	protected void destroyApp(boolean unconditional)
			throws MIDletStateChangeException
	{

	}

	protected void pauseApp()
	{

	}

	protected void startApp() throws MIDletStateChangeException
	{

	}

}

Todo MIDlet deve ter esses três métodos e um construtor default. Agora vou resumir o que cada um faz. Ei, você disso que a gente ia programar? Certo, nós vamos, mas primeiro tem alguns conceitos que serão fundamentais durante o andamento da ‘série’, então preste atenção. Resumindo, esses método fazem o seguinte:

MyMIDlet(): Invocado quando uma instância da MIDlet é criada. Geralmente o construtor não faz nada mais do quê inicializar os componentes utilizados dentro do aplicativo. Aí vai uma dica importante e que mais tarde você irá entender, por isso grave bem: sempre inicialize todo o que for usar no MIDlet dentro do seu construtor. SEMPRE!

destroyApp(boolean unconditional): o sistema que gerencia nossas MIDlet no celular (Application Management System – AMS) invoca esse método quando o aplicativo precisa ser terminado. Após a invocação desse método todos os recursos alocados para a MIDlet são desalocados.

pauseApp(): o AMS invoca esse método quando a MIDlet precisa ser interrompida para dar lugar a algo de prioridade mais alta, como uma ligação ou outra aplicação por exemplo. Os recursos alocados para a MIDlet não são perdidos após a invocação desse método.

startApp(): invocado quando a aplicação é ‘estartada’ ou está rodando no celular. Esse método deve pelo menos lançar o aplicativo e mostrar a primeira tela.

Num dado momento, nossa MIDlet deverá estar em um desses estados:

MIDlet Life Cycle

MIDlet Life Cycle

  • Pausada: não pode recebe eventos do sistema e espera para ser reativada ou destruída.
  • Ativa: recebe eventos do sistema e pode interagir com o usuário.
  • Destruída: A aplicação é destruída, ou seja, todos os seus recursos são desalocados.

Lembra da nossa dica sobre inicializar tudo no construtor? Se eu inicializar tudo fora do construtor, sempre que o MIDlet passar do estado Ativo para qualquer Pausado e retornar para o Ativo, todos os recursos terão que ser reinicializados. Se tudo ficar dentro do construtor esses recursos serão inicializados na hora da construção da MIDlet e só serão desalocados se o MIDlet for destruído. 😉

O gerenciador de aplicativos, o AMS, se comunica com nossa MIDlet através desses métodos. “Essa comunicação é uma via de duas mãos. Por exemplo, assim como o gerenciador de aplicativos pode fazer uma pausa em uma MIDlet (para permitir que o usuário responda a uma ligação telefônica recebida), uma MIDlet pode fazer um pedido de pausa…” [1].

Agora que já entendemos os métodos que apareceram está na hora de colocá-los para trabalhar. Vamos fazer o clássico ‘Hello World’ e em outros posts iremos aprofundar nossos estudos sobre MIDlets.

Veja o código abaixo. Copie-o e coloque para rodar.

Se tudo der certo um emulador de dispositivos irá aparecer como texto Hello World escrito na tela.

MIDlet em funcionamento

MIDlet em funcionamento

Agora vamos dar uma olhada mais detalhada em nosso código.

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class MyMIDlet extends MIDlet
{

	// Já, já falaremos sobre essas classes.
	private Display display;
	private Form myForm;
	
	public MyMIDlet()
	{
		// Pedimos ao AMS que nos deixe 'mexer' no display
		display = Display.getDisplay(this);
		
		// Pense no form como um JForm de SWING
		myForm = new Form("My First MIDlet");
		// Adiciona uma String ao myForm
		myForm.append("Hello World!");
	}

	protected void destroyApp(boolean unconditional)
			throws MIDletStateChangeException
	{
		// Nada aqui.
	}

	protected void pauseApp()
	{
		// Nada aqui também (por enquanto).
	}

	protected void startApp() throws MIDletStateChangeException
	{
		// Coloca o myForm em evidência.
		display.setCurrent(myForm);
	}

}

A classe que mais chama atenção é Display. Cada MIDlet (isso mesmo, cada MIDlet) tem uma referência para um e apenas um objeto Display. Esse objeto tem a capacidade de obter informações sobre a tela atual e inclui métodos para solicitar que esse objetos (como o nosso myForm) sejam exibidos. É exatamente isso que acontece dento do método startApp(), com display.setCurrent(myForm). Tente ver o objeto Display como o guardião da tela do celular. Ele é que decide quem será mostrado, onde será mostrado, que formato terá e várias outras coisas.

Embora haja apenas um Display por MIDlet, dentro de uma MIDlet podem existir diversos objetos para serem exibidos. Ficou confuso? Vamos ver isso com mais calma em posts futuros, não se preocupe. 😉

Como o objeto Display é muito especial, eu não posso sair por aí instanciando vários objetos desse tipo (eles acabariam brigando pra ver quem tomaria de conta da tela). Então como eu faço para conseguir um objeto desse tipo? Simples. Dentro do construtor da nossa MIDlet observe que nosso atributo ‘display’, do tipo Display, consegue o controle da tela através de uma chamada para um método estático da classe Display. Essa referência é constantemente mantida durante a existência da MIDlet em uma variável.

E o myForm? Bem, pense no myForm como um container onde é possível armazenar alguns tipos de objetos, como Strings, StringItems, Images, e outros. Eu adiciono esse objetos através do método append() da classe Form.

Chegamos ao final de mais um episódio da nossa série. Até a próxima pessoal.

Referências

[1] Core J2ME – Configuração e MIDP

[2] Beginning Java ME Platform.

Anúncios