Android异常:that was originally added here
2014-06-26 20:32
369 查看
摘要: android.view.WindowLeaked: Activity com.test.activity.TestActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@427bebc8 that was originally added here
这是我在播放视频弹出Dialog时,出现的异常。
分析:
经常在应用中需要处理一些耗时的工作,诸如读取大文件、访问网络资源等。为了避免因程序假死而带来的糟糕用户体验,通常我们可以通过线程+Handler或者Android提供的AsyncTask来解决该问题,并一般以ProgressDialog等提示性控件来告知用户当前的程序进度。而标题中描述的异常则会常常出现在这样的场景中,并且往往掩盖了导致异常的真正的罪魁祸首。
问题原因:
从 异常描述中,大致的意思是存在窗口句柄泄露,即未能及时销毁某个PhoneWindow。而这往往误导了我们,把过多的精力放在查找所谓的内存泄露上了。 其实存在这么一种情况,即因我们在非主线程中的某些操作不当而产生了一个严重的异常,从而强制当前Activity被关闭。而在关闭的同时,却没能及时的 调用dismiss来解除对ProgressDialog等的引用,从而系统抛出了标题中的错误,而掩盖了真正导致这个错误的异常信息。
解决方法之一:
本解决方法并不能真正的解决问题,但是在一定程度上可以将真正导致错误的异常信息显露出来。即重写Activity的onDestroy方法,在方法中调用dismiss来解除对ProgressDialog等的引用。
另外引出的一个异常
Unable to add window -- token android.os.BinderProxy@42f10c40 is not valid; is your activity running?
因为使用了线程,在线程完成以后弹出窗口。
这个时候如果用户在线程未执行完 按了返回按钮,activity已经onDestory了,
那么就会报出android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4479b390 is not valid; is your activity running?
解决方法一在弹出窗口之前用Activity的isFinishing判断一下Activity是否还存在。
02-19 15:08:02.228: E/WindowManager(22172): Activity com.test.activity.TestActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@427bebc8 that was originally added here 02-19 15:08:02.228: E/WindowManager(22172): android.view.WindowLeaked: Activity com.test.activity.TestActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@427bebc8 that was originally added here 02-19 15:08:02.228: E/WindowManager(22172): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:438) 02-19 15:08:02.228: E/WindowManager(22172): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:292) 02-19 15:08:02.228: E/WindowManager(22172): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224) 02-19 15:08:02.228: E/WindowManager(22172): at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149) 02-19 15:08:02.228: E/WindowManager(22172): at android.view.Window$LocalWindowManager.addView(Window.java:558) 02-19 15:08:02.228: E/WindowManager(22172): at android.app.Dialog.show(Dialog.java:316) 02-19 15:08:02.228: E/WindowManager(22172): at com.test.activity.TestActivity.onError(TestActivity.java:326) 02-19 15:08:02.228: E/WindowManager(22172): at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:2113) 02-19 15:08:02.228: E/WindowManager(22172): at android.os.Handler.dispatchMessage(Handler.java:99) 02-19 15:08:02.228: E/WindowManager(22172): at android.os.Looper.loop(Looper.java:137) 02-19 15:08:02.228: E/WindowManager(22172): at android.app.ActivityThread.main(ActivityThread.java:4881) 02-19 15:08:02.228: E/WindowManager(22172): at java.lang.reflect.Method.invokeNative(Native Method) 02-19 15:08:02.228: E/WindowManager(22172): at java.lang.reflect.Method.invoke(Method.java:511) 02-19 15:08:02.228: E/WindowManager(22172): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:804) 02-19 15:08:02.228: E/WindowManager(22172): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:571) 02-19 15:08:02.228: E/WindowManager(22172): at dalvik.system.NativeStart.main(Native Method)
这是我在播放视频弹出Dialog时,出现的异常。
分析:
经常在应用中需要处理一些耗时的工作,诸如读取大文件、访问网络资源等。为了避免因程序假死而带来的糟糕用户体验,通常我们可以通过线程+Handler或者Android提供的AsyncTask来解决该问题,并一般以ProgressDialog等提示性控件来告知用户当前的程序进度。而标题中描述的异常则会常常出现在这样的场景中,并且往往掩盖了导致异常的真正的罪魁祸首。
问题原因:
从 异常描述中,大致的意思是存在窗口句柄泄露,即未能及时销毁某个PhoneWindow。而这往往误导了我们,把过多的精力放在查找所谓的内存泄露上了。 其实存在这么一种情况,即因我们在非主线程中的某些操作不当而产生了一个严重的异常,从而强制当前Activity被关闭。而在关闭的同时,却没能及时的 调用dismiss来解除对ProgressDialog等的引用,从而系统抛出了标题中的错误,而掩盖了真正导致这个错误的异常信息。
解决方法之一:
本解决方法并不能真正的解决问题,但是在一定程度上可以将真正导致错误的异常信息显露出来。即重写Activity的onDestroy方法,在方法中调用dismiss来解除对ProgressDialog等的引用。
另外引出的一个异常
Unable to add window -- token android.os.BinderProxy@42f10c40 is not valid; is your activity running?
因为使用了线程,在线程完成以后弹出窗口。
这个时候如果用户在线程未执行完 按了返回按钮,activity已经onDestory了,
那么就会报出android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4479b390 is not valid; is your activity running?
解决方法一在弹出窗口之前用Activity的isFinishing判断一下Activity是否还存在。
if (!Activity.isFinishing() && !dialog.isShowing()) { dialog.show(); }
相关文章推荐
- has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here异常解决
- 【转】Android异常:that was originally added here
- 问题排查:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here
- Android排错:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here
- has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here
- android.view.WindowLeaked:PhoneWindow$DecorView@405297d0 that was originally added here
- Android 报错:has leaked window XXXXX that was originally added here
- has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here
- Android排错:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here
- Android排错: has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here
- Android排错:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here
- Android排错:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here
- Android常见错误之android.widget.LinearLayout@4375f248 that was originally added here
- Android排错:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here
- Android 开发 Tip 3 -- that was originally added here
- Android排错:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added
- Android排错:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added
- Android排错:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added
- Android错误:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added
- Android排错:has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added