当前位置:网站首页>Window source code analysis (III): window update mechanism
Window source code analysis (III): window update mechanism
2022-07-28 09:37:00 【Yu Qirong】
notes : The source code analyzed in this article is based on API 25, Part of the content comes from 《Android Exploration of development Art 》.
Chapter one :《Window The source code parsing ( One ): And DecorView Those things 》
Second articles :《Window The source code parsing ( Two ):Window The mechanism of adding 》
Header
In the last one , It introduces Window Implementation of adding mechanism .
So today, let's explore Window Renewal mechanism . Actually Window Update internal processes and add Window There's no difference , So this article may be brief .
But it is still worth knowing , So old crash driving .
Window The update mechanism of
We update Window Code for :
WindowManager.updateViewLayout
WindowManagerImpl
updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params)
So our entrance is WindowManagerImpl Implementation class , Look at the code first :
@Override
public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.updateViewLayout(view, params);
} Sure enough , The interior is still handed over to WindowManagerGlobal To deal with the , And this code and addView Are very similar .
WindowManagerGlobal
updateViewLayout(View view, ViewGroup.LayoutParams params)
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
if (view == null) {
throw new IllegalArgumentException("view must not be null");
}
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
}
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
view.setLayoutParams(wparams);
synchronized (mLock) {
// To find the view The index of
int index = findViewLocked(view, true);
ViewRootImpl root = mRoots.get(index);
// Replace params
mParams.remove(index);
mParams.add(index, wparams);
root.setLayoutParams(wparams, false);
}
}This code is basically easy to understand . Because it's an update Window , So it must be replaced params 了 .
Then call ViewRootImpl.setLayoutParams To set up a new params .
ViewRootImpl
setLayoutParams(WindowManager.LayoutParams attrs, boolean newView)
void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
synchronized (this) {
...
applyKeepScreenOnFlag(mWindowAttributes);
// Incoming newView yes false , Do not execute these codes
if (newView) {
mSoftInputMode = attrs.softInputMode;
requestLayout();
}
// Don't lose the mode we last auto-computed.
if ((attrs.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
== WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {
mWindowAttributes.softInputMode = (mWindowAttributes.softInputMode
& ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
| (oldSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);
}
mWindowAttributesChanged = true;
// send view Go through three processes again
scheduleTraversals();
}
} stay setLayoutParams in , Called scheduleTraversals() Method .
Before that View Working principle , We've all seen it scheduleTraversals() In the end, it will call performTraversals() Let's start View The measurement of 、 Layout and drawing . So here , And it triggers View Readjust yourself .
performTraversals()
private void performTraversals() {
...
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
...
}performTraversals() The method is too long , Don't look at the rest , We only pay attention to this code .
next , Internally, it calls relayoutWindow(params, viewVisibility, insetsPending) Method . You can know what this method does by looking at its name .
relayoutWindow()
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
...
// I can see you , Here is another call session Come and go IPC technological process , Then get an update window Result relayoutResult
int relayoutResult = mWindowSession.relayout(
mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingConfiguration,
mSurface);
...
return relayoutResult;
} Here we are , We meet again familiar mWindowSession .
I also know that this is actually a walk IPC Call procedure for , It will definitely be used inside WindowManagerService To complete Window Update .
and relayoutResult This is the IPC The final result , That is to say Window The result of the update .
Although I understand the routine , But sometimes we still have to eat . Then go Session Class .
Session
relayout(IWindow window, int seq, WindowManager.LayoutParams attrs ... )
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Rect outBackdropFrame,
Configuration outConfig, Surface outSurface) {
if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
+ Binder.getCallingPid());
int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, flags,
outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
outStableInsets, outsets, outBackdropFrame, outConfig, outSurface);
if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
return res;
}As we expected , Internally, it calls mService , That is to say WindowManagerService .
WindowManagerService
relayoutWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs ... )
public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,
Configuration outConfig, Surface outSurface) {
int result = 0;
boolean configChanged;
boolean hasStatusBarPermission =
mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
== PackageManager.PERMISSION_GRANTED;
long origId = Binder.clearCallingIdentity();
synchronized(mWindowMap) {
// according to session and client obtain windowState object
WindowState win = windowForClientLocked(session, client, false);
if (win == null) {
return 0;
}
// Convert the attributes accordingly and save them to WindowState
...
// To update window
if (viewVisibility == View.VISIBLE &&
(win.mAppToken == null || !win.mAppToken.clientHidden)) {
result = relayoutVisibleWindow(outConfig, result, win, winAnimator, attrChanges,
oldVisibility);
try {
result = createSurfaceControl(outSurface, result, win, winAnimator);
} catch (Exception e) {
mInputMonitor.updateInputWindowsLw(true /*force*/);
Slog.w(TAG_WM, "Exception thrown when creating surface for client "
+ client + " (" + win.mAttrs.getTitle() + ")",
e);
Binder.restoreCallingIdentity(origId);
return 0;
}
}
...
boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
// Little hack here -- we -should- be able to rely on the
// function to return true if the IME has moved and needs
// its layer recomputed. However, if the IME was hidden
// and isn't actually moved in the list, its layer may be
// out of data so we make sure to recompute it.
// If the window sorting is changed , So for DisplayContent All windows of assign the final display order
mLayersController.assignLayersLocked(win.getWindowList());
}
...
// to update window Then set some variables
}WMS Of relayoutWindow In the method , Get what needs to be updated first WindowState object , Then execute the update . If Window If the display order of changes , The order needs to be reassigned . Finally, set some Window Some variables after the update .
Other code is too complicated , Poor learning , Not all can be analyzed .
Footer
All in all ,Window Updating is the same as adding , It's all through session To call IPC The process is completed . And the final implementation is in WindowManagerService in .
thus , There's another article. Window Deletion has not been analyzed . You don't have to guess , This process is certainly similar . But we still need to go deep into it .
It's over today ,bye !
References
边栏推荐
- [multithreading] non atomic agreement of long and double
- Which system table is the keyword of SQL Server in?
- LeetCode - 哈希表专题
- 股指期货开户的条件和流程
- LinkedList内部原理解析
- Informatics Olympiad all in one 1617: circle game | 1875: [13noip improvement group] circle game | Luogu p1965 [noip2013 improvement group] circle game
- 对话MySQL之父:代码一次性完成才是优秀程序员
- 【日志】日志干什么的?日志工厂是什么?log4j 的配置和使用? log4j.properties 文件配置、log4j jar包坐标
- Database core system
- [autosar-rte] - introduction of 2-component, component and VFB
猜你喜欢

技术分享| 快对讲综合调度系统

【C语言】详解顺序表(SeqList)

51 single chip microcomputer storage: EEPROM (I2C)

《PyTorch深度学习实践》第九课多分类问题(手写数字MNIST)

Activiti startup error: cannot create poolableconnectionfactory (could not create connection to database server

Express builds a simple local background (1)

QT基础练手小程序-简单计算器设计(附带源码,解析)

matlab基本操作

对话MySQL之父:代码一次性完成才是优秀程序员

Introduction to shardingsphere's concept of sub database and sub table (2)
随机推荐
How to use gbase C API in multithreaded environment?
Conditions and procedures of stock index futures account opening
负数的十六进制表示
【解决】ERROR in [eslint] ESLint is not a constructor
Introduction to shardingsphere (I)
IT行业数据与应用关系的变迁
C# 之 方法参数传递机制
C signed and unsigned byte variables
Activiti启报错: Cannot create PoolableConnectionFactory (Could not create connection to database server
[solution] error in [eslint] eslint is not a constructor
opencv安装配置测试
Magic brace- [group theory] [Burnside lemma] [matrix fast power]
Talk to the father of MySQL: code completion at one time is a good programmer
常用工具函数 持续更新
21天学习挑战赛-《Autosar从入门到精通-实战篇》
Regular expressions for positive and negative values
7 C control statements: branches and jumps
数据库核心体系
19c sysaux tablespace sqlobj$plan table is too large. How to clean it up
[C language] detailed explanation sequence table (seqlist)