FD泄露导致 leaked window 导致App Crash
关键字:com.sec.android.widgetapp.ap.hero.cmaweather
1. 无 Error 9 dup channel fd -2147483647.
2. 有 Error 9 dup channel fd -2147483647. 关键字( dup channel fd )
关键字: leaked window
01-19 01:22:59.773 E/WindowManager(31106): Activity com.android.settings.bluetooth.BluetoothScanDialog has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{41b3e5f8 V.E..... R......D 0,0-480,447} that was originally added here
01-19 01:22:59.773 E/WindowManager(31106): android.view.WindowLeaked: Activity com.android.settings.bluetooth.BluetoothScanDialog has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{41b3e5f8 V.E..... R......D 0,0-480,447} that was originally added here
android.view.WindowLeaked:已经解决
解决:好多人都说这个是内存泄漏 我自己也弄了好久 终于找到了原因 哈哈 其实不是什么内存泄漏
原因是 activity 和dialog同时显示 要先dialog.dismiss() 后activity.finish() 如果直接finish() 会出错 但不影响功能。
该错误是由于在Activity中创建并显示了Alertdialog,但并未使用Activity提供的showDialog()方法,因此导致在Activity被结束后,Alertdialog所引用的context为空。解决办法为,
1, 将dialog采用oncreateDialog的方式创建,交由系统维护。
2, 在onDestroy()方法中将该alertdialog dismiss掉。
其意思大概就是:窗体已经关闭了但是dialog仍然在显示,Activity has leaked window(activity渗透出窗体),大概就是这个意思。
那么就要在activity finish()之前将dialog dismiss()掉。
我的做法就是重写本activity的onDestroy()方法,在此方法中将dialog清除
/** * 此方法必须重写,以决绝退出activity时 dialog未dismiss而报错的bug */ @Override protected void onDestroy() { // TODO Auto-generated method stub try{ myDialog.dismiss(); }catch (Exception e) { System.out.println("myDialog取消,失败!"); // TODO: handle exception } super.onDestroy(); }
|
//JBP_PROD/BAFFIN_Q/GT-I9168_CHN_ZM/android/frameworks/base/services/java/com/android/server/BluetoothManagerService.java
Looper.loop() android线程中的消息循环
Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环(message loop)的,需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用,从消息队列里取消息,处理消息。
注:写在Looper.loop()之后的代码不会被立即执行,当调用后mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。 |
每创建一个线程,他会占用3个FD, 如多线程不释放,那么压力测试的时候就会不断的占用FD, 而每个进程的FD数量是有限的,如果占用数量达到最大值,再申请的话就会出现leaked window异常。
最终解决
测试方法:
找最大的线程号,点击蓝牙图标,看弹框时时Thread后的数字会不会变大
参考资料: