美文网首页
AndroidUI绘制流程(二)

AndroidUI绘制流程(二)

作者: 森码 | 来源:发表于2019-03-26 20:09 被阅读0次

    上篇文章中,我们讲到了UI绘制的三大步,最后我们的方法定位到了performTraversals()方法,而performTraversals的上游又是谁呢?我们接着继续分析

    调用performTraversals()方法的寻找很简单,只有一个调用者doTraversal(),而doTraversal()的调用者是一个Runnable即TraversalRunnable,它的实例调用是

    mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
    

    而它的调用者是ViewRootImpl中的scheduleTraversals()方法,这个方法的在很多处都有调用,而这里基本上是我们逆向分析的终点了,这里我们从主分支开始,即Activity的调用,即ViewRootImpl.requestLayout(),这个方法是我们经常要用到的,而且里面有一个我们常见的Exception(Only the original thread that created a view hierarchy can touch its views.)一些黑科技通过绕过这个方法在子线程刷新UI。

    public void requestLayout() {
            if (!mHandlingLayoutInLayoutRequest) {
                checkThread();
                mLayoutRequested = true;
                scheduleTraversals();
            }
        }
    

    requestLayout()调用者也非常多,这里我们先到ViewRootImpl中找到setView方法,最终我们可以找到的是WindowManagerGlobal中的addView方法,WindowManagerGlobal是什么呢?通过UML图来简单了解一下。



    WindowManager是一个控制窗口的管理类,addView、removeView、updateView都需要它的参与,但是它并不是自己处理的,WindowManager是一个接口,它更多的是一个Binder中Client的角色(可以先简单的认为要与系统的线程间通信)它的实现类其实是WindowManagerImpl,但我们查看WindowManagerImpl中其实并没有多少方法,大部分是通过WindowManagerGlobal去处理了,这里是一个代理模式的实现,这样的好处就是底层可以根据需要(比如有些优化,新版本特性)去改变底层实现,但是上层的接口依然可以沿用。

    WindowManagerGlobal的addView方法中实例化了ViewRootImpl,通过ViewRootImpl我们就可以调用三大步来绘制UI。
    在分析了WindowManagerGlobal之后,我们需要找到它的上层调用WindowManager,我们需要找到创建WindowManager的地方,而与Activity相关,并且初始化Window的地方只有在Activity中的attach方法

    final void attach(Context context, ActivityThread aThread){
    //省略一些代码
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                    mToken, mComponent.flattenToString(),
                    (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    mWindowManager = mWindow.getWindowManager();
    }
    

    这里只是创建了WindowManager,而真正调用addView的地方是在handleResumeActivity()方法中,而调用handleResumeActivity的地方是一个名叫H的Handler,而这个Handler是Activity启动的必经之路,所以我们的调用之路只能到这里了,在这之上的逻辑更多的是Activity的启动流程。

    总结

    面对复杂的调用,没有什么是比时序图能更好理解的了。


    Android_Activity绘制时序图.png

    坦白来说,这篇博客写的并不好,这样逆向分析对上一篇可能好用,但是这篇确实有点太牵强,之后再改改吧。博客写的不多,以后尽量多练习一下,要把这几年积累的都记录下来,加油。

    相关文章

      网友评论

          本文标题:AndroidUI绘制流程(二)

          本文链接:https://www.haomeiwen.com/subject/ehhnvqtx.html