博客首页:http://www.cnblogs.com/kezhuang/p/

关于Activity的contentView的构建过程,我在我的博客中已经分析过了,不了解的可以去看一下

《[Android FrameWork 6.0源码学习] Window窗口类分析》

本章博客是接着上边那篇博客分析,目的是为了引出分析ViewRootImpl这个类。现在只是分析完了Window和ActivityThread的调用过程

从ActivityThread到WindowManager再到ViewRootImpl这块还属于空白部分,所以要补这篇博客

在上篇博客的末尾提到最后是由WindowManager的addView来请求显示界面,那么我们接着分析

WindowManager这是一个接口,他继承了ViewManager这个接口,所以具有管理View的能力

WindowManager这个实例是通过 Activity.getWindowManager 方法获取的,我们先找到他的实例,在逐渐去看addView函数

    public WindowManager getWindowManager() {
        return mWindowManager;
    }

Activity中是这样定义的该函数,返回了mWindowManager对像,接下来找一下赋值mWindowManager对象的地方

    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) {

        mWindow = new PhoneWindow(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
    }

我们看到在Activity初始化时候调用的attach方法中赋值了mWindowManager方法,但是这个值是从mWindow对象中获取到的,我们进入看一下

    public WindowManager getWindowManager() {
        return mWindowManager;
    }

在Window中也是这样定义的,返回mWindowManager

    public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
            boolean hardwareAccelerated) {
        mAppToken = appToken;
        mAppName = appName;
        mHardwareAccelerated = hardwareAccelerated
                || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
        if (wm == null) {
            wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        }
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    }

Window中的mWindowManager是在setWindowManager中创建而来,而这个setWindowManager其实是在Activity的attach方法中调用
可以看到其实就是用的系统服务WindowManager强转成WindowManagerImpl之后又调用了createLocalWindowManager方法得到的对象

    public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
        return new WindowManagerImpl(mDisplay, parentWindow);
    }

这个方法也很简单,就是new了一下WindowManagerImpl

OK了,到现在可以知道WindowManager的实现类为WindowManagerImpl,那么我们继续分析它实现的addView方法

    @Override
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        mGlobal.addView(view, params, mDisplay, mParentWindow);
    }

该方法定义在WindowManagerImpl中,mGlobal为WindowManagerGlobal对象,是一个系统单例对象

    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
        if (view == null) {
            throw new IllegalArgumentException("view must not be null");
        }
        if (display == null) {
            throw new IllegalArgumentException("display must not be null");
        }
        if (!(params instanceof WindowManager.LayoutParams)) {
            throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
        }

        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
        if (parentWindow != null) {
            parentWindow.adjustLayoutParamsForSubWindow(wparams);
        } else {
            // If there's no parent, then hardware acceleration for this view is
            // set from the application's hardware acceleration setting.
            final Context context = view.getContext();
            if (context != null
                    && (context.getApplicationInfo().flags
                            & ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
                wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
            }
        }

        ViewRootImpl root;
        View panelParentView = null;

        synchronized (mLock) {
            // Start watching for system property changes.
            if (mSystemPropertyUpdater == null) {
                mSystemPropertyUpdater = new Runnable() {
                    @Override public void run() {
                        synchronized (mLock) {
                            for (int i = mRoots.size() - 1; i >= 0; --i) {
                                mRoots.get(i).loadSystemProperties();
                            }
                        }
                    }
                };
                SystemProperties.addChangeCallback(mSystemPropertyUpdater);
            }

            int index = findViewLocked(view, false);
            if (index >= 0) {
                if (mDyingViews.contains(view)) {
                    // Don't wait for MSG_DIE to make it's way through root's queue.
                    mRoots.get(index).doDie();
                } else {
                    throw new IllegalStateException("View " + view
                            + " has already been added to the window manager.");
                }
                // The previous removeView() had not completed executing. Now it has.
            }

            // If this is a panel window, then find the window it is being
            // attached to for future reference.
            if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
                    wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
                final int count = mViews.size();
                for (int i = 0; i < count; i++) {
                    if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
                        panelParentView = mViews.get(i);
                    }
                }
            }

            //创建了一个新的ViewRootImpl对象出来
            root = new ViewRootImpl(view.getContext(), display);

            view.setLayoutParams(wparams);
            //为当前界面保存ViewRootImpl和view还有添加的Layout参数
            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);
        }
        // do this last because it fires off messages to start doing things
        try {
        //调用ViewRootImpl中的setView方法,准备进行View的重绘流程,并且绘制到界面上
            root.setView(view, wparams, panelParentView);
        } catch (RuntimeException e) {
            // BadTokenException or InvalidDisplayException, clean up.
            synchronized (mLock) {
                final int index = findViewLocked(view, false);
                if (index >= 0) {
                    removeViewLocked(index, true);
                }
            }
            throw e;
        }
    }

这篇博客到这就结束了,接下来我总结下上边的流程
1.Activity初始化的时候创建了一个WindowManager对象(和系统的WindowManager服务还有点区别)
2.利用这个Activity专属的WindowManager对象请求添加一个View到当前界面上
3.WindowManager找到自己的实现类WindowManagerImpl,然后在委托给系统单例类WindowManagerGlobal处理
4.WindowManagerGlobal会创建一个ViewRootImpl对象出来
5.ViewRootImpl对象调用setView方法,然后进行界面重绘最后交给Surface进行界面展示

