首页 文章

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

提问于
浏览
475

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

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

8 回答

  • 6

    来自docs

    我明白你应该使用:

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

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

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

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

  • 28

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

    方法 getBaseContext() 仅在您拥有 ContextWrapper 时才相关 . Android提供了一个 ContextWrapper 类,它是在现有的 Context 周围使用:

    ContextWrapper wrapper = new ContextWrapper(context);
    

    使用 ContextWrapper 的好处是它允许您“修改行为而不更改原始上下文” . 例如,如果您有一个名为 myActivity 的活动,则可以使用与 myActivity 不同的主题创建 View

    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();
        }
      }
    }
    
  • 15

    getApplicationContext() - 返回在应用程序中运行的所有活动的上下文 . getBaseContext() - 如果要从应用程序中的其他上下文访问Context,则可以访问 . getContext() - 仅返回当前运行活动的上下文视图 .

  • 469

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

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

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

  • 64

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

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

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

    This blog post试图在不同情况下总结 Context 类的适用性 .

    让我从该帖子中复制主表以确保完整性:


    | |应用|活动|服务| ContentProvider | BroadcastReceiver |


    |显示对话框|没有|是的|没有|没有|没有|
    |开始活动| NO¹|是的| NO¹| NO¹| NO¹|
    |布局通胀| NO²|是的| NO²| NO²| NO²|
    |启动服务|是的|是的|是的|是的|是的|
    |绑定到服务|是的|是的|是的|是的|没有|
    |发送广播|是的|是的|是的|是的|是的|
    |注册BroadcastReceiver |是的|是的|是的|是的| NO³|
    |加载资源值|是的|是的|是的|是的|是的|


    应用程序可以从此处启动活动,但它需要创建新任务 . 这可能适合特定的用例,但可以在您的应用程序中创建非标准的后台堆栈行为不推荐或认为是良好做法 . 这是合法的,但通货膨胀将使用您运行的系统的默认主题完成,而不是您的应用程序中定义的内容 . 如果接收方为空,则允许在Android 4.2及更高版本上用于获取粘性广播的当前值 . - 截图

  • 1

    一段上下文的UML图

    enter image description here

  • 1

    getApplicationContext()

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

    getContext() and getBaseContext()

    最可能是相同的 . 这些仅仅是现有活动 .

    this

    总是引用当前的类对象 .

相关问题