今天遇到一个很奇特的问题,当用户设置了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)
AndroidRuntime: at com.android.stk.StkDialogActivity$4.onClick(StkDialogActivity.java:188)
这是开机识别到SIM卡之后弹出的STK对话框。那为什么会报com.android.phone已停止运行呢?
经过以上分析,我们可以大致猜测是因为STK引起的问题,既然是STK的问题那为什么会报phone的错误呢?如果是phone的错误那么从log中应该可以检索到phone相关的问题,为什么没有呢?那么我们接下来一一解答这些问题。
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
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是存在的。