今天遇到一个很奇特的问题,当用户设置了PIN码,在锁屏界面正常解锁PIN码后,进入Launcher时显示com.android.phone 已停止运行。一开始猜想会不会是解锁PIN码的时候处理导致了Phone进程报错,通过log分析找到了问题的大概原因:

AndroidRuntime: FATAL EXCEPTION: main
AndroidRuntime: java.lang.IllegalArgumentException: View not attached to window manager
AndroidRuntime: at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:385)
AndroidRuntime: at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:287)
AndroidRuntime: at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:79)
AndroidRuntime: at android.app.Dialog.dismissDialog(Dialog.java:323)
AndroidRuntime: at android.app.Dialog.dismiss(Dialog.java:306)
AndroidRuntime: at com.android.stk.StkDialogActivity$4.onClick(StkDialogActivity.java:188)
AndroidRuntime: at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:169)
AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
AndroidRuntime: at android.os.Looper.loop(Looper.java:153)
AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5299)
AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method)
AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:511)
AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)
转载请务必注明出处:http://blog.csdn.net/yihongyuelan

       通过分析PIN码的解锁流程知道,并不是PIN码解释时的dialog导致的问题。PIN码解锁流程另用文档说明。
仔细查看log后发现有:
AndroidRuntime: 	at com.android.stk.StkDialogActivity$4.onClick(StkDialogActivity.java:188)

这是开机识别到SIM卡之后弹出的STK对话框。那为什么会报com.android.phone已停止运行呢?

经过以上分析,我们可以大致猜测是因为STK引起的问题,既然是STK的问题那为什么会报phone的错误呢?如果是phone的错误那么从log中应该可以检索到phone相关的问题,为什么没有呢?那么我们接下来一一解答这些问题。

(1). 为什么报错com.android.phone已停止运行?

       通过查看STK的源码(单卡MTK的代码在/mediatec/packages/app/stk1),在其AndroidManifest.xml可以发现:
android:sharedUserId="android.uid.phone"
也就是STK和Phon在一个进程中,因此在报错的表现上来讲就会是com.andorid.phone。

(2). 为什么会报View not attached to window manager错误?

       这个错误的意思是说我们所操作的View没有被纳入window manager的管理。
       我们知道所有的窗口创建和管理都是依附于window manager的,因此Dialog的创建也不例外。Dialog的创建流程通过查看源码可以知道,在Dialog的构造函数中,创建了一个Window对象,但我们知道Window对象并不是用于显示的,真正用于显示的是View对象。因此通过Dialog的show方法构造了一个mDecor的View对象,并最终通过WindowManager的addView()方法显示Dialog。
       通过查看log信息我们可以看到com.android.stk.StkDialogActivity$4.onClick(StkDialogActivity.java:188)
查看对应的StkDialogActivity代码后发现,在188行处代码为dialog.dismiss();
       在网络上搜索后发现,多数情况下出现这种错误,都是在dismiss Dialog时,发现创建该Dialog的Activity存在而导致的。
比如在界面上显示一个Dialog,当任务处理结束后再Dismiss Dialog。如果在Dialog显示期间,该Activity因为某种原因被杀掉且又重新启动了,那么当任务结束时,Dismiss Dialog的时候WindowManager检查,就会发现该Dialog所属的Activity已经不存在了(重新启动了一次,是一个新的Activity),所以会报IllegalArgumentException: View not attached to window manager.
通过以上分析我们可以知道在STK Dialog在执行dismiss方法时,发现启动它的Activity已经不见了,被杀掉了(现在这个是重新启动的),所以才报错出现异常。

(3). 为什么STKDialogActivity会被"杀掉"?

       通过跟踪查看异常log我们可以看到StkDialogActivity的生命周期打印log如下:
onCreate
onResume - mbSendResp[false], sim id: 0
... ...省略部分
onSaveInstanceState
onPause, sim id: 0
... ...省略部分
onDestroy-
onCreate
... ...省略部分
onRestoreInstanceState - [com.android.internal.telephony.cat.TextMessage@41fe7d80]
onResume - mbSendResp[false], sim id: 0
到这里后就出现了异常错误……
       通过log我们可以很清楚的看到该Activity启动了两次。在log中我们也看到了onSaveInstanceState方法。
