美文网首页Android精选
Android Activity的视图的显示简单理解

Android Activity的视图的显示简单理解

作者: Preupen | 来源:发表于2018-12-13 15:11 被阅读5次

    一.Activity

    Activity是Android四大组件之一 他主要表示应用程序一个界面的所有事物,当然他包含window和一些什么周期方法等等事物。这里我们主要说的window。

    二.Window

    Window可以说是一个窗口,一个用户可以看见的事物,Window是一个抽象类他的具体实现类是PhoneWindow。

    1.Window的分类

    应用 Window:应用类 Window 对应一个 Acitivity
    子 Window:子 Window 不能单独存在,需要依附在特定的父 Window 中,比如常见的一些 Dialog 就是一个子 Window。
    系统 Window:系统 Window是需要声明权限才能创建的 Window,比如 Toast 和系统状态栏都是系统 Window。
    Window 是分层的,层级大的会覆盖在层级小的 Window 上面
    应用 Window 1~99
    子 Window 1000~1999
    系统 Window 2000~2999
    这些层级范围对应着 WindowManager.LayoutParams 的 type 参数,如果想要 Window 位于所有 Window 的最顶层,那么采用较大的层级即可,很显然系统 Window 的层级是最大的,当我们采用系统层级时,需要声明权限。

    2. Activity 的 Window 创建过程

    Activity 的启动过程很复杂,最终会由 ActivityThread 中的 performLaunchActivity() 来完成整个启动过程,在这个方法内部会通过类加载器创建 Activity 的实例对象,并调用其 attach 方法为其关联运行过程中所依赖的一系列上下文环境变量。
    Activity 的 Window 创建就发生在 attach 方法里,系统会创建 Activity 所属的 Window 对象并为其设置回调接口,代码如下:

     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, window); //在这里直接new一个Window
        mWindow.setCallback(this);//设置回调接口,当window接收系统发送给它的例如键盘和触摸屏事件,就可以通知Activity,Activity做出相应的处理
        .....
        //设置窗口管理器
        mWindow.setWindowManager(
             (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        .....
        }
    

    由于 Activity 实现了 Window 的 Callback 接口,因此当 Window 接受到外界的状态改变时就会回调 Activity 的方法。Callback 接口中的方法很多,有几个是我们非常熟悉的,如 onAttachedToWindow、onDetachedFromWindow、dispatchTouchEvent 等等。

    三.Window、WindowManager和WindowManagerServer关系

    Window是这三者的核心,起到了桥梁的作用,她是一个抽象类,主要定义了一些对Window操作的抽象方法。WindowManager主要是管理Window是一个接口类,他继承自ViewManager接口,主要定义了一些对View的操作和一些常量,例如:添加View,移除View,删除View。WindowManagerServer就是位于 Framework 层的窗口管理服务,它的职责就是管理系统中的所有窗口,通过Binder连接WindowManager与Window之间的的通信,即WindowManager通过WindowManagerServer操作Window。

    四.DecorView

    DecorView(FrameLayout)是一个界面的顶级布局,内部有一个垂直方向的LinearLayout,LinearLayout又包含一个ActionBar和ContentPrent。DecorView是PhoneWindow唯一对应的布局。

    五. Activity 的视图是怎么附属到 Window 上的

    下面分析 Activity 的视图是怎么附属到 Window 上的,而 Activity 的视图由 setContentView 提供,所以从 setContentView 入手,它的源码如下:

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

    1.可以看到,Activity 将具体实现交给了 Window,而 Window 的具体实现是 PhoneWindow,所以只需要看 PhoneWindow 的相关逻辑即可,它的处理步骤如下:

    (1)、如果没有 DecorView 就创建一个

    DecorView 是 Activity 中的顶级 View,是一个 FrameLayout,一般来说它的内部包含标题栏和内容栏,但是这个会随着主题的变化而改变,不管怎么样,内容栏是一定存在的,并且有固定的 id:”android.R.id.content”,在 PhoneWindow 中,通过 generateDecor 方法创建 DecorView,通过 generateLayout 初始化主题有关布局。

    (2)、将 View 添加到 DecorView 的 mContentParent 中

    这一步较为简单,直接将 Activity 的视图添加到 DecorView 的 mContentParent 中即可,由此可以理解 Activity 的 setContentView 这个方法的来历了,为什么不叫 setView 呢?因为 Activity 的布局文件只是被添加到 DecorView 的 mContentParent 中,因此叫 setContentView 更加具体准确。

    (3)、回调 Activity 的 onContentChanged 方法通知 Activity 视图已经发生改变

    前面分析到 Activity 实现了 Window 的 Callback 接口,这里当 Activity 的视图已经被添加到 DecorView 的 mContentParent 中了,需要通知 Activity,使其方便做相关的处理。
    经过上面的三个步骤,DecorView 已经被创建并初始化完毕,Activity 的布局文件也已经成功添加到了 DecorView 的 mContentParent 中,但是这个时候 DecorView 还没有被 WindowManager 正式添加到 Window 中。在 ActivityThread 的 handleResumeActivity 方法中,首先会调用 Acitivy 的 onResume 方法,接着会调用 Acitivy 的 makeVisible() 方法,正是在 makeVisible 方法中,DecorView 才真正的完成了显示过程,到这里 Activity 的视图才能被用户看到,如下:

        void makeVisible() {  
          if (!mWindowAdded) {     
           ViewManager wm = getWindowManager(); //获得WindowManager(WindowManager extends ViewManager)
           wm.addView(mDecor, getWindow().getAttributes());   //将DecorView加入到Window中
           mWindowAdded = true;   
          }   
          mDecor.setVisibility(View.VISIBLE);
        }
    

    相关文章

      网友评论

        本文标题:Android Activity的视图的显示简单理解

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