在处理问题的时候,经常会遇到ANR,停止运行等问题,经过分析和验证,和如下的一行关键log有关
WindowManager: Adding more than one toast window for UID at a time.
这一行log对应的代码如下:
// If adding a toast requires a token for this app we always schedule hiding // toast windows to make sure they don't stick around longer then necessary. // We hide instead of remove such windows as apps aren't prepared to handle // windows being removed under them. // // If the app is older it can add toasts without a token and hence overlay // other apps. To be maximally compatible with these apps we will hide the // window after the toast timeout only if the focused window is from another // UID, otherwise we allow unlimited duration. When a UID looses focus we // schedule hiding all of its toast windows. if (type == TYPE_TOAST) { if (!getDefaultDisplayContentLocked().canAddToastWindowForUid(callingUid)) { Slog.w(TAG_WM, "Adding more than one toast window for UID at a time."); return WindowManagerGlobal.ADD_DUPLICATE_ADD; } // Make sure this happens before we moved focus as one can make the // toast focusable to force it not being hidden after the timeout. // Focusable toasts are always timed out to prevent a focused app to // show a focusable toasts while it has focus which will be kept on // the screen after the activity goes away. if (addToastWindowRequiresToken || (attrs.flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0 || mCurrentFocus == null || mCurrentFocus.mOwnerUid != callingUid) { mH.sendMessageDelayed( mH.obtainMessage(H.WINDOW_HIDE_TIMEOUT, win), win.mAttrs.hideTimeoutMilliseconds); } }
此段代码在WindowManagerService.java中的addWindow函数,可以对比android源码,只有android7.1才会有这段代码,即只有android7.1对toast类型的窗口有限制。
那么这个限制导致到底是什么呢?
可以查看如下修改说明:
https://android.googlesource.com/platform/frameworks/base/+/dc24f93%5E%21/#F6
修改的目的:
Prevent apps to overlay other apps via toast windows
It was possible for apps to put toast type windows that overlay other apps which toast winodws aren’t removed after a timeout.