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();
}
}
}
8 回答
来自docs
我明白你应该使用:
View.getContext():返回视图当前运行的上下文 . 通常是当前活动的Activity .
Activity.getApplicationContext():返回整个应用程序的上下文(所有活动正在其中运行的进程) . 如果您需要与整个应用程序的生命周期相关联的上下文,而不仅仅是当前的Activity,请使用此而不是当前的Activity上下文 .
ContextWrapper.getBaseContext():如果需要从另一个上下文中访问Context,则使用ContextWrapper . Context从内部引用ContextWrapper是通过getBaseContext()访问的 .
大多数答案已涵盖
getContext()
和getApplicationContext()
,但很少解释 getBaseContext() .方法
getBaseContext()
仅在您拥有ContextWrapper
时才相关 . Android提供了一个ContextWrapper
类,它是在现有的Context
周围使用:使用
ContextWrapper
的好处是它允许您“修改行为而不更改原始上下文” . 例如,如果您有一个名为myActivity
的活动,则可以使用与myActivity
不同的主题创建View
:ContextWrapper
非常强大,因为它允许您覆盖Context
提供的大多数功能,包括访问资源的代码(例如openFileInput()
,getString()
),与其他组件(例如sendBroadcast()
,registerReceiver()
)交互,请求权限(例如checkCallingOrSelfPermission()
)和解析文件系统位置(例如getFilesDir()
) .ContextWrapper
对于解决特定于设备/版本的问题或将一次性自定义应用于需要上下文的视图等组件非常有用 .方法 getBaseContext() 可用于访问
ContextWrapper
包含的“基本”上下文 . 如果需要,您可能需要访问“基础”上下文,例如,检查它是Service
,Activity
还是Application
:或者,如果您需要调用方法的“解包”版本:
Context
向新创建的组件提供有关Actvity
或Application
的信息 .应将相关的
Context
提供给新创建的组件(无论是应用程序上下文还是活动上下文)由于
Activity
是Context
的子类,因此可以使用this
来获取该活动的上下文“上下文是什么”这个问题是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及更高版本上用于获取粘性广播的当前值 . - 截图
一段上下文的UML图
getApplicationContext()
getContext() and getBaseContext()
this