×
Namespaces

Variants
Actions
(Difference between revisions)

Como utilizar uma API opcional em Java ME

From Nokia Developer Wiki
Jump to: navigation, search
hamishwillee (Talk | contribs)
m (Hamishwillee - Fix categories)
lpvalente (Talk | contribs)
m (Lpvalente -)
 
Line 19: Line 19:
 
|author= [[User:Grahamhughes]]
 
|author= [[User:Grahamhughes]]
 
}}
 
}}
Como detectar a presença de uma API opcional (como a API Location) em tempo de execução, e usá-lo somente se ele estiver disponível. Por exemplo, para desenvolver um aplicativo que funciona no dispositivo sem a Location API, mas pode tornar-se consciente de localização em dispositivos que têm a API Location, sem a necessidade de várias compilações.
+
 
 +
{{Abstract|Este artigo demonstra como detectar a presença de uma API opcional (como a API Location) em tempo de execução, e usá-lo somente se ele estiver disponível.}} Por exemplo, para desenvolver um aplicativo que funciona no dispositivo sem a Location API, mas pode tornar-se consciente de localização em dispositivos que têm a API Location, sem a necessidade de várias compilações.
  
 
Este exemplo fará referência para a API Location, mas se aplica igualmente a outras APIs.
 
Este exemplo fará referência para a API Location, mas se aplica igualmente a outras APIs.

Latest revision as of 01:51, 10 November 2013

Article Metadata

Artigo
Tradução:
Por thiagobrunoms
Última alteração feita por lpvalente em 10 Nov 2013

Este artigo demonstra como detectar a presença de uma API opcional (como a API Location) em tempo de execução, e usá-lo somente se ele estiver disponível. Por exemplo, para desenvolver um aplicativo que funciona no dispositivo sem a Location API, mas pode tornar-se consciente de localização em dispositivos que têm a API Location, sem a necessidade de várias compilações.

Este exemplo fará referência para a API Location, mas se aplica igualmente a outras APIs.

Contents

[edit] Advertência

Esta técnica deve funcionar em toda a máquina virtual Java compatível com a especificação VM incluindo a especificação CLDC. No entanto, pode haver algumas VMs que realizam algum tipo de instalação de verificação do tempo, ou otimização de re-compilação do bytecode Java, que impedem que esta técnica funcione. Não funciona no modelo Motorola T720 (dispositivo MIDP-1). search

[edit] Teoria

A fim de executar o código em uma classe Java, cinco etapas devem ser concluídas.

  1. Carregamento. O arquivo de classe é localizado e carregado na memória heap do Java. Isto acontece quando a classe é necessária para o carregamento de outra classe, ou quando Class.forName () é invocado.
  2. Verificação. O byte-code é verificado para garantir que representa um programa em Java correto e válido. Isso sempre ocorre antes da preparação
  3. Preparação. A memória é alocada para os campos estáticos da classe, e inicializado com valores padrão (0, 0,0, '\ 0', falso ou nulo). Isso sempre ocorre antes da resolução.
  4. Resolução. Qualquer outra classe referenciada por esta classe são localizadas e carregadas.
  5. Inicialização. A classe de inicialização é executada. Isto inclui qualquer bloco static{} na definição da classe, e qualquer código utilizado para inicialização de campos estáticos (statics). Este passo é disparado na primeira tentativa de criar a instância da classe, para acessar algum dos campos estáticos, ou para invocar algum dos métodos estáticos.

Resolução é o passo chave. Se usarmos uma classe que faz referência a uma API inexistente, este é o ponto onde o código não irá funcionar. Precisamos ter certeza de que este processo só ocorre se a API está presente.

Eu não expliquei quando o processo de resolução irá funcionar. Isto porque varia entre diferentes implementações da JVM. Diferentes implementações da JVM executam este passo em tempos diferentes. Aqui encontram-se dois exemplos:

  • Mais cedo: A VM realiza verificação, preparação e resolução completa da classe imediatamente após o carregamento. Isso normalmente resulta em um conjunto de classes que estão sendo carregados e resolvido, muitas vezes a aplicação inteira.
  • Mais tarde: A VM pode esperar até que as referências da classe externa precisam ser resolvidas, a fim de executar código na classe.

