Em um aplicativo Android, há algo errado com a seguinte abordagem:
public class MyApp extends android.app.Application {
private static MyApp instance;
public MyApp() {
instance = this;
}
public static Context getContext() {
return instance;
}
}
e passá-lo para todos os lugares (por exemplo, SQLiteOpenHelper) onde o contexto é necessário (e não está vazando, é claro)?
android
android-context
yanchenko
fonte
fonte
<application>
nó do seu arquivo AndroidManifest.xml para incluir a seguinte definição de atributo:android:name="MyApp"
. O MyApp precisa estar no mesmo pacote que seu manifesto faz referência.Respostas:
Existem alguns problemas em potencial com essa abordagem, embora em muitas circunstâncias (como no seu exemplo) funcione bem.
Em particular, você deve ter cuidado ao lidar com qualquer coisa que lide com o
GUI
que exige aContext
. Por exemplo, se você passar o aplicativo Context para oLayoutInflater
diretório, receberá uma exceção. De um modo geral, sua abordagem é excelente: é uma boa prática usar umActivity's
Context
dentro dissoActivity
eApplication Context
ao passar um contexto além do escopo de umActivity
para evitar vazamentos de memória .Além disso, como alternativa ao seu padrão, você pode usar o atalho para chamar
getApplicationContext()
umContext
objeto (como uma Atividade) para obter o Contexto do Aplicativo.fonte
LayoutInflator
apenas funcionou para mim. Deve ter sido alterado nos últimos três anos.Na minha experiência, essa abordagem não deve ser necessária. Se você precisar do contexto para qualquer coisa, normalmente é possível obtê-lo por meio de uma chamada para View.getContext () e, usando o resultado
Context
obtido, pode chamar Context.getApplicationContext () para obter oApplication
contexto. Se você estiver tentando obter oApplication
contexto disso a partir de um,Activity
você sempre pode chamar Activity.getApplication (), que deve ser transmitido conforme oContext
necessário para uma chamadaSQLiteOpenHelper()
.No geral, não parece haver um problema com sua abordagem para essa situação, mas ao lidar com
Context
apenas verifique se você não está vazando memória em nenhum lugar, conforme descrito no blog oficial do Google Android Developers .fonte
Algumas pessoas perguntaram: como o singleton pode retornar um ponteiro nulo? Eu estou respondendo a essa pergunta. (Não consigo responder em um comentário porque preciso postar código.)
Pode retornar nulo entre dois eventos: (1) a classe é carregada e (2) o objeto dessa classe é criado. Aqui está um exemplo:
Vamos rodar o código:
A segunda linha mostra que Y.xinstance e X.yinstance são nulos ; eles são nulos porque as variáveis X.xinstance e Y.yinstance foram lidas quando eram nulas.
Isso pode ser corrigido? Sim,
e este código não mostra nenhuma anomalia:
MAS isso não é uma opção para o
Application
objeto Android : o programador não controla a hora em que é criado.Mais uma vez: a diferença entre o primeiro exemplo e o segundo é que o segundo exemplo cria uma instância se o ponteiro estático for nulo. Mas um programador não pode criar o objeto de aplicativo Android antes que o sistema decida fazê-lo.
ATUALIZAR
Mais um exemplo intrigante, onde estão os campos estáticos inicializados
null
.Main.java :
E você obtém:
Observe que você não pode mover a declaração da variável estática uma linha para cima, o código não será compilado.
fonte
Classe de aplicação:
Declare o aplicativo no AndroidManifest:
Uso:
fonte
Você está tentando criar um wrapper para obter o Contexto do Aplicativo e existe a possibilidade "
null
" de retornar o ponteiro.De acordo com o meu entendimento, acho que é melhor abordagem para chamar qualquer um dos 2
Context.getApplicationContext()
ouActivity.getApplication()
.fonte
É uma boa abordagem. Eu também o uso. Eu apenas sugeriria substituir
onCreate
para definir o singleton em vez de usar um construtor.E desde que você mencionou
SQLiteOpenHelper
:onCreate ()
você também pode abrir o banco de dados.Pessoalmente, acho que a documentação errou ao dizer que normalmente não há necessidade de subclassificar Application . Eu acho que o oposto é verdadeiro: você deve sempre subclassificar Application.
fonte
Eu usaria o Contexto do Aplicativo para obter um Serviço do Sistema no construtor. Isso facilita os testes e os benefícios da composição
A classe de teste usaria o construtor sobrecarregado.
O Android usaria o construtor padrão.
fonte
Eu gosto, mas sugiro um singleton:
fonte
new
o aplicativo sozinho (com a possível exceção dos testes de unidade). O sistema operacional fará isso. Você também não deve ter um construtor. É para isso queonCreate
serve.Estou usando a mesma abordagem, sugiro escrever o singleton um pouco melhor:
mas não estou usando em todos os lugares, eu uso
getContext()
egetApplicationContext()
onde posso fazer isso!fonte