您的位置:首页 > 健康 > 养生 > 页面设计总结_网络推广公司代理_seo云优化公司_十大最靠谱教育培训机构

页面设计总结_网络推广公司代理_seo云优化公司_十大最靠谱教育培训机构

2025/3/4 16:54:51 来源:https://blog.csdn.net/xuyongqz/article/details/145980239  浏览:    关键词:页面设计总结_网络推广公司代理_seo云优化公司_十大最靠谱教育培训机构
页面设计总结_网络推广公司代理_seo云优化公司_十大最靠谱教育培训机构

1.问题描述
在项目开发过程中,遇到input的问题。用户点击status bar的Wifi图标之后,会弹出wifi列表的window,而点击这个window之外的区域,wifi列表的窗口不会消失的问题。
在这里插入图片描述
2. 问题分析定位

分析触摸问题,必不可少的会用到下面的两个dump命令,用来查询当前window的信息,以及window对应的inputManager的信息。

adb shell dumpsys window w > ws.log
adb shell dumpsys input > input.log

  2: name='a0f96b1 com.android.carsettings', id=265, displayId=0, inputConfig=PREVENT_SPLITTING | TRUSTED_OVERLAY | WATCH_OUTSIDE_TOUCH, alpha=1.00, frame=[1677,127][2397,847], globalScale=1.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=[-2560,-1440][5120,2880], ownerPid=11831, ownerUid=1000, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTEDtransform (ROT_0) (TRANSLATE)1.0000  0.0000  -1677.00000.0000  1.0000  -127.00000.0000  0.0000  1.0000

从input info可以看出来Wifi列表的弹框对应的
window:‘a0f96b1 com.android.carsettings’
frame,也就是window的位置和大小:frame=[1677,127][2397,847]
touchableRegion,也就是触摸区域:touchableRegion=[-2560,-1440][5120,2880]

