Android上的“上下文”是什么?

在Android编程中, Context类是什么,它用于什么?

我在开发者网站上阅读了这篇文章,但是我无法清楚地理解它。

简单来说:

顾名思义,这是应用程序/对象的当前状态的上下文。 它可以让新创build的对象了解到底发生了什么。 通常你会调用它来获取有关程序的另一部分(活动和包/应用程序)的信息。

您可以通过调用getApplicationContext()getContext()getBaseContext()this (在从Context扩展的类中,如Application,Activity,Service和IntentService类)来获取Context

上下文的典型用途:

  • 创build新对象 :创build新视图,适配器,侦听器:

     TextView tv = new TextView(getContext()); ListAdapter adapter = new SimpleCursorAdapter(getApplicationContext(), ...); 
  • 访问标准的公共资源 :LAYOUT_INFLATER_SERVICE,SharedPreferences之类的服务:

     context.getSystemService(LAYOUT_INFLATER_SERVICE) getApplicationContext().getSharedPreferences(*name*, *mode*); 
  • 隐式访问组件 :关于内容提供者,广播,意图

     getApplicationContext().getContentResolver().query(uri, ...); 

上下文的定义::

  • 上下文表示环境数据
  • 它提供对诸如数据库的访问

更简单的术语::

  • 考虑一下Person-X是创业软件公司的首席执行官。

  • 公司里有一位首席架构师,这个架构师做公司里所有涉及到数据库,UI等的工作。

  • 现在,CEO聘请了一名新的开发人员。

  • build筑师根据新人的技能来讲述新雇员的责任,不pipe他是否会在数据库或UI上工作。

更简单的术语::

  • 这就像android活动访问应用程序的资源。

  • 这与您访问酒店时相似,您需要在合适的时间点享用早餐,午餐和晚餐,对吗?

  • 在逗留期间,您还喜欢其他许多东西。 你怎么得到这些东西?

  • 你问客房服务人员为你带来这些东西。

  • 这里的客房服务人员是考虑到你是单一的活动和酒店作为你的应用程序的情况下,最后的早餐,午餐和晚餐必须是资源。


涉及上下文的事情是:

  1. 加载资源。
  2. 启动新的活动。
  3. 创build视图。
  4. 获得系统服务。

上下文是ActivityServiceApplication ….等的基类

另一种描述方式是:考虑上下文,因为电视中的电视和频道的远程是资源,服务,使用意图等。这里,远程作为访问来访问所有不同资源的前景。

  • 所以,远程访问渠道,如资源,服务,使用意图等….
  • 同样,谁拥有远程访问权限,就可以访问资源,服务,使用意图等所有的东西

您可以通过不同的调用方法来获取上下文

  • getApplicationContext()
  • getContext()
  • getBaseContext()
  • 或者this (当在活动课上的时候)

例:

 TextView TV=new TextView(this); 

this – >是指当前活动的上下文。

资源


Android环境中的主题似乎太混乱了。 人们只是知道,上下文是经常需要在Android做基本的东西。 人们有时会因为试图执行一些需要上下文的操作而不知道如何“获得”正确的上下文而感到恐慌。 我将尝试在Android中揭示Context的概念。 对这个问题的全面处理超出了本文的范围,但是我会尽量给出一个总体的概述,以便你了解Context是什么以及如何使用它。 为了理解Context是什么,我们来看看源代码:

https://github.com/android/platform_frameworks_base/blob/master/core/java/android/content/Context.java

什么是上下文?

那么,文档本身提供了一个相当直接的解释:Context类是一个“关于应用程序环境的全局信息的接口”。

Context类本身被声明为抽象类,其实现由Android OS提供。 该文档进一步提供了上下文“…允许访问特定于应用程序的资源和类,以及对应用程序级操作(如启动活动,广播和接收意图等)的上调。

你现在可以很好地理解,为什么这个名字是Context。 因为就是这样。 如果您愿意的话,上下文为活动,服务或任何其他组件提供链接或挂钩,从而将其链接到系统,从而能够访问全局应用程序环境。 换句话说,上下文为组件问题提供了答案:“我到底在哪里与应用程序有关,以及如何访问应用程序的其余部分?”如果这一切似乎有点混乱,快速看看Context类暴露的方法提供了一些关于其本质的进一步线索。

以下是这些方法的随机抽样:

  1. getAssets()
  2. getResources()
  3. getPackageManager()
  4. getString()
  5. getSharedPrefsFile()

所有这些方法有什么共同点? 它们都可以使任何访问Context的人都能够访问应用程序范围内的资源。

换言之,上下文会将引用它的组件挂接到应用程序环境的其余部分。 例如,资产(您的项目中的“资产”文件夹)可在整个应用程序中使用,前提是一个活动,服务或任何知道如何访问这些资源的资源。 getResources()同样适用于getResources().getColor() ,它将钩住colors.xml资源(永远不要让aapt通过java代码访问资源,这是一个单独的问题)。

结果是, Context是访问系统资源的一种方式,也是将组件挂接到“更大的应用程序”中。让我们看一下Context的子类,这个类提供了抽象的Context类的实现。最明显的类是Activity类inheritance自ContextThemeWrapper ,它inheritance自ContextWrapper ,它inheritance自Context本身,这些类有助于更深层次地理解事物,但现在知道ContextThemeWrapperContextWrapper几乎就是它们听起来像,它们通过“包装”上下文(实际上下文)并将这些函数委托给该上下文来实现Context类本身的抽象元素,一个例子是有用的 – 在ContextWrapper类中,来自Context类的抽象方法getAssets实施如下:

 @Override public AssetManager getAssets() { return mBase.getAssets(); } 

mBase只是一个由构造函数设置为特定上下文的字段。 所以一个上下文被封装, ContextWrapper把它的getAssets方法的实现委派给这个上下文。 我们来回顾一下最终从Contextinheritance的Activity类,看看这一切是如何工作的。

你可能知道一个活动是什么,但要回顾 – 基本上是用户可以做的一件事情。 它负责提供一个放置用户与之交互的UI的窗口。 熟悉其他API甚至非开发人员的开发人员可能会认为它是一个“屏幕”。这在技术上是不准确的,但对我们的目的来说并不重要。 那么, ActivityContext是如何相互作用的?它们的inheritance关系到底是什么?

再次看看具体的例子是有帮助的。 我们都知道如何开展活动。 如果您有启动活动的“上下文”,则只需调用startActivity(intent) ,其中Intent描述了启动Activity的上下文以及您想要启动的Activity。 这是熟悉的startActivity(this, SomeOtherActivity.class)

这是什么? this是您的Activity,因为Activity类从Contextinheritance。 完整的独家新闻是这样的:当你调用startActivity ,最终Activity类执行如下所示:

 Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode); 

所以它利用Instrumentation类中的execStartActivity (实际上来自Instrumentation名为ActivityResult的内部类)。

在这一点上,我们开始窥视系统内部。

这是操作系统实际处理一切的地方。 那么Instrumentation如何正确启动Activity? 那么,上面的execStartActivity方法中的param就是你的Activity,即Context,而execStartActivity则使用了这个上下文。

一个30,000的概述是这样的:Instrumentation类跟踪它监视的活动列表,以便完成它的工作。 这个清单是用来协调所有的活动,并确保一切顺利pipe理活动的stream程。

有一些操作,我没有充分考虑哪些协调线程和进程问题。 最终, ActivityResult使用本机操作 – ActivityManagerNative.getDefault().startActivity() ,它使用您在调用startActivity时传入的Context 。 如果需要,您传入的上下文用于协助“意图解决”。 意向parsing是系统可以在没有提供的情况下确定意图的目标的过程。 (查看指南在这里了解更多细节)。

为了让Android做到这一点,它需要访问Context提供的信息。 具体来说,系统需要访问ContentResolver以便“确定意图数据的MIMEtypes”。关于startActivity如何使用上下文有点复杂,我自己也不完全了解内部。要点是说明如何访问应用程序范围内的资源,以便执行许多对于应用程序来说至关重要的操作, Context可以提供对这些资源的访问,一个简单的例子就是Views。你通过扩展RelativeLayout或者其他一些View类来创build一个自定义的视图,你必须提供一个构造函数来将Context作为一个参数,当你实例化你自定义的视图时,为什么?因为View需要能够拥有访问主题,资源和其他视图configuration细节,视图configuration实际上是一个很好的例子,每个上下文有不同的参数(在Context的实现中的字段),由操作系统自己设置 例如显示器的尺寸或密度。 很容易明白为什么这些信息对于设置视图等很重要

最后一句话:由于某些原因,Android新手(甚至不是那么新的人)似乎完全忘记了面向对象的编程。 出于某种原因,人们试图将其Android开发转变为预先设想的范式或学习行为。

Android有它自己的范例和一个特定的模式,如果放弃你预先设想的概念,并简单地阅读文档和开发指南,实际上是相当一致的。 然而,我的真实观点是,“正确的背景”有时可能会比较棘手,人们无理地恐慌,因为他们遇到了需要背景的情况,并认为他们没有这种背景。 Java再次是一个具有inheritancedevise的面向对象语言。

你只有“有”你的活动内的上下文,因为你的活动本身inheritance上下文。 没有什么魔力(除了操作系统自己设置各种参数以及正确“configuration”你的上下文的所有东西)。 所以,把内存/性能问题放在一边(例如,当你不需要或者以对内存产生负面影响的方式来执行时,保持对上下文的引用等等),Context是一个像其他任何对象一样的对象,它可以被传递就像任何POJO(普通Java对象)一样。 有时你可能需要做一些聪明的事情来检索这个上下文,但是除了Object本身以外的其他任何常规的Java类都可以用可以访问上下文的方式编写。 只需公开一个接受上下文的公共方法,然后根据需要在该类中使用它。 这并不是对Context或者Android内部的一个详尽的处理,但是我希望它有助于对Context的一点点解释。

上下文是系统的句柄; 它提供的服务包括parsing资源,访问数据库和首选项等等。 一个Android应用程序有活动。 它就像您的应用程序当前正在运行的环境的句柄。活动对象inheritance了Context对象。

有关更多信息,请参阅使用Android Studio进行Android开发简介 – 教程

只要你反正思考,想得很大。

接口有关应用程序环境的全局信息。 这是一个抽象类,其实现由Android系统提供。

它允许访问特定于应用程序的资源和类,以及对应用程序级操作(如启动活动,广播和接收意图等)的调用。

活动图

ANDROID AND CONTEXT如果你仔细查看各种Android API,你会发现它们中的很多都以一个android.content.Context对象作为参数。 您还会看到一个Activity或一个服务通常被用作一个Context。 这是可行的,因为这两个类都是从Context开始的。

什么是上下文? 根据Android参考文档,它是表示各种环境数据的实体。 它提供对本地文件,数据库,与环境相关的类加载器的访问,包括系统级服务在内的服务等等。 在整本书中,在您使用Android进行日常编码时,您会看到经常传递的上下文。 来自:“Android实践”书。

Android 上下文是一个“接口” ,允许访问特定于应用程序的资源和类以及有关应用程序环境的信息。

如果你的android应用程序是一个web应用程序,你的上下文将类似于ServletContext(我没有在这里做一个确切的比较)

您的活动和服务还将Context扩展到inheritance所有这些方法以访问运行该应用程序的环境信息。

简单的例子来理解android中的context