E existem variações entre os dois.

Em VMs que a resolução de uso final, pode ser o suficiente para não executar qualquer código que se refere à API em falta. No entanto, esse código pode quebrar em VMs que a resolução de uso mais cedo.

Para ter certeza que o nosso código irá funcionar, precisamos ter certeza de que nenhuma classe é sempre carregada que refere-se a API opcional, a menos que a API está presente.

[edit] Técnica

[edit] Criar um pacote separado

Isto é opcional, mas torna a técnica "mais seguro". Vamos dizer que a nossa aplicação está no pacote:

com.mycompany.myapplication pacote;

Nenhuma classe neste pacote terá qualquer referência à localização da API. Nós vamos colocar todos os serviços de localização de código em um pacote separado:

com.mycompany.locationservices pacote;

Ao fazer isso, nós podemos parar de codificar na aplicação do código de acesso local diretamente, usando pacote de privacidade. Isto fará mais sentido depois.

[edit] Crie uma classe abstrata

Nós precisamos criar uma classe abstrata no pacote de serviços de localização. Esta será a única classe pública em que o pacote, e é o único que não deve utilizar uma parte do local da API. Ele irá definir uma interface através da qual vamos utilizar serviços de localização.

package com.mycompany.locationservices;
 
public abstract class LocationProvider {
// define a interface através da qual iremos accessar as informações de localização
public abstract double getLatitude();
public abstract double getLongitude();
 
/**
* este método será utilizado para obter informações da classe LocationProvider
*/
public static LocationProvider getProvider() throws ClassNotFoundException {
LocationProvider provider;
try {
// Este trecho irá lançar se a JSR-179 não estiver disponível
Class.forName("javax.microedition.location.Location");
 
// mais sobre esta classe depois!
Class c = Class.forName("com.mycompany.locationservices.LocationImplementation");
provider = (LocationProvider)(c.newInstance());
} catch (Exception e) {
throw new ClassNotFoundExcepion("API Location não encontrada!");
}
return provider;
}
}

Esta classe não faz referência a classes em JSR-179, nem a qualquer outra classe do pacote locationservices, excetopara referências em Strings em chamadas para Class.forName (). Estes não fará com que as classes sejam carregadas até que sejam executadas, e então eles vão lançar exceções (que podem ser capturadas e manipuladas), se existir um problema.

Uma vez que esta será a única classe pública no pacote, ela será a única classe que pode referir-se a partir da aplicação principal. Porque ele não faz referência a quaisquer categorias de localização, é seguro fazer referência a ela.

A classe LocationImplementation não será pública, e por isso deve estar no mesmo pacote que LocationProvider para evitar uma exceção do tipo IllegalAccessError.

[edit] Criando uma Implementação

Agora nós precisamos da classe LocationImplementation discutida anteriormente.

package com.mycompany.locationservices;
 
import javax.microedition.location.*;
 
class LocationImplementation extends LocationProvider {
 
LocationImplementation() {
/*
Nós devemos ter um construtor sem parâmetros, ou a chamada a Class.newInstance() não pode
criar uma instância desta classe.
*/
}
 
// implemente os métodos abstratos de LocationProvider
 
public double getLatitude() {
// fazer qualquer coisa!
}
 
public double getLongitude() {
// fazer qualquer coisa!
}
}

Note que essa classe não é pública. Isso impede que as classes fora deste pacote use-a, e é um protetor seguro contra acessos em outro lugar (e arruinando o nosso plano de esperteza).

Quaisquer outras classes necessárias para apoiar este pode ser criado neste pacote, mas torne-os pacotes privados (não público) também.

[edit] Utilizando o LocationProvider

Para utilizar isto na aplicação é muito fácil agora.

try {
LocationProvider provider = LocationProvider.getProvider();
double latitude = provider.getLatitude();
double longitude = provider.getLongitude();
} catch (ClassNotFoundException cnfe) {
// não está disponível a API Location neste dispositivo
}
This page was last modified on 10 November 2013, at 01:51.
146 page views in the last 30 days.