09-17 23:03:38.954: E/WindowManager(1994): android.view.WindowLeaked: Activity app.ui.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{b2d3d4e0 V.E..... R.....I. 0,0-280,139} that was originally added here 09-17 23:03:38.954: E/WindowManager(1994): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:348) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69) 09-17 23:03:38.954: E/WindowManager(1994): at android.app.Dialog.show(Dialog.java:286) 09-17 23:03:38.954: E/WindowManager(1994): at app.ui.MainActivity.showExitDialog(MainActivity.java:69) 09-17 23:03:38.954: E/WindowManager(1994): at app.ui.MainActivity.onKeyDown(MainActivity.java:48) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.KeyEvent.dispatch(KeyEvent.java:2640) 09-17 23:03:38.954: E/WindowManager(1994): at android.app.Activity.dispatchKeyEvent(Activity.java:2423) 09-17 23:03:38.954: E/WindowManager(1994): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1962) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3418) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3558) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:3718) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2010) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1704) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1695) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:1987) 09-17 23:03:38.954: E/WindowManager(1994): at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141) 09-17 23:03:38.954: E/WindowManager(1994): at android.os.MessageQueue.nativePollOnce(Native Method) 09-17 23:03:38.954: E/WindowManager(1994): at android.os.MessageQueue.next(MessageQueue.java:138) 09-17 23:03:38.954: E/WindowManager(1994): at android.os.Looper.loop(Looper.java:123) 09-17 23:03:38.954: E/WindowManager(1994): at android.app.ActivityThread.main(ActivityThread.java:5017) 09-17 23:03:38.954: E/WindowManager(1994): at java.lang.reflect.Method.invokeNative(Native Method) 09-17 23:03:38.954: E/WindowManager(1994): at java.lang.reflect.Method.invoke(Method.java:515) 09-17 23:03:38.954: E/WindowManager(1994): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 09-17 23:03:38.954: E/WindowManager(1994): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 09-17 23:03:38.954: E/WindowManager(1994): at dalvik.system.NativeStart.main(Native Method)
首先说明:这个错误不属于内存溢出,而是android中的窗体溢出。
1.Activity 的生命周期与 Dialog 的不一样 AlertDialog.Builder builder=new AlertDialog.Builder(context);
2.这个context 是Activity的上下文
3.Dialog 要在Activity 销毁前 dismiss()掉,不然就窗体溢出
所以在解决此问题时,要判断窗体是否关闭,再干掉Activity
/** * 捕获返回按钮事件 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { showExitDialog(); return false; } else { return super.onKeyDown(keyCode, event); } } //退出提示 protected void showExitDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("提示"); builder.setMessage("您确定要退出么?"); builder.setNegativeButton("取消", null); builder.setPositiveButton("退出", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { MainActivity.this.finish(); dialog.cancel();//取消dialog,或dismiss掉 } }); if (!isFinishing()) { builder.create().show(); } }原因:
在android中常常会遇到与context有关的内容,浅论一下context : 在语句 AlertDialog.Builder builder = new AlertDialog.Builder(this); 中,要求传递的参数就是一个context,在这里传入的是this,那么这个this究竟指的是什么东东呢? 这里的this指的是Activity.this,是当前这个Activity 的上下文(Context)。
网上有很多朋友在这里传入this.getApplicationContext(),这是不对的。为什么? AlertDialog对象是依赖于一个View的,而View是和一个Activity对应的。 于是,这里涉及到一个生命周期的问题,this.getApplicationContext()取的是整个应用程序的Context,Activity.this取的是这个Activity的Context,这两者的生命周期是不同 的,前者的生命周期是整个应用,后者的生命周期只是它所在的Activity。而AlertDialog应该是属于一个Activity的,在Activity销毁的时候它也就销毁了,不会再存在;但是,如果传入this.getApplicationContext(),就表示它的生命周期是整个应用程序,这显然超过了它 的生命周期了。
所以,在这里只能使用Activity的this。 差别就是不同的生命周期。