Ok了,很清晰的分析出了从WindowManager到ViewRootImpl的过程,接下来就可以分析ViewRootImpl.setView和ViewRootImpl的performTraversals方法了

[Android FrameWork 6.0源码学习] View的重绘过程之WindowManager的addView方法的更多相关文章

  1. [Android FrameWork 6.0源码学习] View的重绘过程之Draw

    View绘制的三部曲,测量,布局,绘画现在我们分析绘画部分测量和布局 在前两篇文章中已经分析过了.不了解的可以去我的博客里找一下 下面进入正题,开始分析调用以及函数原理 private void pe ...

  2. [Android FrameWork 6.0源码学习] View的重绘过程之Layout

    View绘制的三部曲,测量,布局,绘画现在我们分析布局部分测量部分在上篇文章中已经分析过了.不了解的可以去我的博客里找一下 View的布局和测量一样,都是从ViewRootImpl中发起,ViewRo ...

  3. [Android FrameWork 6.0源码学习] View的重绘过程

    View绘制的三部曲,  测量,布局,绘画今天我们分析测量过程 view的测量是从ViewRootImpl发起的,View需要重绘,都是发送请求给ViewRootImpl,然后他组织重绘在重绘的过程中 ...

  4. [Android FrameWork 6.0源码学习] View的重绘ViewRootImpl的setView方法

    博客首页:http://www.cnblogs.com/kezhuang/p/ 本篇文章来分析一下WindowManager的后续工作,也就是ViewRootImpl的setView函数的工作 /i* ...

  5. Android View的重绘过程之WindowManager的addView方法

    博客首页:http://www.cnblogs.com/kezhuang/p/ 关于Activity的contentView的构建过程,我在我的博客中已经分析过了,不了解的可以去看一下 <[An ...

  6. [Android FrameWork 6.0源码学习] LayoutInflater 类分析

    LayoutInflater是用来解析XML布局文件,然后生成对象的ViewTree的工具类.是这个工具类的存在,才能让我们写起Layout来那么省劲. 我们接下来进去刨析,看看里边的奥秘 //调用i ...

  7. [Android FrameWork 6.0源码学习] ViewGroup的addView函数分析

    Android中整个的View的组装是采用组合模式. ViewGroup就相当与树根,各种Layout就相当于枝干,各种子View,就相当于树叶. 至于View类.我们就当它是个种子吧.哈哈! Vie ...

  8. [Android FrameWork 6.0源码学习] Window窗口类分析

    了解这一章节,需要先了解LayoutInflater这个工具类,我以前分析过:http://www.cnblogs.com/kezhuang/p/6978783.html Window是Activit ...

  9. 【Spark2.0源码学习】-1.概述

          Spark作为当前主流的分布式计算框架,其高效性.通用性.易用性使其得到广泛的关注,本系列博客不会介绍其原理.安装与使用相关知识,将会从源码角度进行深度分析,理解其背后的设计精髓,以便后续 ...

随机推荐

  1. 【BZOJ1412】狼和羊的故事(网络流)

    [BZOJ1412]狼和羊的故事(网络流) 题面 Description "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......" Orez听 ...

  2. 我的C++学习之旅

    说在前面:1.学习缘由及学习途径: 在学了Python,c#(自认为未精通)之后,我决定学一下C++. 于是去网上找视频教程,发现都不适合我这种有一定基础的自学者,要么是不完整的高级教程,要么是零基础 ...

  3. windows下编译caffe报错:error MSB4062: 未能从程序集 E:\NugetPackages\OpenCV.2.4.10\......的解决办法

    参考博客:http://blog.csdn.net/u013277656/article/details/75040459 在windows上编译caffe时,用vs打开后会自动加载还原NugetPa ...

  4. 面向对象设计模式_生成器模式详解(Builder Pattern)

    首先提出一个很容易想到应用场景: 手机的生产过程:手机有非常多的子件(部件),成千上万,不同品牌的手机的生产过程都是复杂而有所区别的,相同品牌的手机在设计上也因客户需求多样化,大到型号,小到颜色,是否 ...

  5. 数据操纵:SELECT, INSERT, UPDATE, DELETE

    SELECT 句法 SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE ...

  6. 基于netcore实现mongodb和ElasticSearch之间的数据实时同步的工具(Mongo2Es)

    基于netcore实现mongodb和ElasticSearch之间的数据实时同步的工具 支持一对一,一对多,多对一和多对多的数据传输方式. 一对一 - 一个mongodb的collection对应一 ...

  7. python中的str.strip()的用法

    python中字符串str的strip()方法 str.strip()就是把字符串(str)的头和尾的空格,以及位于头尾的\n \t之类给删掉. 例1:str=" ABC"prin ...

  8. LNMP详解

    目录 Nginx配置    1 PHP解析    1 Mysql操作    3 服务安装    3 连接测试    3 数据配置    3 Blogs建立    4   LNMP 环境 Mysql:1 ...

  9. maven项目与普通项目的区别

    maven项目 1:创建方式不同 (web项目举例) 第一种: 第二种: 2:目录结构  稍有不同 3:Pom文件 添加依赖信息,需要那个jar包的时候  加入哪个jar包的依赖,要不然无法使用这个j ...

  10. 1.使用dom4j解析XML文件

    一.dom4j的简介 dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的.dom4j是一个十分优秀的JavaXML API,具有性能优异.功能强大和极其易使用的特点,它 ...