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

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)

当前回答

我正在制作一个科学的应用程序,已经接近4.5万行,我使用异步任务,以便能够中断长任务,如果需要的话,用户点击一定的按钮。

因此,有一个响应式的用户界面,有时还有一个并行的长任务。

当长任务结束时,我需要运行一个管理用户界面的例程。

因此,在异步任务结束时,我执行以下涉及接口的操作,不能直接执行该操作,否则将给出错误。所以我用

this.runOnUiThread(Runnable { x(...)})   // Kotlin

很多时候,这个错误发生在函数x的某个点上。

如果函数x在线程外部被调用

              x(...)  // Kotlin

Android Studio将显示带有错误行的调用堆栈,并且可以在几分钟内轻松解决问题。

由于我的源代码是驯服的,并且不存在严重的结构问题(上面的许多答案都描述了这种错误),所以出现这种可怕的错误消息的原因更加严重,而不那么重要。

这只是链接到线程的执行中的任何愚蠢错误(例如,访问超出定义长度的向量),如下图所示:

           var i = 10                  // Kotlin
           ...
           var arr = Array(5){""}       
           var element = arr[i]       // 10 > 5, it's a index overflow

不幸的是,Android Studio并没有指出这个愚蠢的错误。

我甚至认为这是一个bug,因为Android Studio知道有一个错误,它位于哪里,但是,由于一些未知的原因,它丢失了,并给出了一个随机的消息,完全与问题无关,即,一个奇怪的消息,没有提示显示。

解决方案:有足够的耐心在调试器中一步一步地运行,直到到达错误线,这是Android Studio拒绝提供的。

这种情况在我身上发生过几次,我想这是Android项目中非常常见的错误。在我使用线程之前,我从来没有给过我这种错误。

没有人是绝对正确的,我们容易犯一些小错误。在这种情况下,你不能指望Android Studio的直接帮助来发现你的错误!

其他回答

我也曾面临过这个问题,但我意识到这并不是因为我的对话框,而是因为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();
 }

我正在制作一个科学的应用程序,已经接近4.5万行,我使用异步任务,以便能够中断长任务,如果需要的话,用户点击一定的按钮。

因此,有一个响应式的用户界面,有时还有一个并行的长任务。

当长任务结束时,我需要运行一个管理用户界面的例程。

因此,在异步任务结束时,我执行以下涉及接口的操作,不能直接执行该操作,否则将给出错误。所以我用

this.runOnUiThread(Runnable { x(...)})   // Kotlin

很多时候,这个错误发生在函数x的某个点上。

如果函数x在线程外部被调用

              x(...)  // Kotlin

Android Studio将显示带有错误行的调用堆栈,并且可以在几分钟内轻松解决问题。

由于我的源代码是驯服的,并且不存在严重的结构问题(上面的许多答案都描述了这种错误),所以出现这种可怕的错误消息的原因更加严重,而不那么重要。

这只是链接到线程的执行中的任何愚蠢错误(例如,访问超出定义长度的向量),如下图所示:

           var i = 10                  // Kotlin
           ...
           var arr = Array(5){""}       
           var element = arr[i]       // 10 > 5, it's a index overflow

不幸的是,Android Studio并没有指出这个愚蠢的错误。

我甚至认为这是一个bug,因为Android Studio知道有一个错误,它位于哪里,但是,由于一些未知的原因,它丢失了,并给出了一个随机的消息,完全与问题无关,即,一个奇怪的消息,没有提示显示。

解决方案:有足够的耐心在调试器中一步一步地运行,直到到达错误线,这是Android Studio拒绝提供的。

这种情况在我身上发生过几次,我想这是Android项目中非常常见的错误。在我使用线程之前,我从来没有给过我这种错误。

没有人是绝对正确的,我们容易犯一些小错误。在这种情况下,你不能指望Android Studio的直接帮助来发现你的错误!

只需确保您的活动不会由于代码中某处引发的异常而意外关闭。通常在异步任务中,当activity在doinBackground方法中面临强制关闭时,asynctask返回到onPostexecute方法。

如果您正在处理LiveData,当更新值而不是使用LiveData时。尝试做liveData.postValue(someValue)

这里有一个解决方案,当你想要解散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()
}