628

getContext(), getApplicationContext(), getBaseContext(), 和 " " 和有什么不一样this

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

4

10 回答 10

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

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

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

于 2012-05-17T18:15:25.737 回答
130

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

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

ContextWrapper wrapper = new ContextWrapper(context);

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

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

ContextWrapper非常强大,因为它允许您覆盖通过Context包含访问资源(例如openFileInput()getString())、与其他组件交互(例如sendBroadcast()registerReceiver())、请求权限(例如checkCallingOrSelfPermission())和解析文件系统位置(例如getFilesDir())的代码提供的大多数功能。ContextWrapper对于解决设备/版本特定问题或将一次性自定义应用于需要上下文的视图等组件非常有用。

getBaseContext()方法可用于访问ContextWrapper环绕的“基本”上下文。如果您需要例如检查它是 a还是Service,您可能需要访问“基本”上下文:ActivityApplication

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");
    }
    ...
  }
}

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

class MyCustomWrapper extends ContextWrapper {
  @Override
  public Drawable getWallpaper() {
    if (BuildInfo.DEBUG) {
      return mDebugBackground;
    } else {
      return getBaseContext().getWallpaper();
    }
  }
}
于 2017-02-13T18:24:07.880 回答
43

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

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

当涉及到我们应该使用哪种时Context,它变得非常复杂,因为除了是上帝对象之外,Context子类的层次结构树粗暴地违反了里氏替换原则。

这篇博文(现在来自 Wayback Machine)试图总结Context类在不同情况下的适用性。

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

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

截屏

于 2017-03-09T16:31:38.313 回答
39

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

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

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

于 2014-03-10T08:51:02.770 回答
28

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

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

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

于 2013-03-02T13:28:01.400 回答
3

获取应用程序上下文()

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

getContext() 和 getBaseContext()

很可能是相同的。这些仅引用了当前的活动。

这个

总是引用当前类对象。

于 2017-08-11T11:46:13.777 回答
2

this:当前类对象

getContext():返回当前活动的上下文

getApplicationContext():返回应用程序中正在运行的所有活动

于 2021-03-24T06:08:12.327 回答
1

从这个文档

我知道你应该使用:

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

于 2014-04-15T06:54:34.597 回答
1

一个Context是:

  • 一个抽象类,其实现由 Android 系统提供。
  • 它允许访问特定于应用程序的资源和类,以及向上调用应用程序级操作,例如启动活动、广播和接收意图等。
于 2019-11-07T09:11:36.577 回答
0

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

getBaseContext()  - 当您想从应用程序中的另一个上下文访问上下文时,您可以访问。

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

this - 它指的是当前的类对象

this指的是当前的activity类对象,activity继承了context,所以在context或者activity可以使用的地方必须使用this。

于 2022-02-12T13:32:12.183 回答