Diferença entre getContext (), getApplicationContext (), getBaseContext () e "this"

565

Qual é a diferença entre getContext(), getApplicationContext(), getBaseContext(), e " this"?

Embora essa seja uma pergunta simples, sou incapaz de entender a diferença básica entre eles. Por favor, dê alguns exemplos fáceis, se possível.

iCurious
fonte
1
Existe uma excelente redação na primeira resposta: stackoverflow.com/questions/1026973/… #
ky1enamic 17/12/12

Respostas:

528
  • View.getContext(): Retorna o contexto em que a visualização está sendo executada. Geralmente, a Atividade ativa no momento.

  • Activity.getApplicationContext(): Retorna o contexto para o aplicativo inteiro (o processo em que todas as atividades estão sendo executadas). Use isso em vez do contexto atual da Atividade se precisar de um contexto vinculado ao ciclo de vida de todo o aplicativo, não apenas da Atividade atual.

  • ContextWrapper.getBaseContext(): Se você precisar acessar um contexto de outro contexto, use um ContextWrapper. O Contexto referido de dentro desse ContextWrapper é acessado via getBaseContext ().

Alexander Lucas
fonte
59
e o que dizer "isso"?
CooL i3oY
16
+ CooL i3oY mesmo com getContext
Mikey '
13
na verdade, estou confuso que qual é a definição adequada de contexto?
Ravi
11
"isto" e getContext () ambos são mesmo
KCRaju
43
thise getContext()nem sempre são iguais, por exemplo, na classe Activity, você pode usar thisporque Activityherda de, Contextmas o método getContext()não está na Activityclasse. @mikedroid @KCRaju
nandan
92

A maioria das respostas já cobre getContext()e getApplicationContext()mas getBaseContext () raramente é explicado.

O método getBaseContext()é relevante apenas quando você tem um ContextWrapper. O Android fornece uma ContextWrapperclasse criada em torno de uma existente Contextusando:

ContextWrapper wrapper = new ContextWrapper(context);

O benefício de usar a ContextWrapperé que ele permite "modificar o comportamento sem alterar o contexto original". Por exemplo, se você tiver uma atividade chamada myActivity, poderá criar uma Viewcom um tema diferente de myActivity:

ContextWrapper customTheme = new ContextWrapper(myActivity) {
  @Override
  public Resources.Theme getTheme() { 
    return someTheme;
  }
}
View myView = new MyView(customTheme);

ContextWrapperé realmente poderoso porque permite substituir a maioria das funções fornecidas, Contextincluindo código para acessar recursos (por exemplo openFileInput(),getString() ), interagir com outros componentes (por exemplo sendBroadcast(), registerReceiver()), solicitar permissões (por exemplo checkCallingOrSelfPermission()) e resolver locais de sistema de arquivos (por exemplo getFilesDir()). ContextWrapperé realmente útil para solucionar problemas específicos do dispositivo / versão ou para aplicar personalizações pontuais a componentes como Exibições que exigem um contexto.

O método getBaseContext () pode ser usado para acessar o Contexto "base" que o ContextWrapperenvolve. Você pode precisar acessar o contexto "base" se precisar, por exemplo, verificar se é umService , Activityou Application:

public class CustomToast {
  public void makeText(Context context, int resId, int duration) {
    while (context instanceof ContextWrapper) {
      context = context.baseContext();
    }
    if (context instanceof Service)) {
      throw new RuntimeException("Cannot call this from a service");
    }
    ...
  }
}

Ou se você precisar chamar a versão "desembrulhada" de um método:

