Existe uma maneira de obter a Context
instância atual dentro de um método estático?
Estou procurando esse caminho porque odeio salvar a instância 'Context' sempre que ela muda.
android
android-context
Andrea Baccega
fonte
fonte
Context
, pode haver uma maneira melhor de criar o código.Respostas:
Faça isso:
No arquivo Android Manifest, declare o seguinte.
Em seguida, escreva a classe:
Agora, em qualquer lugar, ligue
MyApplication.getAppContext()
para obter o contexto do aplicativo estaticamente.fonte
static context
variável comovolatile
?A maioria dos aplicativos que deseja um método conveniente para obter o contexto do aplicativo cria sua própria classe, que se estende
android.app.Application
.GUIA
Você pode fazer isso criando primeiro uma classe em seu projeto, como a seguir:
Em seu AndroidManifest, você deve especificar o nome da sua classe na tag do AndroidManifest.xml:
Você pode recuperar o contexto do aplicativo em qualquer método estático usando o seguinte:
ATENÇÃO
Antes de adicionar algo como o acima ao seu projeto, considere o que a documentação diz:
REFLEXÃO
Também há outra maneira de obter o contexto do aplicativo usando a reflexão. Muitas vezes, a reflexão é menosprezada no Android e, pessoalmente, acho que isso não deve ser usado na produção.
Para recuperar o contexto do aplicativo, devemos chamar um método em uma classe oculta ( ActivityThread ) que está disponível desde a API 1:
Há mais uma classe oculta ( AppGlobals ) que fornece uma maneira de obter o contexto do aplicativo de maneira estática. Ele obtém o contexto usando,
ActivityThread
então realmente não há diferença entre o método a seguir e o postado acima:Feliz codificação!
fonte
Supondo que estamos falando sobre como obter o Contexto do Aplicativo, eu o implementei conforme sugerido pelo @Rohit Ghatol, que estende o Aplicativo. O que aconteceu, então, é que não há garantia de que o contexto recuperado dessa maneira sempre será não nulo. No momento em que você precisa, geralmente é porque você deseja inicializar um auxiliar ou obter um recurso que você não pode atrasar no tempo; lidar com o caso nulo não o ajudará. Então eu entendi que estava basicamente lutando contra a arquitetura Android, conforme declarado nos documentos
e explicado por Dianne Hackborn
Ela também está sugerindo a solução para este problema:
então o que eu fiz foi me livrar da extensão Application e passar o contexto diretamente para o getInstance () do auxiliar singleton, enquanto salvava uma referência ao contexto do aplicativo no construtor privado:
o chamador passará um contexto local para o auxiliar:
Portanto, para responder adequadamente a essa pergunta: existem maneiras de acessar o Contexto do Aplicativo estaticamente, mas todas elas devem ser desencorajadas, e você deve preferir passar um contexto local para o getInstance do singleton ().
Para qualquer pessoa interessada, você pode ler uma versão mais detalhada no blog fwd
fonte
getInstance(ctx)
. Você tem uma raizinstance
do tipo GCMyHelper
, que possui um campo particularmContext
do tipoContext
, que faz referência ao contexto do aplicativo coletado por meio do contexto passado paragetInstance()
.instance
nunca é definido pela segunda vez, nem limpo, para que o GC nunca pegue o contexto do aplicativo mencionado porinstance
. Você não vaza nenhuma atividade, por isso é IMO de baixo custo.this
inApplication.onCreate()
, o que torna a resposta aceita melhor.Não, acho que não existe. Infelizmente, você não consegue ligar
getApplicationContext()
deActivity
ou de uma das outras subclasses deContext
. Além disso, esta questão está um pouco relacionada.fonte
Aqui está uma maneira não documentada de obter um Aplicativo (que é um Contexto) de qualquer lugar no thread da interface do usuário. Ele se baseia no método estático oculto
ActivityThread.currentApplication()
. Deve funcionar pelo menos no Android 4.x.Observe que é possível que esse método retorne nulo, por exemplo, quando você chama o método fora do thread da interface do usuário ou o aplicativo não está vinculado ao thread.
Ainda é melhor usar a solução do @RohitGhatol se você puder alterar o código do aplicativo.
fonte
Depende do que você está usando o contexto. Eu posso pensar em pelo menos uma desvantagem para esse método:
Se você estiver tentando criar um
AlertDialog
comAlertDialog.Builder
, oApplication
contexto não funcionará. Eu acredito que você precisa do contexto para o atualActivity
...fonte
Kotlin way :
Manifesto:
MyApplication.kt
Você pode acessar a propriedade via
MyApplication.instance
fonte
Se você estiver aberto para usar o RoboGuice , poderá injetar o contexto em qualquer classe que desejar. Aqui está uma pequena amostra de como fazer isso com o RoboGuice 2.0 (beta 4 no momento da redação deste artigo)
fonte
Eu usei isso em algum momento:
Esse é um contexto válido que eu usei para obter serviços do sistema e trabalhei.
Mas, usei apenas em modificações de estrutura / base e não tentei em aplicativos Android.
Um aviso que você deve saber: Ao se registrar para receptores de transmissão com esse contexto, ele não funcionará e você receberá:
fonte
Kotlin
e obtenha um contexto como
ou
fonte
Você pode usar o seguinte:
MainActivity.java:
Qualquer outra classe:
fonte
Se você não quiser modificar o arquivo de manifesto, poderá armazenar manualmente o contexto em uma variável estática em sua atividade inicial:
E apenas defina o contexto quando sua atividade (ou atividades) iniciar:
Nota: Como todas as outras respostas, esse é um possível vazamento de memória.
fonte
Eu acho que você precisa de um corpo para o
getAppContext()
método:fonte
De acordo com esta fonte, você pode obter seu próprio Contexto estendendo o ContextWrapper
JavaDoc for ContextWrapper
fonte
Se, por algum motivo, você desejar o contexto Aplicativo em qualquer classe, não apenas aqueles que estendem o aplicativo / atividade, talvez para algumas classes de fábrica ou auxiliares. Você pode adicionar o seguinte singleton ao seu aplicativo.
em seguida, inicialize-o no onCreate da sua classe de aplicativo com
use-o em qualquer lugar chamando
No entanto, não recomendo essa abordagem para nada além do contexto do aplicativo. Como isso pode causar vazamentos de memória.
fonte
Eu uso uma variação do padrão de design Singleton para me ajudar com isso.
Então eu ligo
ApplicationContextSingleton.setContext( this );
no meu activity.onCreate () eApplicationContextSingleton.setContext( null );
em onDestroy () ;fonte
Acabei de lançar um framework inspirado em jQuery para Android chamado Vapor API que visa simplificar o desenvolvimento de aplicativos.
A Central
$
classe de fachada mantém umWeakReference
(link para o incrível post do blog sobre Java de Ethan Nicholas) sobre oActivity
contexto atual que você pode recuperar chamando:UMA
WeakReference
mantém uma referência sem impedir que a coleta de lixo recupere o objeto original, para que você não tenha problemas com vazamentos de memória.A desvantagem, claro, é que você corre o risco de
$.act()
retornar nulo. Ainda não me deparei com esse cenário, talvez seja apenas um risco mínimo, que vale a pena mencionar.Você também pode definir o contexto manualmente se não estiver usando
VaporActivity
como suaActivity
classe:Além disso, grande parte dos estrutura da API Vapor usa esse contexto armazenado de forma inerente, o que pode significar que você não precisa armazená-lo sozinho se decidir usar a estrutura. Confira o site para mais informações e amostras.
Espero que ajude :)
fonte
A resposta de Rohit parece correta. No entanto, saiba que o "Instant Run" do AndroidStudio depende de não ter
static Context
atributos no seu código, tanto quanto eu saiba.fonte
no Kotlin, colocar o Contexto / Contexto do Aplicativo no objeto complementar ainda gera aviso
Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
ou se você usar algo como isto:
É simplesmente enganar o fiapo para não descobrir o vazamento de memória, a instância do App ainda pode produzir vazamento de memória, pois a classe Application e seu descendente são um Contexto.
Como alternativa, você pode usar a interface funcional ou as propriedades funcionais para ajudá-lo a obter o contexto do aplicativo.
Basta criar uma classe de objeto:
ou você pode usá-lo com mais segurança usando o tipo anulável:
e na sua classe App, adicione esta linha:
e no seu manifesto, declare o nome do aplicativo como
. MyApp
Quando você quiser obter o contexto, basta ligar para:
Espero que ajude.
fonte
Tente algo como isto
fonte