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

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

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

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


当前回答

几天前我读了这篇文章,问自己同样的问题。读完这篇文章后,我的决定很简单:始终使用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上进行测试。

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

其他回答

我同意,当涉及到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/)中。无论你使用哪个上下文,它们都将被映射到相同的文件夹/文件,所以没问题。

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

在某些情况下,当在线程中运行某些内容时,您可能会使用活动上下文而不是应用程序上下文。当线程完成执行并且需要将结果返回给调用者活动时,您需要具有处理程序的上下文。

((YourActivity) context).yourCallbackMethod(yourResultFromThread, ...);

我只使用这个和getBaseContext从一个onClick toast(非常绿色的新手到Java和android)。当我的点击器直接在活动中,并且必须在匿名的内部点击器中使用getBaseContext时,我使用这个。我猜这就是getBaseContext的诀窍,它可能返回隐藏内部类的活动的上下文。

几天前我读了这篇文章,问自己同样的问题。读完这篇文章后,我的决定很简单:始终使用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上进行测试。

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