an0*_*00b 34 android android-context android-alertdialog android-activity
在我正在进行的学习过程中(这次是对话框),我发现这有效:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
Run Code Online (Sandbox Code Playgroud)
虽然以下方法不起作用(运行时因WindowManager $ BadTokenException而失败):
AlertDialog.Builder builder = new AlertDialog.Builder(this.getApplicationContext());
Run Code Online (Sandbox Code Playgroud)
我不明白为什么,因为AlertDialog.Builder 的构造函数被定义为接受Context作为参数,而不是Activity:
public AlertDialog.Builder(Context context)
构造函数使用此构建器的上下文及其创建的AlertDialog.
我错过了什么?
DJC*_*DJC 25
活动继承Context.AlertDialog.Builder指定一个Context参数,因为它可以由作为Context的子类的任何类使用,包括Activity,ListActivity,Service,......(这背后有一个共同的编码习惯用法 - 你可以了解更多关于它的信息通过阅读Joshua Bloch精彩的Effective Java中的第I8项(关于接口和抽象类).
getApplicationContext()返回应用程序的上下文,它与您的活动上下文大致相同 - 而"大多数"是让您失望的内容.细节尚不清楚,但这是一个广泛遇到的问题,典型的答案是使用将警报写入屏幕的上下文.请注意,这不是 getApplicationContext()返回的那个.
现在如果你像我一样,你可能会说"但我在一个不从Activity继承的类中工作 - 这就是为什么我想首先使用getApplicationContext()为什么 - 呃!" 我实际上并不像那样粗鲁地说话; p ...重点是我也来过这里.我修理它是这样的:1)问问自己"我是否在非活动类中使用了我的UI AlertDialog代码,因为我希望跨活动分享它......甚至是在ListActivities,Services,...?"中.如果没有,嗯...你真的在代码中有AlertDialog UI调用,你不能保证可以访问UI(以及上下文)吗?如果是这样,请重新考虑您的设计.
假设你确实希望跨活动分享这个课程,......答案就变得清晰了.您希望您的类可以被各种调用者使用,每个调用者可能都有自己的上下文:因此调用者必须将其上下文作为参数传递给您的类:
myClass(Context theContext, ...) { ... }
然后,每个活动,服务等都会调用:
myClass(this, ...);
看起来熟悉?
小心点!如果您要共享代码,则必须考虑并行调用共享代码的不同调用的可能性,以及所有分支.这超出了我们的范围......
玩得开心 :)
j__*_*__m 13
AlertDialog是Dialog的子类,它有一个关联的Window,它有一个关联的LayoutParams.其中一个参数是窗口类型.默认类型为TYPE_APPLICATION_ATTACHED_DIALOG,需要父窗口.
与Activity关联的WindowManager配置为使用Activity的窗口作为父窗口.与Application关联的WindowManager没有关联的父窗口.
底线:要成功显示对话框,您必须将默认窗口类型更改为不需要父窗口的类型,或者必须使用具有关联父窗口的上下文.