每个老板都有一个助理照顾,做所有不那么重要和耗时的工作。 如果需要一个文件或一杯咖啡,助理正在运行。 有些老板几乎不知道办公室里发生了什么事情,所以他们也问他们的助手。 他们自己做一些工作,但是对于大多数其他事情他们需要助手的帮助。

在这种情况下,

老板 – 是Android的应用程序

助理 – 是上下文

文件/一杯咖啡 – 是资源

当我们需要获取有关应用程序的不同部分的信息(例如“活动”,“应用程序”等)

涉及上下文的一些操作(需要助手的地方):

加载公共资源创builddynamic视图显示Toast消息启动活动等获取上下文的不同方式:

 getContext() getBaseContext() getApplicationContext() this 

可以把它看作是运行应用程序或服务的虚拟机。独立环境可以访问一系列底层系统信息和某些允许的资源。 你需要这样的环境来获得这些服务。

只是把它放在那里为新手;

所以先了解Word上下文:

在英语中。 它的意思是:

“构成事件,陈述或想法的环境,以及可以充分理解和评估的情况。”

“书面或口语中的某些部分立即在一个字或一个段落之后,并且明确其含义。”

现在对编程世界也有同样的理解:

应用程序/对象当前状态的上下文。 它可以让新创build的对象了解到底发生了什么。 通常情况下,您可以调用它来获取有关程序的另一部分(活动,程序包/应用程序)

您可以通过调用getApplicationContext()getContext(), getBaseContext()this (在activity类中)来获取上下文。

要在应用程序的任何位置使用以下代码:

在android应用程序中创build新的类AppContext

 public class AppContext extends Application { private static Context context; public void onCreate(){ super.onCreate(); AppContext.context = getApplicationContext(); } public static Context getAppContext() { return AppContext.context; } } 

现在任何时候你想要在非活动类的应用程序上下文,调用这个方法,你有应用程序上下文。

希望这个帮助;)

  • 上下文表示获取环境数据的句柄。
  • Context类本身被声明为abstract,其实现由android OS提供。
  • 上下文就像电视和电video道的资源,服务等一样遥远。 在这里输入图像描述

你能用它做什么?

  • 加载资源。
  • 启动新的活动。
  • 创build视图。
  • 获得系统服务。

上下文的方法:

  • getApplicationContext()
  • getContext()
  • getBaseContext() 在这里输入图像描述 在这里输入图像描述

上下文是对当前对象的引用。 此外,上下文允许访问有关应用程序环境的信息。

android.content.Context提供了连接到Android系统和项目的资源。 它是有关应用程序环境的全局信息的接口。

Context还提供对Android服务的访问,例如定位服务。

活动和服务扩展了Context类。

上下文基本上是资源访问和获取应用程序(对于应用程序上下文)或活动(对于活动上下文)或任何其他的环境细节…

为了避免内存泄漏,您应该为每个需要上下文对象的组件使用应用程序上下文

上下文是应用程序/对象的当前状态的上下文,是表示各种环境数据的实体。 上下文有助于当前活动与本地文件,数据库,与环境相关的类加载器,包括系统级服务在内的外部android环境进行交互,等等。

上下文是系统的句柄。 它提供的服务包括parsing资源,获取数据库和首选项等等。 一个Android应用程序有活动。 它就像您的应用程序当前正在运行的环境的句柄。活动对象inheritance了Context对象。

不同的调用方法可以获得上下文1. getApplicationContext(),2. getContext(),3. getBaseContext()4.或this(当在activity类中)。

接口有关应用程序环境的全局信息。 这是一个抽象类,其实现由Android系统提供。 它允许访问特定于应用程序的资源和类,以及对应用程序级操作(如启动活动,广播和接收意图等)的调用。

上下文是类的实例android.content.Context提供连接到执行应用程序的Android系统。 例如,您可以通过上下文来检查当前设备显示的大小。

它还可以访问项目的资源。 它是有关应用程序环境的全局信息的接口。

Context类还提供对Android服务的访问,例如,警报pipe理器触发基于时间的事件。

