getContext(),getApplicationContext(),getBaseContext()和“this”
getContext()
, getApplicationContext()
, getBaseContext()
和“ this
”有什么getBaseContext()
?
虽然这是个简单的问题,但我无法理解它们之间的基本区别。 如果可能,请给出一些简单的例子。
-
View.getContext()
:返回视图当前正在运行的上下文。通常是当前活动的Activity。 -
Activity.getApplicationContext()
:返回整个应用程序的上下文(进程中所有的活动都在里面运行)。 如果您需要一个与整个应用程序的生命周期相关的上下文,而不仅仅是当前的Activity,那么使用它而不是当前的Activity上下文。 -
ContextWrapper.getBaseContext()
:如果需要从另一个上下文中访问Context,则使用ContextWrapper。 从ContextWrapper引用的Context是通过getBaseContext()来访问的。
getApplicationContext() – 返回在应用程序中运行的所有活动的上下文。
getBaseContext() – 如果要从应用程序中的其他上下文访问上下文,则可以访问该上下文。
getContext() – 仅返回当前正在运行的活动的上下文视图。
Context
提供关于Actvity
或Application
给新创build的组件。
相关Context
应该提供给新创build的组件(无论是应用程序上下文还是活动上下文)
由于Activity
是Context
一个子类,因此可以使用this
来获取该Activity的上下文
大多数答案已经覆盖了getContext()
和getApplicationContext()
但getBaseContext()很less解释。
方法getBaseContext()
只有当你有一个ContextWrapper
时才相关。 Android提供了一个ContextWrapper
类,它是在现有的Context
创build的:
ContextWrapper wrapper = new ContextWrapper(context);
使用ContextWrapper
的好处是它可以让你“修改行为而不改变原来的上下文”。 例如,如果您有一个名为myActivity
的活动,则可以使用与myActivity
不同的主题创build一个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()
)和parsing文件系统位置(例如getFilesDir()
)。 ContextWrapper
对解决设备/版本特定问题或将一次性自定义应用于需要上下文的组件(例如Views)非常有用。
方法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"); } ... } }
或者,如果你需要调用一个方法的“unwrapped”版本:
class MyCustomWrapper extends ContextWrapper { @Override public Drawable getWallpaper() { if (BuildInfo.DEBUG) { return mDebugBackground; } else { return getBaseContext().getWallpaper(); } } }
“背景是什么”这个问题是Android系统中最难的问题之一。
Context定义了访问系统资源,检索应用程序的静态资产,检查权限,执行UI操作等等的方法。 本质上, Context
是上帝对象反生产模式的一个例子。
当涉及到我们应该使用哪种types的Context
,它变得非常复杂,因为除了作为上帝对象之外, Context
子类的层次树却残酷地违反了里斯科replace原则。
本博客文章试图总结Context
类在不同情况下的适用性。
让我从该post复制主表,以完整性:
+----------------------------+-------------+----------+---------+-----------------+-------------------+ | | 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 | +----------------------------+-------------+----------+---------+-----------------+-------------------+
- 一个应用程序可以从这里启动一个Activity,但是它需要创build一个新的任务。 这可能适合特定的用例,但可以在应用程序中创build非标准的后退堆栈行为,通常不被推荐或被认为是良好的做法。
- 这是合法的,但通货膨胀将与您正在运行的系统的默认主题完成,而不是在您的应用程序中定义的。
- 如果在Android 4.2及更高版本上,接收器为空(用于获取粘性广播的当前值),则允许。
– 截图
从这个文档
我明白你应该使用:
尝试使用上下文应用程序而不是上下文活动
getApplicationContext()
这是用于应用程序级别并参考所有活动。
getContext()和getBaseContext()
很可能是相同的。这些仅仅是当前的活动。
这个
始终引用当前类对象。