android window 界面,Android之Window与WIndowManager

基本概念

Window、PhoneWindow

顶层窗口样式和行为的抽象类, 概括了Android窗口的基本属性和基本功能。该类实例的getDecorView()方法返回的DecorView被用来作为顶层视图添加到WM中。

创建时机: ActivityThread.handleLaunchActivity ---> ActivityThread.performLaunchActivity --->Activity.attach

WindowManager、WindowManagerImpl、WindowManagerGlobal

WindowManager与一个特定的Display相关联

WindowManagerService

对系统中的所有窗口进行管理。WindowManager是运行在Application process中的, WindowManagerService是在system_server进程中运行, 两者的通信是通过中间的会话层IWindowSession来进行的。

添加一个根View到WindowManager中

{

final WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);

WindowManager.LayoutParams lp = new WindowManager.LayoutParams(

wm.getDefaultDisplay().getWidth(),wm.getDefaultDisplay().getHeight());

lp.type = WindowManager.LayoutParams.TYPE_APPLICATION;

lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

lp.format = PixelFormat.TRANSLUCENT;

wm.addView(maskView, lp);

}

相关类简化结构

public class PhoneWindow extends Window{

private DecorView mDecor;

}

public interface ViewManager{

public void addView(View view, ViewGroup.LayoutParams params);

public void updateViewLayout(View view, ViewGroup.LayoutParams params);

public void removeView(View view);

}

public interface WindowManager extends ViewManager {

public static class LayoutParams extends ViewGroup.LayoutParams{

//X position for this window

public int x;

public int y;

public int type;

public int flags;

}

}

public final class WindowManagerImpl implements WindowManager {

private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();

private final Display mDisplay;

public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {

mGlobal.addView(view, params, mDisplay, mParentWindow);

}

}

public final class WindowManagerGlobal {

//表示View树的根节点

private final ArrayList mViews = new ArrayList();

//表示ViewRootImpl,一个根view对应一个ViewRootImpl

private final ArrayList mRoots = new ArrayList();

//表示根view的WindowManager.LayoutParams

private final ArrayList mParams = new ArrayList();

public void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow) {

final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;

...

ViewRootImpl root = new ViewRootImpl(view.getContext(), display);

view.setLayoutParams(wparams);

mViews.add(view);

mRoots.add(root);

mParams.add(wparams);

...

//通过ViewRootImpl来更新界面并完成Window的添加过程

root.setView(view, wparams, panelParentView);

}

}

public final class ViewRootImpl implements ViewParent{

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {

//1、完成异步刷新请求,重绘界面

requestLayout();

...

//2、通过WindowSession最终完成window的添加过程, WindowSession内部通过WindowManagerService来实现Window的添加

int res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,

getHostVisibility(), mDisplay.getDisplayId(),

mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,

mAttachInfo.mOutsets, mInputChannel);

}

}

Window的创建过程

Activity对应的PhoneWindow创建过程及添加时机

首先看下ActivityThead中的两个重要的方法:

performLaunchActivity( );

handleResumeActivity( );

创建时机:

在performLaunchActivity中,会调用activity.attach方法建立一个window。

Activity的View附属到Window上:setContentView()

添加时机:

在handleResumeActivity方法中启动activity的时候,首先会调用Activity的onResume方法,>接着调用Activity的makeVisible方法,在该方法中将主窗口加入到WindowManager中

代码如下:

void makeVisible() {

if (!mWindowAdded) {

ViewManager wm = getWindowManager();

wm.addView(mDecor, getWindow().getAttributes());//实际上是把主窗口的顶级view加入到WindowMangaer

mWindowAdded = true;

}

mDecor.setVisibility(View.VISIBLE);

}

Dialog的Window创建过程

创建窗口:构造函数中

初始化DecorView并将Dialog的View添加到DecorView中:setContentView()

将DecorView添加到Window中并显示:show()

public class Dialog implements DialogInterface, ... {

Dialog(Context context,int themeResId, boolean createContextThemeWrapper) {

if (createContextThemeWrapper) {

mContext = new ContextThemeWrapper(context, themeResId);

} else {

mContext = context;

}

mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

final Window w = new PhoneWindow(mContext);

mWindow = w;

w.setCallback(this);

w.setOnWindowDismissedCallback(this);

w.setWindowManager(mWindowManager, null, null);

w.setGravity(Gravity.CENTER);

mListenersHandler = new ListenersHandler(this);

}

public void setContentView(@LayoutRes int layoutResID) {

mWindow.setContentView(layoutResID);

}

public void show() {

mDecor = mWindow.getDecorView();

mWindowManager.addView(mDecor, l);

}

}

Window添加过程

实际上是根视图的添加过程,在WindowManager层已经没有Window的概念,Window的概念存在于UI层,是对于Activity、Dialog、Toast等而言的。

WindowManager.addView():调用2

WindowManagerGlobal.addView():

创建ViewRootImpl

调用3

ViewRootImpl.setView():

requestLayout()

mWindowSession.addToDisplay

总结

通过WindowManager.addView(View view, ViewGroup.LayoutParams params)可以看到:Window是一个抽象的概念,它以View的形式存在(不同于PhoneWindow,该Window是顶层View样式和行为的抽象类),但同时Activity、Dialog、Toast等又必须通过Window与View建立关联。根View一一对应ViewRootImpl,WindowManager内部通过ViewRootImpl进行Window(即根View)的添加、删除、更新,而ViewRootImpl内部通过WindowSession和WindowManagerService通信,最终WindowManagerService完成根View的添加、删除、更新。

Android中的Activity、Dialog、Toast、PopupWindow、菜单、状态栏都是通过Window来实现对应的View的,视图都对应一个Window。

从WmS的角度看,一个窗口并不是Window类,而是一个View类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值