android bad进程,android.view.WindowManager$BadTokenException崩溃的4种情形

此文包含android.view.WindowManager$BadTokenException的4种情形:

1.Unable to add window --token null is not valid; is your activity running

**2.Unable to add window --token null is not for an application **

3.Unable to add window -- token android.os.BinderProxy@XXX is not valid;

is your activity running

**4.Unable to add window -- token android.app.LocalActivityManager

$LocalActivityRecord @xxx is not valid; is your activity running

**

情形1.android.view.WindowManager$BadTokenException: Unable to add window --token null is not valid; is your activity running?异常处理。

$BadTokenException: Unable to add window --

token null is not valid; is your activity running

E/AndroidRuntime(1412): at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)

......

该异常多见于Popup Window组件的使用中抛出。

原因:错误在PopupWindow.showAtLocation(findViewById(R.id.main), Gravity.BOTTOM,0,0); popwindow必须依附于某一个view,而在oncreate中view还没有加载完毕,必须要等activity的生命周期函数全部执行完毕,你需要依附的view加载好后才可以执行popwindow。

解决办法:showAtLocation()函数可以这样改:

//修正后代码

findviewById(R.id.mView).post(new Runnable() {

@Override

public void run() {

popwindow.showAtLocation(mView, Gravity.CENTER, 0, 0);

}

});

总结: PopupWindow必须在某个事件中显示或者是开启一个新线程去调用,不能直接在onCreate方法中显示一个Popupwindow,否则永远会有以上的错误。

情形2.android.view.WindowManager$BadTokenException: Unable to add window --token null is not for an application ?异常处理。

$BadTokenException: Unable to add window --

token null is not for an application

E/AndroidRuntime(1412): at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)

......

该异常多见于AlertDialog组件的使用中抛出。

//抛异常代码

new AlertDialog.Builder(getApplicationContext()) //不能用getApplicationContext()

.setIcon(android.R.drawable.ic_dialog_alert)

.setTitle("Warnning")

.setPositiveButton("Yes", positiveListener)

.setNegativeButton( "No", negativeListener)

.create().show();

原因:导致报这个错是在于new AlertDialog.Builder(mcontext),虽然这里的参数是AlertDialog.Builder(Context context),但我们不能使用getApplicationContext()获得的Context,而必须使用Activity,因为只有一个Activity才能添加一个窗体。

解决方法:将new AlertDialog.Builder(Context context)中的参数用Activity.this(Activity是你的Activity的名称)或者getActivity()来填充就可以正确的创建一个Dialog了。

//修正后代码

new AlertDialog.Builder(this) //this可以替换为MainActivity.this或getActivity()

.setIcon(android.R.drawable.ic_dialog_alert)

.setTitle("Warnning")

.setPositiveButton("Yes", positiveListener)

.setNegativeButton( "No", negativeListener)

.create().show();

情形3.android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@XXX is not valid; is your activity running?异常处理。

android.view.WindowManager$BadTokenException: Unable to add window --

token android.os.BinderProxy@4250d6d8 is not valid; is your activity running?

at android.view.ViewRootImpl.setView(ViewRootImpl.java:698)

......

at dalvik.system.NativeStart.main(Native Method)

原因:从错误信息我们也可以明白其原因,此问题根本原因就是由于将要弹出的dialog所要依附的View已经不存在导致的。当界面销毁后再弹出来;或者界面跳转时我们的view发生改变,dialog依附的context发生变化或者界面未运行了。

解决方法:界面已经销毁引起的错误就只能判断界面是否存在然后再弹出了。

//修正后代码

if(!isFinishing()) {

alert.show();

}

情形4.android.view.WindowManager

math?formula=BadTokenException%3A%20Unable%20to%20add%20window%20--%20token%20android.app.LocalActivityManagerLocalActivityRecord @xxx is not valid; is your activity running? 异常处理。

android.view.WindowManager$BadTokenException: Unable to add window --

token android.app.LocalActivityManager$LocalActivityRecord@43e5b158

is not valid; is your activity running?

//异常代码

TipDialog dialog = new TipDialog(XXX.this) ;

原因:因为new对话框的时候,参数context 指定成了this,即指向当前子Activity的context。但子Activity是动态创建的,不能保证一直存在。其父Activity的context是稳定存在的,所以有下面的解决办法。

解决方法:将context替换为getParent()即可。 注意:要创建dialog对象,上下文环境必须是activity,同时若ActivityGroup中嵌套ActivityGroup,嵌套多少就该使用多少个getParent()。

//修正后代码,只有最多一个parent的情形

TipDialog dialog = new TipDialog(getParent()) ;

//修正后代码,适用于一个或多个parent的情形

Activity activity = TestActivity.this;

while (activity.getParent() != null) {

activity = activity.getParent();

}

TipDialog dialog = new TipDialog(activity) ;

注:为什么要使用getParent我们可以从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中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值