活动和服务扩展了Context类。 因此他们可以直接用来访问上下文。

上下文是关于应用程序环境的全局信息的接口。 这是一个抽象类,其实现由Android系统提供。

Context允许访问特定于应用程序的资源和类,以及调用应用程序级操作,如launching activities, broadcasting and receiving intents, etc.

这里是例子

  public class MyActivity extends Activity { public void Testing() { Context actContext = this; /*returns the Activity Context since Activity extends Context.*/ Context appContext = getApplicationContext(); /*returns the context of the single, global Application object of the current process. */ Button BtnShowAct1 = (Button) findViewById(R.id.btnGoToAct1); Context BtnContext = BtnShowAct1.getContext(); /*returns the context of the View. */ 

有关更多详细信息,请访问http://developer.android.com/reference/android/content/Context.html

类android.content.Context的实例提供到执行应用程序的Android系统的连接。 例如,您可以通过上下文来检查当前设备显示的大小。

它还可以访问项目的资源。 它是有关应用程序环境的全局信息的接口。

Context类还提供对Android服务的访问,例如,警报pipe理器触发基于时间的事件。

活动和服务扩展了Context类。 因此他们可以直接用来访问上下文。

Context就是我们大多数人所称的应用程序 。 它是由Android系统制作的,只能执行应用程序的function。 在Tomcat中,Context也是我所说的应用程序。

有一个Context包含许多活动,每个Activity可以有很多Views。

很显然,有些人会说这不适合,因为这个或那个,他们可能是正确的,但说一个上下文是你目前的应用程序将帮助你了解你在方法参数。

如果你想在Android中连接Context和其他熟悉的类,请记住这个结构:

上下文<ContextWrapper <应用程序

上下文<ContextWrapper <ContextThemeWrapper <Activity

上下文<ContextWrapper <ContextThemeWrapper <Activity <ListActivity

上下文<ContextWrapper <服务

上下文<ContextWrapper <Service <IntentService

所以,所有这些类都是以自己的方式进行的。 如果您愿意,您可以将ServiceListActivity强制转换上下文 。 但是如果仔细观察,一些类也会inheritance主题。 在活动或片段中,您希望将主题应用于您的视图,但不要关心它的服务类。

我在这里解释不同的背景。

上下文是每个应用程序的沙盒 ,提供访问应用程序私人数据,如资源,数据库,私人filedirectories,首选项,设置的Android特定的API …

对于一个应用程序的所有活动/服务/广播听众来说,大多数私有数据是相同的。

由于Application,Activity和Service实现了Context接口,因此可以在api调用需要Context参数的情况下使用它们

上下文表示当前。 上下文用于当前屏幕的操作。 恩。 1.getApplicationContext()2.getContext()

Toast.makeText(getApplicationContext(),“hello”,Toast.LENGTH_SHORT).show();

上下文是应用程序/对象的当前状态的上下文,是表示各种环境数据的实体。 上下文有助于当前活动与本地文件,数据库,与环境相关的类加载器,包括系统级服务在内的外部android环境进行交互,等等。

上下文是系统的句柄。 它提供的服务包括parsing资源,获取数据库和首选项等等。 一个Android应用程序有活动。 它就像您的应用程序当前正在运行的环境的句柄。活动对象inheritance了Context对象。 上下文的使用示例:

  1. 创build新对象:创build新视图,适配器,侦听器

TextView tv = new TextView(getContext()); ListAdapter adapter = new SimpleCursorAdapter(getApplicationContext(),…);

  1. 访问标准通用资源:LAYOUT_INFLATER_SERVICE,SharedPreferences之类的服务:

context.getSystemService(LAYOUT_INFLATER_SERVICE)getApplicationContext()。getSharedPreferences( namemode );

  1. 隐式访问组件:关于内容提供者,广播,意图

getApplicationContext()。getContentResolver()。query(uri,…);

活动上下文与应用程序上下文的区别

They are both instances of Context, but the application instance is tied to the lifecycle of the application, while the Activity instance is tied to the lifecycle of an Activity. Thus, they have access to different information about the application environment.

If you read the docs at getApplicationContext it notes that you should only use this if you need a context whose lifecycle is separate from the current context.

But in general, use the activity context unless you have a good reason not to.

Need of Context :

The documentation says that every view needs the context to access the right resources (eg the theme, strings etc.).

But why in the constructor and not through setContentView(View)?

1.Because the resources must be accessible while the view is being constructed (the constructor will need some resources to fully initialise the view).

2.This allows the flexibility of using a context that is different from the one of the current activity (imagine a view that uses some other string resources and not the ones from the current activity).

3.The designers of the Android SDK seem to have chosen that the context must be set only once and then stay the same throughout the lifetime of the view. Why context is not determined automatically at construction point?

1.Because there exists no static variable that would tell you the current global context of your application. The method getApplicationContext() is the closest to this, but it's not static, so you need an instance of the Activity object to call it.

2.The Java language provides an option to look through the call stack and find whether the View has been constructed in a Context class. But what if there are many? Or what if there are none? This method is very expensive and error prone. So the designers of the API decided that a context must be manually provided.

Putting simple, Androids Context is a mess that you won't love until you stop worrying about.

Android Context s are:

  • God-objects.

  • Thing that you want to pass around all your application when you are starting developing for Android, but will avoid doing it when you get a little bit closer to programming, testing and Android itself.

    • Unclear dependency.

    • Common source of memory leaks.

    • PITA for testing.

  • Actual context used by Android system to dispatch permissions, resources, preferences, services, broadcasts, styles, showing dialogs and inflating layout. And you need different Context instances for some separate things (obviously, you can't show a dialog from an application or service context; layouts inflated from application and activity contexts may differ).

Boss Assistant Analogy

Lets have a small analogy before diving deep in the technicality of Context

Every Boss has an assistant or someone( errand boy) who does less important and more time consuming things for him. For example if they need a file or coffee then an assistant will be on run. Boss will not know what is going on in the background but the file or the task will be delivered

So Here
Boss – Android Application
Assistant – Context
File or cup of coffee – Resource

What official Android Developper site says about Context

Context is your accesss point for application related resources

Lets see some of such resources or tasks

  • Launching an activity.

  • Getting absolute path to the application specific cache directory on the filesystem.

  • Determining whether the given permission is allowed for a particular process and user ID running in the system.

  • Checking whether you have been granted a particular permission.

等等。
So if Android application wants to start an activity, it goes straight to Context(Access Point), and the Context class gives him back the resources(Intent in this case).

Like any other class Context class too has fields and methods.
You can explore more about Context in official documentation, it covers pretty much everything, available methods, fields and even how to use fields with methods.

Context means component (or application) in various time-period. If I do eat so many food between 1 to 2 pm then my context of that time is used to access all methods (or resources) that I use during that time. Content is an component (application) for particular time. Context of components of application keeps changing based on the underlying lifecycle of the components or application. For instance, inside the onCreate() of an Activity,

getBaseContext() — gives the context of the activity that is set (created) by the constructor of activity. getApplicationContext() — gives the context setup (created) during the creation of application.

Note: Application holds all Android Components.

 <application> <activity> .. </activity> <service> … </provider> <receiver> .. </receiver> <provider> .. </provider> </application> 

It means, when you call getApplicationContext() from inside whatever component, you are calling the common context of the whole application.

Context keeps being modified by the system based on the lifecycle of components

Context in Android is an interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

This attribute declares which activity this layout is associated with by default .

In Java, we say " this " keyword refers to the state of the current object of the application. Similarly, in an alternate we have Context in android development.

This can be defined either explicitly or implicitly,

 Context con = this; getApplicationContext(); getBaseContext(); getContext();