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

时间:2012-05-17 18:07:13

标签: android this android-context

getContext()getApplicationContext()getBaseContext()和“this”之间有什么区别?

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

10 个答案:

答案 0 :(得分:495)

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

  • Activity.getApplicationContext():返回整个应用程序的上下文(所有活动在其中运行的进程) 的)。如果需要,请使用此代替当前的Activity上下文 上下文绑定到整个应用程序的生命周期,而不仅仅是 当前的活动。

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

答案 1 :(得分:70)

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

方法getBaseContext()仅在您拥有ContextWrapper时才有意义。 Android提供了ContextWrapper类,该类使用以下内容围绕现有Context创建:

ContextWrapper wrapper = new ContextWrapper(context);

使用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包含的“基础”上下文。如果需要,您可能需要访问“基本”上下文,例如,检查它是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");
    }
    ...
  }
}

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

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

答案 2 :(得分:38)

  

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

     

getBaseContext() - 如果要从应用程序中的其他上下文访问上下文,则可以访问。

     

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

答案 3 :(得分:28)

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

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

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

答案 4 :(得分:19)

问题"背景是什么"是Android世界中最困难的问题之一。

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

当谈到我们应该使用哪种Context时,它变得非常复杂,因为除了作为God Object之外,Context子类的层次结构树残忍地违反了Liskov替换原则。

This blog post尝试在不同情况下总结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. 应用程序可以从此处启动活动,但需要创建新任务。这可能适合特定的用例,但可以在您的应用程序中创建非标准的堆栈行为,通常不建议或被视为良好实践。
  2.   
  3. 这是合法的,但通货膨胀将使用您运行的系统的默认主题,而不是您的应用程序中定义的内容。
  4.   
  5. 如果接收方为空,则允许在Android 4.2及更高版本上用于获取粘性广播的当前值。
  6.         

    screenshot

答案 5 :(得分:8)

一段上下文的UML图

enter image description here

答案 6 :(得分:1)

从此docs

我明白你应该使用:

  

尝试使用context-application而不是context-activity

答案 7 :(得分:1)

this:当前类对象

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

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

答案 8 :(得分:0)

getApplicationContext()

  

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

getContext()和getBaseContext()

  

很可能是相同的。这些仅仅是现有活动。

:此

  

总是引用当前的类对象。

答案 9 :(得分:0)

一个Context是:

  • 一个抽象类,其实现由Android系统提供。
  • 它允许访问特定于应用程序的资源和类,以及 应用程序级操作(如启动活动, 广播和接收意图等。