When does Android think the window is leaking?
I checked the Android source code and found the following methods. (core / Java / Android / view / windowmanagerglobal. Java)
Seems to be who= When null, the window / view is leaked. Who can explain what happened behind this?
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);
}
}
}
}
resolvent:
I checked the source... I'm not sure about it, but I understand what she means
The WHO parameter is only the activity name
Check the method called by closeall (), and you can see who is just the name of the broken activity class, and a window is left behind:
WindowManagerGlobal.getInstance().closeAll(wtoken,
r.activity.getClass().getName(), "Activity");
If a leak occurs, call closeall()
When windows has leaked, it seems that windowmanagerglobal. Closeall() will be called. Therefore, who= Null just checks to make sure the string is not null
If it is not null, create windowleak and print the log. Windowleak is a class that extends androidruntimeexception
final class WindowLeaked extends AndroidRuntimeException {
public WindowLeaked(String msg) {
super(msg);
}
}
The most important fact is that if you call windowmanagerglobal. Closeall(), it means that windows has leaked
Closeall() calls the method
In view.java, we can see that windowmanagerglobal. Closeall() is called when the vulnerability is detected:
ActivityThread.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");
}
In the above code, we can see that windowmanagerglobal. Closeall() will be triggered when an inconsistency is found:
> wtoken!= Null wtoken shows that the view has attachinfo.mwindowtoken information. In other words, it still remains in a window. > r.mpendingremovewindow = = null, there is no view to be deleted
Therefore, this is inconsistent. A view is attached (with attatchinfo), but I have deleted all pending windows (mpendingremovewindow is null)... Therefore, the view has been leaked
I hope I can help you say hello
reference resources:
WindowManagerGlobal
ActivityThread
View