border=0>utacionais, o complicador é quando esse mesmo ambiente tem recursos de armazenamento restrito e, ainda, uma arquitetura de hardware e software bem diferente da encontrada em desktops ou grandes servidores, como é o caso dos dispositivos móveis. Essas diferenças podem ser observadas tanto do ponto de vista do usuário (ergonomia de hardware e software), quanto do ponto de vista do desenvolvedor (ferramentas de software, APIs e recursos). Os telefones celulares conseguiram alcançar uma popularidade quase tão grande quanto a observada na utilização de computadores pessoais a partir da década de 80. Mas, assim como todos os dispositivos móveis, eles também trazem consigo algumas dificuldades, como, problemas relacionados à ergonomia do teclado, uma interface visual simples porém limitada e a dependência de baterias que requerem recarga constante.

Nesse artigo, serão apresentadas as APIs que tratam da persistência de dados disponíveis no J2ME. Inicialmente, alguns fundamentos serão abordados e a seguir o pacote javax.microedition.rms, responsável pelo gerenciamento de registros, será detalhado através de definições e do uso de exemplos. A descrição do funcionamento de uma classe, quatro interfaces e cinco exceções, é tudo do que trata esse artigo. Comprovando, por incrível que pareça, toda a simplicidade e eficiência do pacote RMS.

 J2ME e perfil MIDP

O Java 2 Micro Edition (J2ME) foi desenvolvido para contemplar toda a diversidade computacional existente nos dispositivos móveis. A tecnologia J2ME conseguiu abstrair conceitos e técnicas para homogeneizar o desenvolvimento em dispositivos móveis de forma completamente transparente. O perfil de informação de dispositivos móveis, conhecido como MIDP (Mobile Information Device Profile) surgiu como solução para diferenciar alguns dispositivos que apesar de possuirem características semelhantes, ainda assim são tecnologicamente diferentes. O perfil MIDP contempla os aparelhos celulares e é o responsável pela definição das APIs necessárias para a persistência de dados.

RMS

O conjunto de classes responsáveis por armazenar e recuperar dados é conhecido como Record Management System (RMS) ou sistema de gerenciamento de registros. O RMS permite manter os dados persistentes entre várias chamadas de um MIDlet (aplicação baseada no MIDP). Segundo a especificação MIDP, deve haver, disponível no dispositivo, pelo menos 8 kbytes de memória não-volátil (ROM) para que os aplicativos persistam dados. Exemplos de memória não-volátil seriam ROM, flash e etc. Em teoria, todo o espaço livre na memória ROM, ou flash de um dispositivo móvel, estaria disponível aos aplicativos para persistirem seus dados.

A unidade básica de dados mantida pelo RMS é conhecida como RecordStore ou repositório de registro (RR). Um RR pode ser comparado a uma tabela ou entidade no modelo relacional e é identificado por um nome de até 32 caracteres. Cada registro é composto por um identificador único e um array de bytes, onde os dados do registro serão armazenados. Um RR mantém em sua estrutura um conjunto de registros que podem ter tamanhos variáveis.

Um MIDlet é um aplicativo executado em um dispositivo móvel. Para isso, ele precisa ser empacotado em um arquivo Java (JAR). Um MIDlet pode, ainda, ser empacotado junto com outros MIDlets em um mesmo arquivo JAR, formando um conjunto. Tanto um MIDlet quanto um conjunto de MIDlets, formam uma aplicação J2ME única e completa. Cada conjunto de MIDlets ou um MIDlet, pode criar e manter diversos RRs, podendo, inclusive, compartilhá-los entre si, com o detalhe de que os nomes atribuídos aos RRs precisam ser únicos. A versão 1.0 do MIDP não permitia o compartilhamento de RRs entre MIDlets empacotados em diferentes arquivos JAR. A versão 2.0 do MIDP corrigiu essa limitação, permitindo assim o compartilhamento de um RR por todas os MIDlets instalados no dispositivo.

As APIs do RMS não fornecem recurso para travamento de registros. A implementação de um RR garante que a operação de persistência será realizada de forma indivisível e síncrona evitando eventuais inconsistências no caso de acessos múltiplos. Se for necessário que um MIDlet utilize múltiplas threads para acessar um RR, é necessário toda uma atenção para manter a consistência dos dados. Também, é responsabilidade da implementação no dispositivo fazer todo o possível para garantir a integridade e a consistência dos RRs durante operações normais ao seu uso como reinicialização, troca de baterias e etc.

Durante a desinstalação de um MIDlet do dispositivo, os armazéns de dados pertencentes a ele são removidos automaticamente.

Classe RecordStore

Qualquer operação de inserção, atualização e exclusão de registros em um RR provocam a atualização automática do seu número de versão e da data em que ocorreu a mudança. O número da versão de um RR pode servir como referencial, por exemplo, para algoritmos de replicação. É uma maneira interessante de detectar quantas vezes um RR foi modificado. Esses dois valores, o número da versão e a data da atualização, podem ser recuperados através do uso dos métodos getVersion() e getLastModified() respectivamente. A Tabela 1 lista mais algumas funcionalidades da classe RecordStore.

A Listagem 1 contém um exemplo simples que cria um RR, preenche-o com dois registros e a seguir obtém e apresenta algumas informações sobre o RR. A Figura 1 apresenta a mesma aplicação sendo executada no emulador.

           

Tabela 1. Alguns métodos da classe RecordStore.

Funcionalidade

Método Correspondente

Para fechar o RR.

rr.closeRecordStore()

Para excluir o RR inteiro.

RecordStore.deleteRecordStore(“produto”)

Para obter uma lista com todos os RRs presentes no conjunto de MIDlets.

String[] Arm = RecordStore.listRecordStores()

Para obter o nome do RR.

String Nome = rr.getName()

Para saber a data da última atualização no RR. O detalhe aqui é que essa data está no formato long e pode ser convertido  para o tipo Data.

long UltimaMudanca = rr.getLastModified()

Para obter a versão do RR.

int vs = rr.getVersion()

Para obter o número de registros existentes no RR.

int nr = rr.getNumRecords()

Para obter o total de bytes ocupado pelo RR.

int tb = rr.getSize()

Para obter o espaço total ainda disponível para o RMS.

int getSizeAvailable()

 

image001.png

Figura 1. Informações sobre um RecordStore.

 

1:     /* ExemploRMS.java

2:     */

3:     import javax.microedition.rms.*;

4:     import javax.microedition.midlet.*;

5:     import javax.microedition.lcdui.*;

6:      

7:     public class ExemploRMS extends MIDlet implements CommandListener

8:     {

9:       private List lsLista; // Lista de Informações

10:    private Command cmSair;

11:    

12:    private RecordStore rr = null;

13:    

14:    public ExemploRMS()

15:    {

16:      cmSair = new Command("Sair", Command.EXIT, 1);

17:      lsLista = new List("Informações RR", List.IMPLICIT);

18:      lsLista.addCommand(cmSair); // Janela com apenas um comando...Sair

19:      lsLista.setCommandListener(this); // Registrando um receptor para o evento Sair

20:      

21:      String str;

22:      byte[] Registro;

23:      try

...

Quer ler esse conteúdo completo? Tenha acesso completo