在不同的Android代码中,我看到:

 public class MyActivity extends Activity {
    public void method() {
       mContext = this;    // since Activity extends Context
       mContext = getApplicationContext();
       mContext = getBaseContext();
    }
 }

然而,我找不到任何像样的解释,说明哪种方法更可取,以及在什么情况下应该使用哪种方法。

如果您选择了错误的选项,将非常感谢您提供有关该选项的文档指针,以及关于可能出现故障的指导。


当前回答

首先,我同意我们应该尽可能使用appcontext。然后是"this" in activity。我从来不需要基本的上下文。

在我的测试中,大多数情况下它们是可以互换的。在大多数情况下,您想要获得上下文的原因是访问文件、首选项、数据库等。这些数据最终会以文件的形式反映在应用程序的私有数据文件夹(/data/data/)中。无论你使用哪个上下文,它们都将被映射到相同的文件夹/文件,所以没问题。

这就是我观察到的。也许在某些情况下你应该区分它们。

其他回答

几天前我读了这篇文章,问自己同样的问题。读完这篇文章后,我的决定很简单:始终使用applicationContext。

然而,我遇到了一个问题,我花了几个小时找到它,并在几秒钟解决它…(改变了一个词…)

我正在使用LayoutInflater来膨胀包含旋转器的视图。

所以这里有两种可能性:

1)

    LayoutInflater layoutInflater = LayoutInflater.from(this.getApplicationContext());

2)

    LayoutInflater layoutInflater = LayoutInflater.from(this.getBaseContext());

然后,我做了这样的事情:

    // managing views part
    View view = ContactViewer.mLayoutInflater.inflate(R.layout.aViewContainingASpinner, theParentView, false);
    Spinner spinner = (Spinner) view.findViewById(R.id.theSpinnerId);
    String[] myStringArray = new String[] {"sweet","love"};

    // managing adapter part
    // The context used here don't have any importance -- both work.
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this.getApplicationContext(), myStringArray, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);

    theParentView.addView(view);

我注意到:如果你实例化你的线性布局与applicationContext,那么当你点击你的活动中的旋转器,你会有一个未捕获的异常,来自dalvik虚拟机(不是从你的代码,这就是为什么我花了很多时间来寻找哪里是我的错误…)

如果你使用baseContext,那么没关系,上下文菜单将打开,你将能够在你的选项中进行选择。

所以这是我的结论:我认为(我没有进一步测试)比baseContext是必需的处理上下文菜单在你的活动…

测试使用API 8进行编码,并在HTC Desire、android 2.3.3上进行测试。

希望我的评论到目前为止没有让你厌烦,祝你一切顺利。快乐编码;-)

造成这种困惑的原因是有很多方法 access上下文,(表面上)没有明显的区别。 下面是四种最常见的方法 活动中的上下文。

getContext()
getBaseContext()
getApplicationContext()
getActionBar().getThemedContext() //new

什么是上下文? 我个人喜欢把上下文看作应用程序在任何给定时间的状态。应用程序上下文表示应用程序的全局或基本配置,活动或服务可以构建在它之上,并表示应用程序的配置实例或它的传递状态。

看看android。content的源代码。Context,你可以看到Context是一个抽象类,类上的注释如下:

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. What I take away from this is that Context provides a common implementation to access application level as well as system level resources. Application level resources may be accessing things like String resources [getResources()] or assets [getAssets()] and system-level resource is anything that you access with Context.getSystemService().

事实上,看看这些方法的评论,它们似乎强化了这个概念:

getSystemService(): Return the handle to a system-level service by name. The class of the returned object varies by the requested name. getResources(): Return a Resources instance for your application’s package. getAssets(): Return a Resources instance for your application’s package. It may be worth pointing out that in the Context abstract class, all of the above methods are abstract! Only one instance of getSystemService(Class) has an implementation and that invokes an abstract method. This means, the implementation for these should be provided mostly by the implementing classes, which include:

ContextWrapper
Application
Activity
Service
IntentService

查看API文档,类的层次结构是这样的:

上下文

| - ContextWrapper

| - -应用

|— — 上下文主题包装器

| - - -活动

| - -服务

|— — 意图服务

Since we know that Context itself is not providing any insight, we move down the tree and take a look at the ContextWrapper and realize that there isn't much there either. Since Application extends ContextWrapper, there isn't much to look at over there either since it doesn't override the implementation provided by ContextWrapper. This means that the implementation for Context is provided by the OS and is hidden from the API. You can take a look at the concrete implementation for Context by looking at the source for the ContextImpl class.

简单地说

getApplicationContext()正如方法名称所暗示的那样,将使你的应用程序意识到你可以从应用程序的任何地方访问的应用程序范围的细节。所以你可以在服务绑定,广播注册等中使用它。应用程序上下文将一直存在,直到应用程序退出。

getActivity()或这将使你的应用程序意识到当前屏幕,这也是可见的应用程序上下文提供的应用程序级别的细节。你想知道的关于当前屏幕的任何东西比如Window ActionBar Fragementmanger都可以通过这个context得到。基本上和活动扩展上下文。在当前组件(活动)激活之前,该上下文都是激活的

我同意,当涉及到Android中的上下文时,文档很少,但你可以从各种来源拼凑一些事实。

谷歌Android开发者官方博客上的这篇文章主要是为了帮助解决内存泄漏问题,但也提供了一些关于上下文的好信息:

在常规的Android应用程序中,您 通常有两种语境, 活动和应用程序。

Reading the article a little bit further tells about the difference between the two and when you might want to consider using the application Context (Activity.getApplicationContext()) rather than using the Activity context this). Basically the Application context is associated with the Application and will always be the same throughout the life cycle of your app, where as the Activity context is associated with the activity and could possibly be destroyed many times as the activity is destroyed during screen orientation changes and such.

我找不到任何关于何时使用getBaseContext()的东西,除了Dianne Hackborn的一篇帖子,她是谷歌的工程师之一,致力于Android SDK:

不要使用getBaseContext(),只需使用 你所拥有的环境。

这是来自Android开发人员新闻组的一篇帖子,你可能也想在那里问你的问题,因为有少数Android工作人员实际上在监控那个新闻组并回答问题。

因此,总的来说,尽可能使用全局应用程序上下文似乎更可取。

首先,我同意我们应该尽可能使用appcontext。然后是"this" in activity。我从来不需要基本的上下文。

在我的测试中,大多数情况下它们是可以互换的。在大多数情况下,您想要获得上下文的原因是访问文件、首选项、数据库等。这些数据最终会以文件的形式反映在应用程序的私有数据文件夹(/data/data/)中。无论你使用哪个上下文,它们都将被映射到相同的文件夹/文件,所以没问题。

这就是我观察到的。也许在某些情况下你应该区分它们。