class MyCustomWrapper extends ContextWrapper {
  @Override
  public Drawable getWallpaper() {
    if (BuildInfo.DEBUG) {
      return mDebugBackground;
    } else {
      return getBaseContext().getWallpaper();
    }
  }
}
Mike Laren
fonte
17
Eu diria que esta é a resposta mais importante após uma aceita.
0leg
4
Eu diria que a existência de ContextWrapperé uma das piores decisões já tomadas pelos desenvolvedores do framework Android. Quando eles perceberam que criaram uma família inteira de Objetos Deus, em vez de fazer a coisa certa e refatorar o código para a Responsabilidade Única, eles adicionaram um truque feio que permitia mudar o comportamento do Contexto, aprofundando a árvore de herança. Engenharia de software ruim é a mais feia. Quanto a nós, desenvolvedores, IMHO ninguém deve usar getBaseContext()ou ContextWrapper. Se você faz - é um enorme "cheiro de código".
23717 Vasiliy
Eu gostaria de ver o CustomToastcódigo completo . Obrigado :)))
Alston
39

getApplicationContext () - Retorna o contexto para todas as atividades em execução no aplicativo.

getBaseContext () - Se você quiser acessar o Contexto de outro contexto dentro do aplicativo, poderá acessar.

getContext () - Retorna a visualização de contexto apenas da atividade atual em execução.

Jay Patel
fonte
1
Por favor, incorpore as letras A e B em sua definição de contexto em qualquer contexto, não está claro em nenhuma resposta qual contexto é acessado.
que você
29

A pergunta "o que é o contexto" é uma das perguntas mais difíceis do universo Android.

O contexto define métodos que acessam recursos do sistema, recuperam ativos estáticos do aplicativo, verificam permissões, executam manipulações da interface do usuário e muito mais. Em essência, Contexté um exemplo do antipadrão de Objeto de Deus na produção.

Quando se trata de que tipo de Contextuso devemos usar, isso se torna muito complicado, porque, exceto por ser objeto de Deus, a árvore hierárquica das Contextsubclasses viola brutalmente o princípio da substituição de Liskov.

Esta postagem do blog tenta resumir a Contextaplicabilidade das classes em diferentes situações.

Deixe-me copiar a tabela principal dessa postagem para garantir a integridade:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | Application | Activity | Service | ContentProvider | BroadcastReceiver |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
| Show a Dialog              | NO          | YES      | NO      | NO              | NO                |
| Start an Activity          | NO¹         | YES      | NO¹     | NO¹             | NO¹               |
| Layout Inflation           | NO²         | YES      | NO²     | NO²             | NO²               |
| Start a Service            | YES         | YES      | YES     | YES             | YES               |
| Bind to a Service          | YES         | YES      | YES     | YES             | NO                |
| Send a Broadcast           | YES         | YES      | YES     | YES             | YES               |
| Register BroadcastReceiver | YES         | YES      | YES     | YES             | NO³               |
| Load Resource Values       | YES         | YES      | YES     | YES             | YES               |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
  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 não padronizados de back stack no 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 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.

captura de tela

Vasiliy
fonte
Ótimo post ao qual você vinculou!
lejonl
28

Contextfornece informações sobre o ActvityouApplication componentes recém-criados .

Relevante Contextdeve ser fornecido aos componentes recém-criados (seja contexto de aplicativo ou contexto de atividade)

Como Activityé uma subclasse de Context, pode-se usar thispara obter o contexto dessa atividade

tez
fonte
Onde está sua explicação sobre o baseContext?
IgorGanapolsky
1

A partir disso documento

Eu entendi que você deveria usar:

Tente usar o aplicativo de contexto em vez de uma atividade de contexto

mehmet
fonte
0

getApplicationContext ()

isso é usado para o nível do aplicativo e refere-se a todas as atividades.

getContext () e getBaseContext ()

é provavelmente o mesmo. estes são referidos apenas à atividade atual que está ativa.

isto

é referir o objeto de classe atual sempre.

Jatin Bansal
fonte
0

A Contexté:

  • uma classe abstrata cuja implementação é fornecida pelo sistema Android.
  • Ele permite o acesso a recursos e classes específicos do aplicativo, bem como chamadas para operações no nível do aplicativo, como atividades de lançamento, transmissão e recebimento de intenções, etc.
SANKET RAMANI
fonte