Android getContext() 、 getApplicationContext() 、 getBaseContext() 和“this”之间的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10641144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:28:19  来源:igfitidea点击:

Difference between getContext() , getApplicationContext() , getBaseContext() and "this"

androidthisandroid-context

提问by iCurious

What is the difference between getContext(), getApplicationContext(), getBaseContext(), and "this"?

是什么区别getContext()getApplicationContext()getBaseContext(),和“ this“?

Though this is simple question I am unable to understand the basic difference between them. Please give some easy examples if possible.

虽然这是一个简单的问题,但我无法理解它们之间的基本区别。如果可能,请举一些简单的例子。

采纳答案by Alexander Lucas

  • View.getContext(): Returns the context the view is currently running in. Usually the currently active Activity.

  • Activity.getApplicationContext(): Returns the context for the entire application (the process all the Activities are running inside of). Use this instead of the current Activity context if you need a context tied to the lifecycle of the entire application, not just the current Activity.

  • ContextWrapper.getBaseContext(): If you need access to a Context from within another context, you use a ContextWrapper. The Context referred to from inside that ContextWrapper is accessed via getBaseContext().

  • View.getContext(): 返回视图当前运行的上下文。通常是当前活动的 Activity。

  • Activity.getApplicationContext():返回整个应用程序的上下文(所有活动在其中运行的进程)。如果您需要一个与整个应用程序的生命周期相关联的上下文,而不仅仅是当前的 Activity,请使用它而不是当前的 Activity 上下文。

  • ContextWrapper.getBaseContext():如果您需要从另一个上下文中访问一个 Context,您可以使用 ContextWrapper。从 ContextWrapper 内部引用的 Context 是通过 getBaseContext() 访问的。

回答by Mike Laren

Most answers already cover getContext()and getApplicationContext()but getBaseContext()is rarely explained.

大多数答案已经涵盖getContext()getApplicationContext()但很少解释getBaseContext()

The method getBaseContext()is only relevant when you have a ContextWrapper. Android provides a ContextWrapperclass that is created around an existing Contextusing:

该方法getBaseContext()仅在您拥有ContextWrapper. Android 提供了一个ContextWrapper围绕现有Context使用创建的类:

ContextWrapper wrapper = new ContextWrapper(context);

The benefit of using a ContextWrapperis that it lets you “modify behavior without changing the original Context”. For example, if you have an activity called myActivitythen can create a Viewwith a different theme than myActivity:

使用 a 的好处ContextWrapper是它可以让你“在不改变原始上下文的情况下修改行为”。例如,如果您有一个名为的活动,myActivity则可以创建一个View与以下主题不同的主题myActivity

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

ContextWrapperis really powerful because it lets you override most functions provided by Contextincluding code to access resources (e.g. openFileInput(), getString()), interact with other components (e.g. sendBroadcast(), registerReceiver()), requests permissions (e.g. checkCallingOrSelfPermission()) and resolving file system locations (e.g. getFilesDir()). ContextWrapperis really useful to work around device/version specific problems or to apply one-off customizations to components such as Views that require a context.

ContextWrapper真的很强大,因为它可以让您覆盖所提供的大部分功能Context,包括代码访问的资源(例如openFileInput()getString()),与其他成分相互作用(例如sendBroadcast()registerReceiver()),请求权限(例如checkCallingOrSelfPermission()),并解决文件系统位置(例如getFilesDir())。ContextWrapper对于解决设备/版本特定问题或将一次性自定义应用于需要上下文的组件(例如视图)非常有用。

The method getBaseContext()can be used to access the “base” Context that the ContextWrapperwraps around. You might need to access the “base” context if you need to, for example, check whether it's a Service, Activityor Application:

方法getBaseContext()可用于访问ContextWrapper环绕的“基本”上下文。您可能需要访问“基地”背景下,如果你需要,例如,检查它是否是一个ServiceActivity或者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");
    }
    ...
  }
}

Or if you need to call the “unwrapped” version of a method:

或者,如果您需要调用方法的“解包”版本:

class MyCustomWrapper extends ContextWrapper {
  @Override
  public Drawable getWallpaper() {
    if (BuildInfo.DEBUG) {
      return mDebugBackground;
    } else {
      return getBaseContext().getWallpaper();
    }
  }
}

回答by Jay Patel

getApplicationContext()- Returns the context for all activities running in application.

getBaseContext()- If you want to access Context from another context within application you can access.

