我检查了android的源代码,找到了下面的方法。
core/java/android/view/WindowManagerGlobal.java
who != null窗口/视图被泄漏时。有人能解释这背后的原因吗?

public void closeAll(IBinder token, String who, String what) {
        synchronized (mLock) {
            int count = mViews.size();
            //Log.i("foo", "Closing all windows of " + token);
            for (int i = 0; i < count; i++) {
                //Log.i("foo", "@ " + i + " token " + mParams[i].token
                //        + " view " + mRoots[i].getView());
                if (token == null || mParams.get(i).token == token) {
                    ViewRootImpl root = mRoots.get(i);

                    //Log.i("foo", "Force closing " + root);
                    if (who != null) {
                        WindowLeaked leak = new WindowLeaked(
                                what + " " + who + " has leaked window "
                                + root.getView() + " that was originally added here");
                        leak.setStackTrace(root.getLocation().getStackTrace());
                        Log.e(TAG, "", leak);
                    }

                    removeViewLocked(i, false);
                }
            }
        }
    }

最佳答案

我查了来源…
我不太确定,但我理解她…
“who”参数仅为活动名称
检查closeAll()调用方法,可以看到who只是被破坏并留下一个窗口的活动类名:

WindowManagerGlobal.getInstance().closeAll(wtoken,
                        r.activity.getClass().getName(), "Activity");

如果发生泄漏,则调用closeAll()
当窗口已经泄漏时,似乎调用了WindowManagerGlobal.closeAll()。所以,who != null只是一个检查,以确保String不是NULL
如果不为空,则创建WindowLeaked并打印日志。WindowLeaked是扩展AndroidRuntimeException的类。
final class WindowLeaked extends AndroidRuntimeException {
    public WindowLeaked(String msg) {
        super(msg);
    }
}

最重要的是,如果调用WindowManagerGlobal.closeAll(),则表示窗口已经泄漏。
closeAll()调用方法
View.java中,我们可以看到当检测到浸出时调用WindowManagerGlobal.closeAll()
活动线程.java
private void handleDestroyActivity(IBinder token, boolean finishing,
                                    int configChanges, boolean getNonConfigInstance) {
    ...
    IBinder wtoken = v.getWindowToken();
    ...
    if (wtoken != null && r.mPendingRemoveWindow == null) {
        WindowManagerGlobal.getInstance().closeAll(wtoken,
                r.activity.getClass().getName(), "Activity");
    }

在上面的代码中,我们可以看到当发现不一致时会触发WindowManagerGlobal.closeAll()
wtoken != nullwtoken表示View具有mAttachInfo.mWindowToken信息。换言之,它仍然被某个窗户挡住。
r.mPendingRemoveWindow == null没有要删除的挂起视图。
所以,这是不一致的。已附加一个视图(还有一个mAttachInfo),但我已删除所有挂起的窗口(mPendingRemoveWindow为空)。所以,这种观点已经泄露了。
希望我能帮你
当做
裁判:
WindowManagerGlobal
ActivityThread
View

10-04 17:34