对于onSaveInstanceState方法,在Android SDK里面有这样的描述:
Android calls onSaveInstanceState() before the activity becomes vulnerable to being destroyed by the system, but does not bother calling it when the instance is actually being destroyed by a user action (such as pressing the BACK key)
也就说当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。
       注意这里的容易二字,当前Activity并没有被销毁,只是系统觉得它有可能会被销毁因此会执行该方法。在该方法中我们可以保存Activity中的各种数据信息,如果该Activity真的被杀掉而又重新启动后,可以使用onRestoreInstanceState方法在重新启动该Activity时,还原我们之前保存的数据信息。onSaveInstanceState方法的调用遵循一个重要原则,即当系统“未经你许可”销毁了你的Activity时,onSaveInstanceState就会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然如果你自己不保存,那就没法恢复了)。
       因此通过以上分析我们可以看到STKDialogActivity的确被杀掉后再次启动了,但为什么会被杀掉,通过log并没有找到答案。

(4). 在STKDialogActivity被杀掉时,Dialog存在么?

       可能大家会有疑问,Dialog都没有看到,就出现错误了,怎么能确定该Dialog当时一定是显示的呢?继续在log中搜索我们可以发现:
WindowManager: Activity com.android.stk.StkDialogActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{41fea228 V.E..... R.....ID 0,0-1026,433} that was originally added here
WindowManager: android.view.WindowLeaked: Activity com.android.stk.StkDialogActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{41fea228 V.E..... R.....ID 0,0-1026,433} that was originally added here
WindowManager: at android.view.ViewRootImpl.<init>(ViewRootImpl.java:409)
WindowManager: at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:218)
WindowManager: at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
WindowManager: at android.app.Dialog.show(Dialog.java:281)
WindowManager: at android.app.AlertDialog$Builder.show(AlertDialog.java:951)
WindowManager: at com.android.stk.StkDialogActivity.onCreate(StkDialogActivity.java:192)
WindowManager: at android.app.Activity.performCreate(Activity.java:5122)
WindowManager: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1081)
WindowManager: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2270)
WindowManager: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2358)
WindowManager: at android.app.ActivityThread.access$600(ActivityThread.java:156)
WindowManager: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1340)
WindowManager: at android.os.Handler.dispatchMessage(Handler.java:99)
WindowManager: at android.os.Looper.loop(Looper.java:153)
WindowManager: at android.app.ActivityThread.main(ActivityThread.java:5299)
WindowManager: at java.lang.reflect.Method.invokeNative(Native Method)
WindowManager: at java.lang.reflect.Method.invoke(Method.java:511)
WindowManager: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
WindowManager: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
WindowManager: at dalvik.system.NativeStart.main(Native Method)

这里的WindowManager报错是什么意思呢? 这段log是WindowManager抛出的error错误,当我们的Dialog还没有dismiss时,如果此时该Activity被销毁了,那么就会出现以上错误,提示窗口泄漏(leaked window)。这里自己也做了一个实验,写一个demo,在Activity的onCreate方法中显示一个Dialog,然后直接调用finish方法。代码大致如下:

    protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlertDialog.Builder info = new Builder(this);
info.setTitle("Dialog").setPositiveButton("OK", null).setMessage("This is a Dialog");;
info.show();
finish();
}

直接将此程序run到模拟器或者真机上,查看log我们就能看到leaked window的报错信息。因此这也证明了前面我们的假设,即StkActivity在被销毁时,其所依附的 Dialog是存在的。

(5). 如何解决这个问题呢?

       通过以上分析之后我们知道了问题出现的原因,那么如何解决呢?可以通过以下两个方面来解决:

1. 使用Activity自带的Dialog控制方法

       在Activity中需要使用对话框,可以使用Activity自带的回调,比如onCreateDialog(),showDialog(),dimissDialog(),removeDialog()等等。毕竟这些都是Activity自带的方法,所以用起来更方便,也不用显示创建和操控Dialog对象,一切都由框架操控,相对来说比较安全。

2. 限制Dialog的生命周期

       让创建的Dialog对象的存活周期跟Activity的生命周期一致,也就是说Dialog的生命周期被限定在Activity的onCreate()和onDestroy()方法之间。