getContext()- Returns the context view only current running activity.

getApplicationContext()- 返回应用程序中运行的所有活动的上下文。

getBaseContext()- 如果您想从您可以访问的应用程序内的另一个上下文访问 Context。

getContext()- 仅返回当前正在运行的活动的上下文视图。

回答by Vasiliy

The question "what the Context is" is one of the most difficult questions in the Android universe.

“上下文是什么”这个问题是 Android 世界中最难的问题之一。

Context defines methods that access system resources, retrieve application's static assets, check permissions, perform UI manipulations and many more. In essence, Contextis an example of God Object anti-pattern in production.

上下文定义了访问系统资源、检索应用程序的静态资产、检查权限、执行 UI 操作等的方法。从本质上讲,Context是生产中 God Object 反模式的一个例子。

When it comes to which kind of Contextshould we use, it becomes very complicated because except for being God Object, the hierarchy tree of Contextsubclasses violates Liskov Substitution Principle brutally.

说到Context应该使用哪种,就变得很复杂了,因为除了是God Object之外,Context子类的层次树残酷地违反了Liskov Substitution Principle。

This blog postattempts to summarize Contextclasses applicability in different situations.

这篇博文试图总结Context类在不同情况下的适用性。

Let me copy the main table from that post for completeness:

为了完整起见,让我从该帖子中复制主表:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | Application | Activity | Service | ContentProvider | BroadcastReceiver |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
| Show a Dialog              | NO          | YES      | NO      | NO              | NO                |
| Start an Activity          | NO1         | YES      | NO1     | NO1             | NO1               |
| Layout Inflation           | NO2         | YES      | NO2     | NO2             | NO2               |
| 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             | NO3               |
| Load Resource Values       | YES         | YES      | YES     | YES             | YES               |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
  1. An application CAN start an Activity from here, but it requires that a new task be created. This may fit specific use cases, but can create non-standard back stack behaviors in your application and is generally not recommended or considered good practice.
  2. This is legal, but inflation will be done with the default theme for the system on which you are running, not what's defined in your application.
  3. Allowed if the receiver is null, which is used for obtaining the current value of a sticky broadcast, on Android 4.2 and above.

screenshot

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | Application | Activity | Service | ContentProvider | BroadcastReceiver |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
| Show a Dialog              | NO          | YES      | NO      | NO              | NO                |
| Start an Activity          | NO1         | YES      | NO1     | NO1             | NO1               |
| Layout Inflation           | NO2         | YES      | NO2     | NO2             | NO2               |
| 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             | NO3               |
| Load Resource Values       | YES         | YES      | YES     | YES             | YES               |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
  1. 应用程序可以从这里启动一个 Activity,但它需要创建一个新任务。这可能适合特定用例,但可能会在您的应用程序中创建非标准的返回堆栈行为,通常不推荐或认为是好的做法。
  2. 这是合法的,但通货膨胀将使用您正在运行的系统的默认主题完成,而不是您的应用程序中定义的主题。
  3. 在 Android 4.2 及更高版本上,如果接收器为 null 则允许,用于获取粘性广播的当前值。

截屏

回答by tez

Contextprovides information about the Actvityor Applicationto newly created components.

Context提供有关ActvityApplication新创建的组件的信息。

Relevant Contextshould be provided to newly created components (whether application context or activity context)

相关的Context应该提供给新创建的组件(无论是应用程序上下文还是活动上下文)

Since Activityis a subclass of Context, one can use thisto get that activity's context

由于Activity是 的子类Context,因此可以使用它this来获取该活动的上下文

回答by mehmet

From this docs

从这个文档

I understood that you should use:

我明白你应该使用:

Try using the context-application instead of a context-activity

尝试使用上下文应用程序而不是上下文活动

回答by Jatin Bansal

getApplicationContext()

获取应用程序上下文()

this is used for application level and refer to all activities.

这用于应用程序级别并指代所有活动。

getContext() and getBaseContext()

getContext() 和 getBaseContext()

is most probably same .these are reffered only current activity which is live.

很可能是相同的。这些仅是当前活动的实时活动。

this

这个

is refer current class object always.

总是引用当前类对象。

回答by SANKET RAMANI

A Contextis:

一个Context是:

  • an abstract class whose implementation is provided by the Android system.
  • It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.
  • 一个抽象类,其实现由Android系统提供。
  • 它允许访问特定于应用程序的资源和类,以及调用应用程序级操作,例如启动活动、广播和接收意图等。