当前位置: 首页>后端>正文

Java-WIndow和Activity和View

ActivityThread handleLaunchActivity() performLaunchActivity()--->activity.attach()

1: 创建PhoneWindow 将xml加载到PhoneWindow的DecorView上
attach(){
//创建 PhoneWindow
mWindow = new PhoneWindow(this, window, activityConfigCallback);

}

Activity -->setContentView(){
(PhoneWindow)getWindow().setContentView(layoutResID);
}

创建PhoneWindow 创建DecorView 将xml加载到DecorView中
PhoneWindow-->{

setContentView(){
//创建 DecorView
installDecor(){
//创建 DecorView
mDecor = generateDecor(-1);
//获取父类根布局
mContentParent = generateLayout(mDecor){
//加载 res传递过来的xml
mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
};
};
}
}

2:处理展示---> window.addView

ActivityThread--->handleResumeActivity(){
//执行Activity onResume
重点:
执行Activity onResume的时候 View还没加载到 Window上所以此时还获取不了控件宽高
if (!performResumeActivity(r, finalStateRequest, reason)){};

r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
//WindowManager WindowManagerImpl是WindowManager的实现类实质是到WindowManagerImpl
WindowManagerImpl
此对象实现了{@link ViewManager}接口,
允许您将任何View子类添加为屏幕上的顶级窗口。
定义了其他窗口管理器特定的布局参数,用于控制窗口的显示方式。
它还实现了{@link WindowManager}接口,允许您控制连接到设备的显示。
ViewManager wm = a.getWindowManager();

WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;

//将decorview 加载的View 添加到屏幕上
(WindowManagerImpl)wm.addView(decor, l);

]
WindowManagerImpl
此对象实现了{@link ViewManager}接口,
允许您将任何View子类添加为屏幕上的顶级窗口。
定义了其他窗口管理器特定的布局参数,用于控制窗口的显示方式。
它还实现了{@link WindowManager}接口,允许您控制连接到设备的显示。
WindowManagerImpl -->{
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {

    //view 是decorview   以及布局对象 mContext.getDisplay()是获取了一个屏幕对象 
    mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}

}

为与任何特定上下文无关的操作提供与系统窗口管理器的低级通信
WindowManagerGlobal-->{
addView(){
root = new ViewRootImpl(view.getContext(), display);
root.setView(view, wparams, panelParentView);
}
}

视图层次结构的顶部,实现视图和WindowManager之间所需的协议
ViewRootImpl{
//保证了绘制同步
synchronized (this) {
requestLayout();
requestLayout 是刷新布局的操作,
调用此方法后 ViewRootImpl 所关联的 View 也执行 measure -> layout -> draw 操作,
确保在 View 被添加到 Window 上显示到屏幕之前,已经完成测量和绘制操作。

  // 将 window的内容显示到屏幕上
  res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                        getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
                        mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                        mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
                        
                        
                        
}

}

mWindowSession{
mWindowSession = WindowManagerGlobal.getWindowSession();

   public static IWindowSession getWindowSession() {
    synchronized (WindowManagerGlobal.class) {
        if (sWindowSession == null) {
            try {
                InputMethodManager imm = InputMethodManager.getInstance();
                // windowManager  就是一个WindowManagerService 
                IWindowManager windowManager = getWindowManagerService();
                sWindowSession = windowManager.openSession(
                        new IWindowSessionCallback.Stub() {
                            @Override
                            public void onAnimatorScaleChanged(float scale) {
                                ValueAnimator.setDurationScale(scale);
                            }
                        },
                        imm.getClient(), imm.getInputContext());
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        return sWindowSession;
    }
}

}

WindowManagerService --->{
openSession(){
if (client == null) throw new IllegalArgumentException("null client");
if (inputContext == null) throw new IllegalArgumentException("null inputContext");
this 代表 WindowManagerService
Session session = new Session(this, callback, client, inputContext);
return session;
}
}

mWindowSession.addToDisplay(){

@Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
        int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets,
        Rect outStableInsets, Rect outOutsets,
        DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
    return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,
            outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel);
}

}

又回到了WindowManagerService addWindow{

final WindowState win = new WindowState(this, session, client, token, parentWindow,
                appOp[0], seq, attrs, viewVisibility, session.mUid,
                session.mCanAddInternalSystemWindow);
                
                
                 win.attach();

}

为什么win.attach()是创建与SurfaceFlinger通信的?简单了解下。
跟踪下去是创建了SurfaceSession对象,这个创建进入native,最终创建了一个与SurfaceFlinger通信的 SurfaceComposerClient。 因此,可以与SurfaceFlinger进行通信。
ViewRootImpl创建时 就创建的mSurface,mSurface是ViewRootImpl的成员变量,此时创建的Surface什么都没有,最后通过relayoutWindow()进入WMS 一步步向SurfaceFlinger发出请求。
这时几处相关代码。
WindowState{
void attach() {
if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
mSession.windowAddedLocked(mAttrs.packageName);
}

}

Session{

void windowAddedLocked(String packageName) {
    mPackageName = packageName;
    mRelayoutTag = "relayoutWindow: " + mPackageName;
    if (mSurfaceSession == null) {
        if (WindowManagerService.localLOGV) Slog.v(
            TAG_WM, "First window added to " + this + ", creating SurfaceSession");
        mSurfaceSession = new SurfaceSession();
        if (SHOW_TRANSACTIONS) Slog.i(
                TAG_WM, "  NEW SURFACE SESSION " + mSurfaceSession);
        mService.mSessions.add(this);
        if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
            mService.dispatchNewAnimatorScaleLocked(this);
        }
    }
    mNumWindow++;
}

}

窗口管理核心类:DisplayContent,WindowToken和WindowState

DisplayContent 理解为显示器 管理一个显示器上的各个窗口

WindowState 窗口状态可以理解为一个窗口(各种状态)
WindowToken 可以理解未WindowState 的集合
WindowManager 窗口管理
WindowMaangerService 窗口管理

WindowManagerService 负责窗口(window)管理,窗口动画,输入法,Surface 管理

-窗口管理: 负责窗口的启动,添加和删除,另外窗口的大小也时有 WMS 管理的,
管理窗口的核心成员有DisplayContent,WindowToken 和 WindowState
-窗口动画:窗口间进行切换时,使用窗口动画可以更好看一些,窗口动画由
WMS 动画子系统来负责,动画的管理系统为 WindowAnimator
-输入系统的中转站:通过对窗口触摸而产生的触摸事件,InputManagerServer(IMS) 会对触摸事件进行处理,他会寻找一个最合适的窗口来处理触摸反馈信息,
WMS 是窗口的管理者,因此理所当然的就成为了输入系统的中转站
-Surface管理:
窗口并不具备绘制的功能,因此每个窗口都需要有一个块 Surface 来供自己绘制,为每个窗口分配 Surface 是由 WMS 来完成的。


https://www.xamrdz.com/backend/3y81926104.html

相关文章: