是什么区别getContext()
,getApplicationContext()
,getBaseContext()
,和“ this
“?
尽管这是一个简单的问题,但我无法理解它们之间的基本区别。如果可能的话,请举一些简单的例子。
是什么区别getContext()
,getApplicationContext()
,getBaseContext()
,和“ this
“?
尽管这是一个简单的问题,但我无法理解它们之间的基本区别。如果可能的话,请举一些简单的例子。
Answers:
View.getContext()
:返回视图当前正在其中运行的上下文。通常是当前活动的Activity。
Activity.getApplicationContext()
:返回整个应用程序的上下文(所有Activity在其中运行的进程)。如果您需要一个与整个应用程序(而不只是当前Activity)的生命周期相关联的上下文,请使用它代替当前的Activity上下文。
ContextWrapper.getBaseContext()
:如果需要从另一个上下文中访问上下文,请使用ContextWrapper。可以通过getBaseContext()访问从ContextWrapper内部引用的Context。
this
并且getContext()
并不总是相同的,例如在Activity类中,可以使用,this
因为Activity
继承自Context
但方法getContext()
不在Activity
类中。@mikedroid @KCRaju
大多数答案已经涵盖了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
环绕的“基本”上下文。您可能需要访问“基地”背景下,如果你需要,例如,检查它是否是一个Service
,Activity
或者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();
}
}
}
ContextWrapper
是Android框架开发人员做出的最糟糕的决定之一。当他们意识到自己创建了整个“上帝对象”家族时,他们没有做正确的事并将代码重构为“单一职责”,而是添加了一个丑陋的方法,可以通过加深继承树来更改上下文行为。最糟糕的软件工程。对于我们来说,开发人员,恕我直言,没人可以使用getBaseContext()
或ContextWrapper
。如果这样做-这是巨大的“代码异味”。
CustomToast
代码。THANKS :)))
getApplicationContext() -返回在应用程序中运行的所有活动的上下文。
getBaseContext() -如果要从应用程序中的另一个上下文访问上下文,则可以访问。
getContext() -仅返回上下文视图当前正在运行的活动。
“上下文是什么”问题是Android宇宙中最困难的问题之一。
上下文定义了访问系统资源,检索应用程序的静态资产,检查权限,执行UI操作等方法。本质上,这Context
是生产中“上帝对象”反模式的一个示例。
当涉及到哪种类型时Context
,它变得非常复杂,因为Context
子类的层次树除了成为上帝对象外,还残酷地违反了《里斯科夫替代原理》。
这篇博客文章试图总结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 | +----------------------------+-------------+----------+---------+-----------------+-------------------+
- 应用程序可以从此处开始一个活动,但是它需要创建一个新任务。这可能适合特定的用例,但可能会在您的应用程序中创建非标准的Back Stack行为,通常不建议这样做,也不认为这是一种好的做法。
- 这是合法的,但是通货膨胀将使用您正在运行的系统的默认主题完成,而不是应用程序中定义的主题。
- 在Android 4.2及更高版本上,如果接收器为null(用于获取即时广播的当前值),则允许使用。
Context
提供有关Actvity
或Application
新创建的组件的信息。
有关Context
应提供给新创建的组件(无论是应用程序上下文或活动上下文)
由于Activity
是的子类Context
,因此可以this
用来获取该活动的上下文
getApplicationContext()
这用于应用程序级别并涉及所有活动。
getContext()和getBaseContext()
是最可能相同的。这些仅涉及当前的活动。
这个
总是引用当前类的对象。
A Context
是: