`

ActivityGroup中的子Activity创建Dialog:android.view.WindowManager$BadTokenException: U

阅读更多
我们在ActivityGroup或者TabActivity中的子Activity创建Dialog若使用以下的代码
progressDialog = new ProgressDialog(XXX.this)

创建就会出现如下Exception:
05-24 12:34:42.236: ERROR/AndroidRuntime(6362): android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord@43e5b158 is not valid; is your activity running?


而该使用:
progressDialog = new ProgressDialog(getParent())


若ActivityGroup中嵌套ActivityGroup,嵌套多少就该使用多少个getParent()。

为什么要使用getParent我们可以从柯元旦的《Android内核剖析》中第十章”Ams内部原理“中的ActivityGroup的内部机制来理解:
TabActivity的父类是ActivityGroup,而ActivityGroup的父类是Activity。因此从Ams的角度来看,ActivityGroup与普通的Activity没有什么区别,其生命周期包括标准的start,stop,resume,destroy等,而且系统中只允许同时允许一个ActivityGroup.但ActivityGroup内部有一个重要成员变量,其类型为LocalActivityManager,该类的最大特点在于它可以访问应用进程的主类,即ActivityThread类。Ams要启动某个Activity或者赞同某个Activity都是通过ActivityThread类执行的,而LocalActivityManager类就意味着可以通过它来装载不同的Activity,并控制Activity的不同的状态。注意,这里是装载,而不是启动,这点很重要。所谓的启动,一般是指会创建一个进程(如果所在的应用经常还不存在)运行该Activity,而装载仅仅是指把该Activity作为一个普通类进行加载,并创建一个该类的对象而已,而该类的任何函数都没有被运行。装载Activity对象的过程对AmS来讲是完全不可见的,那些嵌入的Activity仅仅贡献了自己所包含的Window窗口而已。而子Activity的不同状态是通过moveToState来处理的。

所以子Activity不是像普通的Activity一样,它只是提供Window而已,所以在创建Dialog时就应该使用getParent获取ActivityGroup真正的Activity,才可以加Dialog加入Activity中。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics