Android 之 Window、WindowManager 与窗口管理

来源:互联网 发布:ios 大型游戏源码 编辑:程序博客网 时间:2024/05/16 08:38
其实在android中真正展示给用户的是window和view,activity在android中所其的作用主要是处理一些逻辑问题,比如生命周期的管理、建立窗口等。在android中,窗口的管理还是比较重要的一块,因为他直接负责把内容展示给用户,并和用户进行交互。响应用户的输入等。

在讲窗口管理时,有必要先说下ViewManager这个接口,这个接口主要有以下的实现子接口和实现类,分别是:WindowManagerViewGroup里面还有三个重要的方法:

  * addView(); 

 * updateViewLayout();

 * removeView();

WindowManager中,addView方法表示的是将主窗口中的顶级view(也就是DecorView)添加到WindowManager中,并建立会话。接下来会详细介绍。我们先来看看Window

Window:

Windowandroid中的窗口,表示顶级窗口的意思,也就是主窗口,它有两个实现类,PhoneWindowMidWindow,我们一般的activity对应的主要是PhoneWindow,在activity中经常使用的setContentView等方法也是在这个里面实现的。

  @Override

  public void setContentView(View view,ViewGroup.LayoutParams params) {

  if (mContentParent == null) {

  installDecor();

  } else {

  mContentParent.removeAllViews();

  }

  mContentParent.addView(view, params);

  final Callback cb = getCallback();

  if (cb != null) {

 cb.onContentChanged(); //窗口类容发生变化时更新

  }

  }

 每个主窗口中都有一个View,称之为DecorView,是主窗口中的顶级view(实际上就是ViewGroup),在View中有两个成员变量叫做mParent、mChildren,它是用来管理view的上下级关系的。而ViewGroup是对一组View的管理。因此,在ViewGroup中建立了所有view的关系网。而最终ViewGroup附属在主窗口上。这样就很容易在窗口中通过findViewById找到具体的View了。view中的事件处理也是根据这个路径来处理的。

我们再来看看ActivityThead中的两个重要的方法(至于ActivityThead将在一篇中详细介绍)

           performLaunchActivity( );

       handleResumeActivity( );

performLaunchActivity中,会调用activity.attach方法建立一个window,在handleResumeActivity方法中启动activity的时候,会将主窗口加入到WindowManager

  View decor =r.window.getDecorView(); //获得窗口的顶级View

  decor.setVisibility(View.INVISIBLE);

  ViewManager wm= a.getWindowManager(); //WindowManager继承自ViewManager

  WindowManager.LayoutParams l =r.window.getAttributes();

  a.mDecor = decor;

  l.type =WindowManager.LayoutParams.TYPE_BASE_APPLICATION;

 l.softInputMode |= forwardBit;

 if (a.mVisibleFromClient) {

  a.mWindowAdded = true;

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

 }

我们再来看看WindowManager

WindowManager:

WindowManager主要用来管理窗口的一些状态、属性、view增加、删除、更新、窗口顺序、消息收集和处理等。

通过Context.getSystemService(Context.WINDOW_SERVICE)的方式可以获得WindowManager的实例.

WindowManager继承自ViewManager,里面涉及到窗口管理的三个重要方法,分别是:

 * addView(); 

 * updateViewLayout();

 * removeView(); 

WindowManager中还有一个重要的静态类LayoutParams.通过它可以设置和获得当前窗口的一些属性。

我们先来看看addView()方法,在addView中,会利用LayoutParams获得windowView属性,并为每个window创建ViewRootViewRootViewWindowManager之间的桥梁,真正把View传递给WindowManager的是通过ViewRootsetView()方法,ViewRoot实现了ViewWindowManager之间的消息传递。在将主窗口添加到WindowManger时,它首先会建立一个代理对象:

  wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE)

并且打开会话(IWindowSession),之后Window将通过该会话与WindowManager建立联系,

来看下setView方法:

 try {

 res =sWindowSession.add(mWindow, mWindowAttributes,

  getHostVisibility(), mAttachInfo.mContentInsets);

 } catch (RemoteException e) {

  mAdded = false;

 mView = null;

  mAttachInfo.mRootView =null;

  unscheduleTraversals();

  throw newRuntimeException("Adding window failed", e);

  } finally {

  if (restore) {

  attrs.restore();

 }

  }

在这段代码中,ViewRoot通过IWindowSession把窗口添加到WindowManager中。ViewRoot继承了Handler,实际上它的本质就是一个Handler,窗口中View的事件处理、消息发送、回调等将通过ViewRoot来处理。

这样就完成了把窗口添加到WindowManager中,并交由WindowManager来管理窗口的view、事件、消息收集处理等。


接下来我们看其它三者之间的关系,我想大师固然看了前面的View的介绍和SDK中关系UI的根蒂根基介绍之后 还是对Android图形窗口十分困惑,看API也是,有WindowMangaer接口和Window类,然则在申明文档中,并未提到如何用这些。但实 际上这里面要去看到Android核心,Android核心底层GDI是SKIA,同chrome是一样的GDI,然则GUI是不一样的。这里面 Android实现的是C/S模式。如下图所示



从上图,我们可以理出大致的显示过程如下:
【1】ActivityManagerService创建Activity线程,激活一个activity
【2】体系调用Instrumentation.newActivity创建一个activity
【3】Activity创建后,attach到一个新创建的phonewindow中。如许Activity获取一个独一的WindowManager办事的实例
【4】Activity创建过程中应用setcontentView设置用用户UI,这些VIEW被参加到PhoneWindow的ContentParent中。
【5】Activity线程持续履行,当履行到Activity.makeVisible是将根view DecoView参加到WindowManger中,WindowManger实全会为每个DecoView创建对应的ViewRoot
【6】每个ViewRoot拥有一个Surface,每个Surface将会调用底层库创建图形绘制的内存空间。这个底层库就是SurfaceFlinger。SurfaceFlinger同时也负责将个View绘制的图形合到一块(遵守Z轴)显示到用户屏幕。
【7】若是用户直接在Canvas上绘制,实际上它直接操纵Surface。但对每个View的变革,它是要通知到ViewRoot,然后 ViewRoot获取Canvas。若是绘制完成,surfaceFlinger获得通知,归并Surface成一个Surface到设备屏幕。
从上方的图形输出过程解析,我们可以知道真正显示图形的实际上跟Activity没有关系,完全由WindowManager来决意。 WindowManager是一个体系办事,是以可以直接调用这个办事来创建界面,并且更绝的是Dialog、Menu也是有WindowManager 来经管的。别的一个我们也可以看到,最底层都是Surface来,是以,常见开辟游戏的人都推荐你应用SurfaceView来创建界面。




原创粉丝点击