Android快速理解Activity、View及Window&WindowManager之间关系

《Android快速理解Activity、View及Window&WindowManager之间关系》

   贯穿整个深圳的深南大道,也是最繁忙的路,贯穿深圳的几个区,在这条道上有著名的景点和商业圈和IT公司,以上是TCL总部!

 

1.Android 3步搞定事件分发机制,再也不用担心onTouch和onTouchEvent&dispatchTouchEvent

https://blog.csdn.net/WHB20081815/article/details/62888575

2.Android 滑动冲突的完美解决方案 listview和scroView

https://blog.csdn.net/WHB20081815/article/details/88617041

3.Android 深入理解 View 的绘制流程和机制

https://blog.csdn.net/WHB20081815/article/details/62236641

4.Android 5.0 6.0 以及7.0新特性 MD风格 敏感权限 文件访问

https://blog.csdn.net/WHB20081815/article/details/70244065

5.Android 万能适配方案和UI屏幕适配 不同分辨率 最全面 最易懂的

https://blog.csdn.net/WHB20081815/article/details/76937801

6.Android 2分钟刷Android 8.0系统 和 8.0适配 完美方案

https://blog.csdn.net/WHB20081815/article/details/75669925

7.Android快速理解Activity、View及Window&WindowManager之间关系

https://blog.csdn.net/WHB20081815/article/details/62419059

 

 

基本概念描述:

1.Activity用户最直接接触到的,Activity维护应用程序的生命周期,它依赖于Window

2.Window表示一个窗口的概念,类似360悬浮窗的东西就需要Window来实现。依赖于WindowManager,同时绘制View(DecorView)

3.WindowManager用于添加,移除Window对象,如无法直接访问Window,对Window的访问必须通过WindowManager

4.View:视图,UI实现了KeyEvent.Callback和Drawable.Callback。

代码分析:

 

Activity源码

public void setContentView(@LayoutRes int layoutResID) {
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
}

 

public Window getWindow() {
    return mWindow;
}

 

final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
    attachBaseContext(context);

    mFragments.attachHost(null /*parent*/);

    mWindow = new PhoneWindow(this);
    mWindow.setCallback(this);

 

总结:

Activity内部组合了一个Window(这是一个抽象类,具体是PhoneWindow)对象。setContentView,实际上是调用Window对象的 setContentView,所以说界面绘制全部是由Window类的实现类(PhoneWindow类)来完成的。

 

为啥attch优先于onCreate调用,就是由于在attch方法中,会创建window,有了window才能调用setContentView

attach方法中会调用PolicyManager.makeNewWindow()  

 

Activity 里面对各个窗口的管理相当复杂(任务栈、状态等等)

 

《Android快速理解Activity、View及Window&WindowManager之间关系》

 

DecorView是一个应用窗口的根容器,它本质上是一个FrameLayout。DecorView有唯一一个子View,它是一个垂直LinearLayout,包含两个子元素,一个是TitleView(ActionBar的容器),另一个是ContentView(窗口内容的容器)

 

Decor view创建一个ViewRoot,ViewRoot负责协调decorview与windowmanager直接绘图、事件处理

 

1:这个PhoneWindow有一个“ViewRoot”,这个“ViewRoot”是一个View或者说ViewGroup,是最初始的根视图。
2:“ViewRoot”通过addView方法来一个个的添加View。比如TextView,Button等
3:这些View的事件监听,是由WindowManagerService来接受消息,并且回调Activity函数。比如onClickListener,onKeyDown等。

4.如何把我们已经创建好的窗口通知给WindowManagerService ,以便它能够把这个窗口显示在屏幕上。

《Android快速理解Activity、View及Window&WindowManager之间关系》

 

 

 

WindowManager源码:

public interface WindowManager extends ViewManager

 

public interface ViewManager
{
 
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}

 


 

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

我们先来看看addView()方法,在addView中,会利用LayoutParams获得window的View属性,并为每个window创建ViewRoot,ViewRoot是View和WindowManager之间的桥梁,真正把View传递给WindowManager的是通过ViewRoot的setView()方法,ViewRoot实现了View和WindowManager之间的消息传递。在将主窗口添加到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、事件、消息收集处理等。

WindowManager的总结:

(1)WindowManager是外界访问Window的入口,Window的具体实现是WindowManagerService,WindowManager和WindowManagerService的交互是一个IPC过程。
(2)Android中所有的视图都是通过Window呈现的,不管是Activity、Dialog还是Toast,他们的视图实际上都是附加在Window上的,因此Window实际是View的直接管理者。

 

面试回答:

 Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图) LayoutInflater像剪刀,Xml配置像窗花图纸。

 

在Activity中调用attach,创建了一个Window

 

  1. 创建的window是其子类PhoneWindow,在attach中创建PhoneWindow

  2. 在Activity中调用setContentView(R.layout.xxx)

  3. 其中实际上是调用的getWindow().setContentView()

  4. 调用PhoneWindow中的setContentView方法

  5. 创建ParentView:作为ViewGroup的子类,实际是创建的DecorView(作为FramLayout的子类)

  6. 将指定的R.layout.xxx进行填充通过布局填充器进行填充【其中的parent指的就是DecorView】

  7. 调用到ViewGroup

  8. 调用ViewGroup的removeAllView(),先将所有的view移除掉

  9. 添加新的view:addView()

 

 

    原文作者:深南大盗
    原文地址: https://blog.csdn.net/whb20081815/article/details/62419059
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