这个错误是什么,为什么会发生?

05-17 18:24:57.069: ERROR/WindowManager(18850): Activity com.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity ccom.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.ViewRoot.<init>(ViewRoot.java:231)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.Window$LocalWindowManager.addView(Window.java:424)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.Dialog.show(Dialog.java:239)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.mypkg.myP$PreparePairingLinkageData.onPreExecute(viewP.java:183)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.AsyncTask.execute(AsyncTask.java:391)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.mypkg.myP.onCreate(viewP.java:94)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.access$2200(ActivityThread.java:126)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.Looper.loop(Looper.java:123)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.main(ActivityThread.java:4595)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at java.lang.reflect.Method.invokeNative(Native Method)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at java.lang.reflect.Method.invoke(Method.java:521)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at dalvik.system.NativeStart.main(Native Method)

当前回答

你必须在AsyncTask的onPreExecute方法中创建Progressdialog对象,你应该在onPostExecute方法中解散它。

其他回答

在运行猴子测试时,我也遇到了windowleaks的问题。logcat在下面。

android.support.v7.app.AppCompatDelegateImplV7$ListMenuDecorView@4334fd40 that was originally added here
android.view.WindowLeaked: Activity com.myapp.MyActivity has leaked window android.support.v7.app.AppCompatDelegateImplV7$ListMenuDecorView@4334fd40 that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:409)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:312)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
            at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
            at android.view.Window$LocalWindowManager.addView(Window.java:554)
            at android.support.v7.app.AppCompatDelegateImplV7.openPanel(AppCompatDelegateImplV7.java:1150)
            at android.support.v7.app.AppCompatDelegateImplV7.onKeyUpPanel(AppCompatDelegateImplV7.java:1469)
            at android.support.v7.app.AppCompatDelegateImplV7.onKeyUp(AppCompatDelegateImplV7.java:919)
            at android.support.v7.app.AppCompatDelegateImplV7.dispatchKeyEvent(AppCompatDelegateImplV7.java:913)
            at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:241)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2009)
            at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3929)
            at android.view.ViewRootImpl.deliverKeyEvent(ViewRootImpl.java:3863)
            at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3420)
            at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4528)
            at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4506)
            at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4610)
            at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
            at android.os.MessageQueue.nativePollOnce(Native Method)
            at android.os.MessageQueue.next(MessageQueue.java:125)
            at android.os.Looper.loop(Looper.java:124)
            at android.app.ActivityThread.main(ActivityThread.java:4898)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
            at dalvik.system.NativeStart.main(Native Method)

我的活动是AppCompatActivity。我用下面的代码在活动中解决了它。

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    // added by sunhang : intercept menu key to resove a WindowLeaked error in monkey-test.
    if (event.getKeyCode() == KeyEvent.KEYCODE_MENU) {
        return true;
    }
    return super.dispatchKeyEvent(event);
}

确保打电话 this.dialog.show。(活动)

这里有一个解决方案,当你想要解散AlertDialog,但不想在活动中保留对它的引用。

解决方案要求您拥有androidx。项目中的生命周期依赖关系(我相信在评论的时候,这是一个常见的需求)

这让你可以将对话框的解散委托给外部对象(观察者),你不需要再关心它了,因为当活动终止时它会自动取消订阅。(这里是证明:https://github.com/googlecodelabs/android-lifecycles/issues/5)。

因此,观察者保持对对话的引用,而活动保持对观察者的引用。当“onPause”发生时-观察者解散对话框,当“onDestroy”发生时-活动删除观察者,所以没有泄漏发生(好吧,至少我不会在logcat中看到错误)

// observer
class DialogDismissLifecycleObserver( private var dialog: AlertDialog? ) : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        dialog?.dismiss()
        dialog = null
    }
}
// activity code
private fun showDialog() {
        if( isDestroyed || isFinishing ) return
        val dialog = AlertDialog
            .Builder(this, R.style.DialogTheme)
            // dialog setup skipped
            .create()
        lifecycle.addObserver( DialogDismissLifecycleObserver( dialog ) )
        dialog.show()
}

我也有同样的问题。错误不在对话框中,而是在编辑文本中。我试图改变一个异步任务内的编辑文本的值。我唯一能解决的问题就是创造一个新的可运行对象。

runOnUiThread(new Runnable(){
      @Override
      public void run() {
       ...        
      }
    });  

我也曾面临过这个问题,但我意识到这并不是因为我的对话框,而是因为ActionMode。所以如果你试图在ActionMode打开时完成活动,就会导致这个问题。在你的活动的onPause完成动作模式。

 private ActionMode actionMode;

 @Override
 public void onActionModeStarted(ActionMode mode) {
    super.onActionModeStarted(mode);
    actionMode = mode;
 }

 @Override
 protected void onPause() {
    super.onPause();
    if (actionMode != null) actionMode.finish();
 }