关于java.lang.IllegalArgumentException: View not attached to window manager 错误的分析的更多相关文章

  1. java.lang.IllegalArgumentException: View not attached to window manager

    公司项目线上bug: java.lang.IllegalArgumentException: View not attached to window manager at android.view.W ...

  2. decorview that was originally added here or java.lang.IllegalArgumentException: View not attached to window manager

    使用Dialog的时候,没少出现下面这两个报错 12-11 17:47:49.776: E/WindowManager(11461): android.view.WindowLeaked: Activ ...

  3. bug_ _java.lang.IllegalArgumentException: View not attached to window manager 2

    今天遇到一个很奇特的问题,当用户设置了PIN码,在锁屏界面正常解锁PIN码后,进入Launcher时显示com.android.phone 已停止运行.一开始猜想会不会是解锁PIN码的时候处理导致了P ...

  4. bug_ _java.lang.IllegalArgumentException: View not attached to window manager

    ============= 1   view not attached to window manager 转自:http://hi.baidu.com/spare_h/blog/item/7fa3e ...

  5. Android中 View not attached to window manager错误的解决办法

    前几日出现这样一个Bug是一个RuntimeException,详细信息是这样子的:java.lang.IllegalArgumentException: View not attached to w ...

  6. 关于dialog引起的 java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView not attached to window manager 错误的分析

    在跑Monkey测试的时候出现了一个比较特别的问题,先来看看Log: // CRASH: com.meizu.media.painter (pid 12491) // Short Msg: java. ...

  7. View not attached to window manager

    java.lang.IllegalArgumentException: View not attached to window manager 在用ProgressDialog的时候,任务结束后Dis ...

  8. View not attached to window manager crash 的解决办法

    View not attached to window manager crash 的解决办法 转自:http://stackoverflow.com/questions/22924825/view- ...

  9. spring报nested exception is java.lang.IllegalArgumentException: @EnableAsync annotation metadata was not injected错误

    http://www.oschina.net/question/1539472_159699

随机推荐

  1. [转]Loadrunner11之VuGen运行时设置Run-Time Setting

    转自:http://www.51testing.com/html/92/450992-248065.html General 1.Run Logic运行逻辑 脚本如何运行的,每个action和acti ...

  2. Spring配置数据库固定代码

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" > &l ...

  3. HighChart 实现从后台取数据来实时更新柱状和折线组图

    前段时间公司让弄图表,给我说有HighCharts这个js插件,于是上网上搜,由于本人是写后端的,对于JavaScript和jQuery不是很熟悉,虽然找到了模板,但是还是不明白,所以一点一点的改,但 ...

  4. 一步步实现Promise

    最近在https://github.com/ThoughtWorksInc/rest-rpc上工作,遇到了一个scala隐式转换的问题,简单的说是要实现这么个东西: implicit def json ...

  5. Maven 包命令

    1.必须选中项目,然后单击Run As,选择Maven build. 2.在配置窗体中的Goals栏填写clean package. 注意:Installed JREs中配置的JREs的位置必须是JD ...

  6. poj 3006 Dirichlet's Theorem on Arithmetic Progressions

    题目大意:a和d是两个互质的数,则序列a,a+d,a+2d,a+3d,a+4d ...... a+nd 中有无穷多个素数,给出a和d,找出序列中的第n个素数 #include <cstdio&g ...

  7. Attach source code to a Netbeans Library Wrapper Module

    http://rubenlaguna.com/wp/2008/02/22/attach-source-code-to-a-netbeans-library-wrapper-module/ Attach ...

  8. <<海闻电子发票接口 ESB 封装 代码指示 文档>>

    <<海闻电子发票接口 ESB 封装 代码指示 文档>> isValid 是否有效标志 代码 中文 说明 true 成功 false 失败   code 海闻错误说明 代码 中文 ...

  9. RS-232-C串口通讯协议解析(硬件接口协议)

    http://www.dz3w.com/info/interface/0075524.html http://wenku.baidu.com/view/02cc247c27284b73f24250e3 ...

  10. TdxAlertWindowManager右下角HINT显示控件

    带爱像的右下角HINT显示,自动隐藏 function alterInfo: TdxAlertWindowManager;begin  if not Assigned(Falter) then  be ...