Diferença entre Contexto de Atividade e Contexto de Aplicativo


233

Isso me deixou perplexo, eu estava usando isso no Android 2.1-r8 SDK:

ProgressDialog.show(getApplicationContext(), ....);

e também em

Toast t = Toast.makeText(getApplicationContext(),....);

usando getApplicationContext()falhas tanto ProgressDialoge Toast.... o que me levou a esta pergunta:

Quais são as diferenças reais entre um contexto de atividade e um contexto de aplicativo, apesar de compartilhar o texto 'Contexto'?


Isto é o que eu encontrei stackoverflow.com/questions/1561803/… .... #
t0mm13b

14
Isso deve ajudar a esclarecer algumas coisas: Contexto, que contexto?
toobsco42

Respostas:


250

Ambas são instâncias do Contexto , mas a instância do aplicativo está vinculada ao ciclo de vida do aplicativo, enquanto a instância do Activity está vinculada ao ciclo de vida de uma Atividade. Assim, eles têm acesso a informações diferentes sobre o ambiente do aplicativo.

Se você ler os documentos em getApplicationContext , observe que você deve usá-lo apenas se precisar de um contexto cujo ciclo de vida seja separado do contexto atual. Isso não se aplica a nenhum dos seus exemplos.

O contexto de atividade presumivelmente possui algumas informações sobre a atividade atual necessária para concluir essas chamadas. Se você mostrar a mensagem de erro exata, poderá apontar para o que exatamente é necessário.

Mas, em geral, use o contexto da atividade, a menos que você tenha um bom motivo para não fazê-lo.


1
Eu recebi um 'java.lang.reflect.InvocationTargetException' ao usar getApplicationContext, curiosamente, quando mudei para this, ele não travou e funcionou conforme o esperado ... então, se são as duas instâncias do contexto, por que não funciona e o outro faz? Esta informação vai ser de ajuda para os outros que eu espero ... :) Obrigado pela sua resposta rápida ...
t0mm13b

2
Eu precisaria ver o rastreamento de pilha de exceção completo para poder dizer qualquer coisa. No entanto, como eu disse, as instâncias de contexto têm informações diferentes. Presumivelmente, mostrar uma caixa de diálogo ou um brinde na tela requer informações sobre a Atividade que somente a instância da Atividade possui.
Cheryl Simon

74
Eu diria que use o contexto do aplicativo, a menos que você também não tenha um bom motivo (ou seja, para diálogos ou brindes). É bastante fácil de executar em vazamentos de memória, utilizando contextos de atividade em diferentes situações de modo melhor para ser seguro :) android-developers.blogspot.com/2009/01/...
Dori

10
Dave Smith postou uma entrada de blog muito boa para entender o uso do contexto, veja aqui . Leia também os comentários!
precisa saber é o seguinte

1
O fato é que mesmo Dianna Hackborn recomenda usar o contexto de atividade. stackoverflow.com/questions/5228160/… Mas ela parece não ter muita certeza disso.
JacksOnF1re

178

Achei esta tabela super útil para decidir quando usar diferentes tipos de contextos:

insira a descrição da imagem aqui

  1. Um aplicativo PODE iniciar uma Atividade a partir daqui, mas requer que uma nova tarefa seja criada. Isso pode se encaixar em casos de uso específicos, mas pode criar comportamentos de pilha não padronizada em seu aplicativo e geralmente não é recomendado ou considerado uma boa prática.
  2. Isso é legal, mas a inflação será feita com o tema padrão do sistema no qual você está executando, não com o que está definido no seu aplicativo.
  3. Permitido se o receptor for nulo, usado para obter o valor atual de uma transmissão persistente, no Android 4.2 e superior.

Artigo original aqui .



que tal obter os recursos? acho melhor você adicioná-lo à sua mesa. e você pode acessar recursos com o contexto de aplicação.
Amir Ziarati

Podemos começar a atividade a partir do contexto de aplicação
Duy Phan

Artigo também pode ser encontrado aqui: wundermanthompsonmobile.com/2013/06/context
Lifes

34

Obviamente, isso é deficiência do design da API. Em primeiro lugar, o contexto da atividade e o contexto do aplicativo são objetos totalmente diferentes; portanto, os parâmetros do método em que o contexto é usado devem usar ApplicationContextou Activitydiretamente, em vez de usar a classe pai Context. Em segundo lugar, o documento deve especificar qual contexto usar ou não explicitamente.


25
Totalmente de acordo. O Google deixou cair a bola nessa. É uma bagunça completa.
Søren Boisen

@ SørenBoisen Android SDK é uma bagunça completa
CommonSenseCode

Eles estão cientes da bagunça e tenho certeza de que estão se esforçando bastante para consertar o máximo possível.
pasignature 17/06

15

A razão pela qual penso é que ProgressDialogestá anexado à atividade que sustenta o argumento, ProgressDialogpois o diálogo não pode permanecer após a atividade ser destruída, por isso precisa ser passado this(ActivityContext) que também é destruído com a atividade, enquanto o ApplicationContext permanece mesmo após a atividade ser destruída. destruído.


3

Use getApplicationContext () se precisar de algo vinculado a um Contexto que tenha escopo global.

Se você usar a Atividade, a nova instância da Atividade terá uma referência, que tem uma referência implícita à Atividade antiga, e a Atividade antiga não poderá ser coletada como lixo.


2

Acho que quando tudo precisa ser exibido em uma tela (botão, caixa de diálogo, layout ...) precisamos usar a atividade de contexto, e tudo não precisa de uma tela para mostrar ou processar (brinde, telefone, telefone, contato ...) poderia usar um contexto de aplicativo


1

Você pode ver uma diferença entre os dois contextos quando você inicia o aplicativo diretamente na tela inicial e quando o aplicativo é iniciado a partir de outro aplicativo por meio do compartilhamento.

Aqui está um exemplo prático do que significa "comportamentos de pilha não padronizada", mencionados por @CommonSenseCode, significa:

Suponha que você tenha dois aplicativos que se comunicam, App1 e App2 .

Inicie o App2: MainActivity a partir do iniciador. Em MainActivity, inicie o App2: SecondaryActivity . Lá, usando o contexto de atividade ou o contexto do aplicativo, ambas as atividades vivem na mesma tarefa e isso é aceitável (desde que você use todos os modos de inicialização padrão e sinalizadores de intenção). Você pode voltar ao MainActivity pressionando novamente e nos aplicativos recentes você tem apenas uma tarefa.

Suponha agora que você esteja no App1 e inicie o App2: MainActivity com uma intenção de compartilhamento (ACTION_SEND ou ACTION_SEND_MULTIPLE). Em seguida, tente iniciar o App2: SecondaryActivity (sempre com todos os modos de inicialização padrão e sinalizadores de intenção). O que acontece é:

  • se você iniciar App2: SecondaryActivity com contexto de aplicativo no Android <10, não poderá iniciar todas as atividades na mesma tarefa . Eu tentei com o Android 7 e 8 e o SecondaryActivity sempre é iniciado em uma nova tarefa (acho que é porque o App2: SecondaryActivity é iniciado com o contexto do aplicativo App2, mas você é do App1 e não iniciou o aplicativo App2 diretamente Talvez por baixo do capô o Android reconheça isso e use FLAG_ACTIVITY_NEW_TASK). Isso pode ser bom ou ruim, dependendo de suas necessidades, pois meu aplicativo foi ruim.
    No Android 10, o aplicativo trava com a mensagem
    "Chamar startActivity () de fora de um contexto de Atividade requer o sinalizador FLAG_ACTIVITY_NEW_TASK. É isso mesmo que você deseja?" .
    Portanto, para fazê-lo funcionar no Android 10, você precisa usar o FALG_ACTIVITY_NEW_TASK e não pode executar todas as atividades na mesma tarefa.
    Como você pode ver, o comportamento é diferente entre as versões do Android, estranho.

  • se você iniciar App2: SecondaryActivity com o contexto de atividade, tudo correrá bem e você poderá executar todas as atividades na mesma tarefa, resultando em uma navegação linear de backstack.

Espero ter adicionado algumas informações úteis

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.