代码跟踪:

   @VisibleForTestingvoid populateInputWindowHandle(final InputWindowHandleWrapper inputWindowHandle,final WindowState w) {// Add a window to our list of input windows.inputWindowHandle.setInputApplicationHandle(w.mActivityRecord != null? w.mActivityRecord.getInputApplicationHandle(false /* update */) : null);inputWindowHandle.setToken(w.mInputChannelToken);inputWindowHandle.setDispatchingTimeoutMillis(w.getInputDispatchingTimeoutMillis());inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode());inputWindowHandle.setPaused(w.mActivityRecord != null && w.mActivityRecord.paused);inputWindowHandle.setWindowToken(w.mClient);inputWindowHandle.setName(w.getName());// Update layout params flags to force the window to be not touch modal. We do this to// restrict the window's touchable region to the task even if it requests touches outside// its window bounds. An example is a dialog in primary split should get touches outside its// window within the primary task but should not get any touches going to the secondary// task.int flags = w.mAttrs.flags;if (w.mAttrs.isModal()) {flags = flags | FLAG_NOT_TOUCH_MODAL;}inputWindowHandle.setLayoutParamsFlags(flags);inputWindowHandle.setInputConfigMasked(InputConfigAdapter.getInputConfigFromWindowParams(w.mAttrs.type, flags, w.mAttrs.inputFeatures),InputConfigAdapter.getMask());final boolean focusable = w.canReceiveKeys()&& (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());inputWindowHandle.setFocusable(focusable);final boolean hasWallpaper = mDisplayContent.mWallpaperController.isWallpaperTarget(w)&& !mService.mPolicy.isKeyguardShowing()&& !mDisableWallpaperTouchEvents;inputWindowHandle.setHasWallpaper(hasWallpaper);// Surface insets are hardcoded to be the same in all directions// and we could probably deprecate the "left/right/top/bottom" concept.// we avoid reintroducing this concept by just choosing one of them here.inputWindowHandle.setSurfaceInset(w.mAttrs.surfaceInsets.left);// If we are scaling the window, input coordinates need to be inversely scaled to map from// what is on screen to what is actually being touched in the UI.inputWindowHandle.setScaleFactor(w.mGlobalScale != 1f ? (1f / w.mGlobalScale) : 1f);boolean useSurfaceBoundsAsTouchRegion = false;SurfaceControl touchableRegionCrop = null;final Task task = w.getTask();if (task != null) {if (task.isOrganized() && task.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {// If the window is in a TaskManaged by a TaskOrganizer then most cropping will// be applied using the SurfaceControl hierarchy from the Organizer. This means// we need to make sure that these changes in crop are reflected in the input// windows, and so ensure this flag is set so that the input crop always reflects// the surface hierarchy.useSurfaceBoundsAsTouchRegion = true;if (w.mAttrs.isModal()) {TaskFragment parent = w.getTaskFragment();touchableRegionCrop = parent != null ? parent.getSurfaceControl() : null;}} else if (task.cropWindowsToRootTaskBounds() && !w.inFreeformWindowingMode()) {touchableRegionCrop = task.getRootTask().getSurfaceControl();}}inputWindowHandle.setReplaceTouchableRegionWithCrop(useSurfaceBoundsAsTouchRegion);inputWindowHandle.setTouchableRegionCrop(touchableRegionCrop);if (!useSurfaceBoundsAsTouchRegion) {Slog.w("InputWindow", "setTouchableRegion,  mTmpRegion = " + mTmpRegion  + ", w = " + w);w.getSurfaceTouchableRegion(mTmpRegion, w.mAttrs);inputWindowHandle.setTouchableRegion(mTmpRegion);}}

在这里插入图片描述

接下来看看WindowState计算touchableRegion的过程:

   void getSurfaceTouchableRegion(Region region, WindowManager.LayoutParams attrs) {final boolean modal = attrs.isModal();Slog.w("InputWindow", "getSurfaceTouchableRegion,  region = " + region  + ", attrs= " + attrs + ", this = " + this+ ", modal = " + modal + ", mTouchableInsets = " + mTouchableInsets + ", mFrame = " + mWindowFrames.mFrame+ ", mWindowFrames = " + mWindowFrames);if (modal) {if (mActivityRecord != null) {// Limit the outer touch to the activity root task region.updateRegionForModalActivityWindow(region);Slog.w("InputWindow", "getSurfaceTouchableRegion-1,  region = " + region  + ", attrs= " + attrs + ", this = " + this);} else {// Give it a large touchable region at first because it was touch modal. The window// might be moved on the display, so the touchable region should be large enough to// ensure it covers the whole display, no matter where it is moved.getDisplayContent().getBounds(mTmpRect);final int dw = mTmpRect.width();final int dh = mTmpRect.height();region.set(-dw, -dh, dw + dw, dh + dh);Slog.w("InputWindow", "getSurfaceTouchableRegion-2,  region = " + region  + ", attrs= " + attrs + ", this = " + this);}subtractTouchExcludeRegionIfNeeded(region);Slog.w("InputWindow", "getSurfaceTouchableRegion-3,  region = " + region  + ", attrs= " + attrs + ", this = " + this);} else {// Not modalgetTouchableRegion(region);Slog.w("InputWindow", "getSurfaceTouchableRegion-4,  region = " + region  + ", attrs= " + attrs + ", this = " + this);}// Translate to surface based coordinates.final Rect frame = mWindowFrames.mFrame;if (frame.left != 0 || frame.top != 0) {region.translate(-frame.left, -frame.top);Slog.w("InputWindow", "getSurfaceTouchableRegion-5,  region = " + region  + ", attrs= " + attrs + ", this = " + this);}if (modal && mTouchableInsets == TOUCHABLE_INSETS_REGION) {// The client gave us a touchable region and so first// we calculate the untouchable region, then punch that out of our// expanded modal region.mTmpRegion.set(0, 0, frame.right, frame.bottom);mTmpRegion.op(mGivenTouchableRegion, Region.Op.DIFFERENCE);region.op(mTmpRegion, Region.Op.DIFFERENCE);Slog.w("InputWindow", "getSurfaceTouchableRegion-6,  region = " + region  + ", attrs= " + attrs + ", this = " + this);}// TODO(b/139804591): sizecompat layout needs to be reworked. Currently mFrame is post-// scaling but the existing logic doesn't expect that. The result is that the already-// scaled region ends up getting sent to surfaceflinger which then applies the scale// (again). Until this is resolved, apply an inverse-scale here.if (mInvGlobalScale != 1.f) {region.scale(mInvGlobalScale);}Slog.w("InputWindow", "getSurfaceTouchableRegion,  region = " + region  + ", attrs= " + attrs + ", this = " + this+ ", mInvGlobalScale = " + mInvGlobalScale);}

log如下:

01-01 16:00:07.572  1704  1729 W InputWindow: setTouchableRegion,  mTmpRegion = SkRegion((0,0,2560,1440)), w = Window{7542c78 u0 com.android.carsettings}
01-01 16:00:07.572  1704  1729 W InputWindow: getSurfaceTouchableRegion,  region = SkRegion((0,0,2560,1440)), attrs= {(163,127)(720x720) gr=TOP END CENTER sim={adjust=resize} ty=NAVIGATION_BAR_PANEL fmt=RGBA_8888
01-01 16:00:07.572  1704  1729 W InputWindow:   fl=LAYOUT_IN_SCREEN LAYOUT_NO_LIMITS WATCH_OUTSIDE_TOUCH HARDWARE_ACCELERATED
01-01 16:00:07.572  1704  1729 W InputWindow:   pfl=USE_BLAST
01-01 16:00:07.572  1704  1729 W InputWindow:   bhv=DEFAULT
01-01 16:00:07.572  1704  1729 W InputWindow:   fitTypes=NAVIGATION_BARS CAPTION_BAR}, this = Window{7542c78 u0 com.android.carsettings}, modal = true, mTouchableInsets = 0, mFrame = Rect(1677, 127 - 2397, 847), mWindowFrames = com.android.server.wm.WindowFrames@e67a3a8
01-01 16:00:07.573  1704  1729 W InputWindow: getSurfaceTouchableRegion-2,  region = SkRegion((-2560,-1440,5120,2880)), attrs= {(163,127)(720x720) gr=TOP END CENTER sim={adjust=resize} ty=NAVIGATION_BAR_PANEL fmt=RGBA_8888
01-01 16:00:07.573  1704  1729 W InputWindow:   fl=LAYOUT_IN_SCREEN LAYOUT_NO_LIMITS WATCH_OUTSIDE_TOUCH HARDWARE_ACCELERATED
01-01 16:00:07.573  1704  1729 W InputWindow:   pfl=USE_BLAST
01-01 16:00:07.573  1704  1729 W InputWindow:   bhv=DEFAULT
01-01 16:00:07.573  1704  1729 W InputWindow:   fitTypes=NAVIGATION_BARS CAPTION_BAR}, this = Window{7542c78 u0 com.android.carsettings}
01-01 16:00:07.573  1704  1729 W InputWindow: getSurfaceTouchableRegion-3,  region = SkRegion((-2560,-1440,5120,2880)), attrs= {(163,127)(720x720) gr=TOP END CENTER sim={adjust=resize} ty=NAVIGATION_BAR_PANEL fmt=RGBA_8888
01-01 16:00:07.573  1704  1729 W InputWindow:   fl=LAYOUT_IN_SCREEN LAYOUT_NO_LIMITS WATCH_OUTSIDE_TOUCH HARDWARE_ACCELERATED
01-01 16:00:07.573  1704  1729 W InputWindow:   pfl=USE_BLAST
01-01 16:00:07.573  1704  1729 W InputWindow:   bhv=DEFAULT
01-01 16:00:07.573  1704  1729 W InputWindow:   fitTypes=NAVIGATION_BARS CAPTION_BAR}, this = Window{7542c78 u0 com.android.carsettings}
01-01 16:00:07.574  1704  1729 W InputWindow: getSurfaceTouchableRegion-5,  region = SkRegion((-4237,-1567,3443,2753)), attrs= {(163,127)(720x720) gr=TOP END CENTER sim={adjust=resize} ty=NAVIGATION_BAR_PANEL fmt=RGBA_8888
01-01 16:00:07.574  1704  1729 W InputWindow:   fl=LAYOUT_IN_SCREEN LAYOUT_NO_LIMITS WATCH_OUTSIDE_TOUCH HARDWARE_ACCELERATED
01-01 16:00:07.574  1704  1729 W InputWindow:   pfl=USE_BLAST
01-01 16:00:07.574  1704  1729 W InputWindow:   bhv=DEFAULT
01-01 16:00:07.574  1704  1729 W InputWindow:   fitTypes=NAVIGATION_BARS CAPTION_BAR}, this = Window{7542c78 u0 com.android.carsettings}
01-01 16:00:07.575  1704  1729 W InputWindow: getSurfaceTouchableRegion,  region = SkRegion((-4237,-1567,3443,2753)), attrs= {(163,127)(720x720) gr=TOP END CENTER sim={adjust=resize} ty=NAVIGATION_BAR_PANEL fmt=RGBA_8888
01-01 16:00:07.575  1704  1729 W InputWindow:   fl=LAYOUT_IN_SCREEN LAYOUT_NO_LIMITS WATCH_OUTSIDE_TOUCH HARDWARE_ACCELERATED
01-01 16:00:07.575  1704  1729 W InputWindow:   pfl=USE_BLAST
01-01 16:00:07.575  1704  1729 W InputWindow:   bhv=DEFAULT
01-01 16:00:07.575  1704  1729 W InputWindow:   fitTypes=NAVIGATION_BARS CAPTION_BAR}, this = Window{7542c78 u0 com.android.carsettings}, mInvGlobalScale = 1.0
01-01 16:00:07.575  1704  1729 W InputWindow: setTouchableRegion,  region = SkRegion((-4237,-1567,3443,2753)), mHandle = 7542c78 com.android.carsettings, frame=[0,0,0,0], touchableRegion=SkRegion((-4237,-1567,3443,2753)), scaleFactor=1.0, transform=null, windowToken=android.os.BinderProxy@30d22ea, isClone=false, callstack = 
01-01 16:00:07.575  1704  1729 W InputWindow: java.lang.Throwable: xxxx
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.InputWindowHandleWrapper.setTouchableRegion(InputWindowHandleWrapper.java:143)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.InputMonitor.populateInputWindowHandle(InputMonitor.java:316)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.accept(InputMonitor.java:657)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.accept(InputMonitor.java:529)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2728)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2718)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4957)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.WindowState.forAllWindows(WindowState.java:4801)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1699)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1699)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1699)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1699)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1716)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.updateInputWindows(InputMonitor.java:569)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.-$$Nest$mupdateInputWindows(Unknown Source:0)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.wm.InputMonitor$UpdateInputWindows.run(InputMonitor.java:137)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at android.os.Handler.handleCallback(Handler.java:942)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at android.os.Handler.dispatchMessage(Handler.java:99)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at android.os.Looper.loopOnce(Looper.java:201)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at android.os.Looper.loop(Looper.java:288)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at android.os.HandlerThread.run(HandlerThread.java:67)
01-01 16:00:07.575  1704  1729 W InputWindow: 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
wifi列表弹框,没有FLAG_NOT_TOUCH_MODAL ,且没有FLAG_NOT_FOCUSABLE,这样的行为,就是让所有的input event全部给这个window,所以出现bug这个的,点击window之外的区域,不会退出的现象。

3.问题解决方案
wifi列表弹框,加上FLAG_NOT_FOCUSABLE,最终验证PASS。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com