为什么 AlertDialog.Builder(Context context) 只接受 Activity 作为参数? [英] Why does AlertDialog.Builder(Context context) only accepts Activity as a parameter?

查看:36
本文介绍了为什么 AlertDialog.Builder(Context context) 只接受 Activity 作为参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我持续的学习过程中(这次是对话框),我发现这是有效的:

In my ongoing learning process (dialog boxes this time), I discovered that this works:

  AlertDialog.Builder builder = new AlertDialog.Builder(this);

虽然以下不起作用(在运行时因 WindowManager$BadTokenException 失败):

While the following doesn't work (fails at runtime with WindowManager$BadTokenException):

  AlertDialog.Builder builder = new AlertDialog.Builder(this.getApplicationContext());

我不明白为什么,因为 构造函数 被定义为接受 Context 作为参数,而不是 Activity:

I don't understand why, because the constructor for AlertDialog.Builder is defined to accept Context as a parameter, not Activity:

public AlertDialog.Builder(上下文上下文)

public AlertDialog.Builder (Context context)

为此使用上下文的构造函数builder 和 AlertDialog 吧创建.

Constructor using a context for this builder and the AlertDialog it creates.

我错过了什么?

推荐答案

一个活动继承了一个上下文.AlertDialog.Builder 指定了一个 Context 参数,因为它可以被作为 Context 子类的任何类使用,包括 Activity、ListActivity、Service 等(这背后有一个通用的编码习惯 - 你可以了解更多关于它通过阅读 Joshua Bloch 出色的 Effective Java 中的第 I8 项(关于接口和抽象类).

An Activity inherits a Context. AlertDialog.Builder specifies a Context argument because it can then be used by ANY class that is a subclass of Context, including an Activity, ListActivity, Service, ... (There is a common coding idiom behind this - you can learn more about it by reading Item I8 (on Interfaces and Abstract classes) in Joshua Bloch's fantastic Effective Java).

getApplicationContext() 返回您的应用程序的上下文,这与您的活动上下文大致相同 - 而主要"是让您失望的原因.细节不清楚,但这是一个广泛遇到的问题,典型的答案是使用将警报写入屏幕的上下文.请注意,这 不是 getApplicationContext() 返回的那个.

getApplicationContext() returns the context for your application, which is mostly the same as your activities context - and the "mostly" is what is throwing you off. The details are unclear but this is a widely encountered issue, and the typical answer is to use the context that will be writing the alert to the screen. Note that that is not the one returned by getApplicationContext().

现在,如果你像我一样,你可能会说但我在一个不从 Activity 继承的类中工作 - 这就是为什么我想首先使用 getApplicationContext() - 呃!"我实际上不会说得那么粗鲁;p .. 重点是我也来过这里.我是这样修复它的:1)问自己我是否在非活动类中有我的 UI AlertDialog 代码,因为我想在活动之间共享它......甚至跨越 ListActivities、服务......?".如果没有,嗯...你真的有代码中的 AlertDialog UI 调用,你不能保证可以访问 UI(以及上下文)?如果是这样,请重新考虑您的设计.

Now if you're like me, you may say "but I am working in a class that does not inherit from Activity - which is why I want to use getApplicationContext() for this in the first place - duh!" I'm actually don't speak as rudely as that ;p .. the point was I've been here too. I fixed it like so: 1) ask yourself "do I have my UI AlertDialog code in a non-activity class because I want to share it across activities .. or even across ListActivities, Services, ...?". If not, hmmm... do you really have AlertDialog UI calls in code that you can't guarantee will have access to the UI (and thus context)? If so, reconsider your design.

假设您确实希望跨活动共享该课程,...答案就很清楚了.您希望您的类可供各种调用者使用,每个调用者可能都有自己的上下文:因此调用者必须将其上下文作为参数传递给您的类:

Presuming you do want to share this class across Activities, ... the answer becomes clear. You want your class to be usable by a variety of callers, each probably with its own context: so the caller must pass its context into your class as an argument:

myClass(Context theContext, ...) { ... }

每个活动、服务等然后像这样进行调用:

Each activity, service, etc. then makes calls like so:

myClass(this, ...);

看起来很眼熟?

千万小心!如果您正在共享代码,您必须考虑不同调用并行进入您的共享代码的可能性,以及所有这些后果.这超出了我们的范围......

Do be careful! that if you are sharing code, you must consider the possibility of different calls coming into your shared code in parallel, with all the many ramifications. Thats beyond our scope here...

玩得开心:)

这篇关于为什么 AlertDialog.Builder(Context context) 只接受 Activity 作为参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