Window和WindowManager(二)

原创 2016年08月29日 00:20:41

接着上一节,View是Android中的视图的具体呈现方式,但是View必须依附在Window上,不能单独存在,因此有View的地方就有Window,Android中可以提供视图的地方有这么几种,Activity、dialog、Toast、PopupWindow、menu等,我们来分析一下这些地方的window的具体创建过程。

  • Activity中Window的创建过程
    Activity启动的时候过程比较复杂,最终会有ActivityThread中的performLaunchActivity()来完成整个的启动过程,具体的细节这里不做分析,该方法内部会通过类加载器来创建Activity的具体实例,并调用attach方法来为其关联上下文环境变量,代码如下:

    java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
    activity = mInstrumentation.newActivity(cl,component.getClassName(),r.intent);
    
    ...
    
    if(activity!=null){
        Context appContext = createBaseContextForActivity(r,activity);
        CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
        Configration config = new Configuration(mCompatConfiguration);
        if(DEBUG_CONFIGURATION) Slog.v(TAG,"Launching activity"+r.activityInfo.name+"with config"+config);
        activty.attch(appContext,this,getInstrumentation(),r.token,r.ident,app,r.intent,r.activityInfo,title,r.parent,r.embeddedID,r.lastNonConfiguraionInstances,config,r.voiceInteractor);
    
        ...
    

    在Activity的attach方法里,系统会创建Activity所属的Window对象并为其设置回调接口,Window对象的创建是通过PolicyManager的makeNewWindow方法来实现的,由于Activity实现了Window 的callback接口,所以当Window接受到外界的状态改变的时候可以回调Activity的方法,Callback的方法很多,其中onAttachedToWindow、onDetachedFromWindow、dispatchTouchEvent等几个方法是我们比较熟悉的。

    mWindow = PolicyManager.makeNewWindow(this);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if(info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED){
        mWindow.setSoftInputMode(info.softInputMode);
    }
    if(info.uiOptions !=0){
        mWindow.setUiOptions(info.uiOptions);
    }

    从上边的代码我们可以分析出来,Activity的Window是通过PolicyManger的一个工厂方法来创建的,在实际的调用中,PolicyManger的真正实现类是Policy类,该类实现了Ipolicy接口,Policy类中的makeNewWindow方法的实现如下:

    public Window makeNewWindow(Context context){
        return new PhoneWindow(context);
    }

    由此,我们可以确定Window的具体实现类是PhoneWindow。到这里,Window已经创建完毕了,但是我们的视图还没有附加上去,要分析视图的附件过程,我们通过Activity的setContentview方法入手即可:

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

    这里我们可以看出,Activity中setcontentview的具体实现交给了window,而Window的具体实现是phoneWindow,所以我们来看一下PhoneWindow的setContentview方法,PhoneWindow中的实现过程也是比较复杂的,我们看其中几个关键步骤,

    1. 如果没有DecorView,创建DecorView

      DecorView是Activity中的顶级View,是一个FrameLayout,包括标题栏和内容栏,我们在activity中的setcontentview设置的就是decorView中的内容栏。

      DecorView的创建过程由installDecor来完成,该方法内部会调用generateDecor方法来创建一个空表的DecorView。

      而后,PhoneWindow通过generateLayout方法来加载具体的布局文件到DecorView中。

    2. 将View添加到DecorView中的content部分

    3. 回调Activity的onContentChanged方法来通知Activity视图已经改变,该方法在Activity中是一个空实现,需要的时候我们可以在自己的Activity中去处理这个回调。

    经过上边几个步骤,DecorView已经被创建并初始化完成,Activity中的布局文件也已经添加到了DecorView中的mContentParent部分,但是这时候DecorView还没有被WindowManger正式的添加到Window中,在ActivityThread中的handleResumeActivity方法执行之后,DecorView才算是真正的完成了添加和显示这两个过程,Activity的视图才能被用户看到,在该方法中主要执行了两个步骤,首先他会调用activity的onResume方法,接着调用activity的makeVisible方法,实现如下:

    void makeVisible(){
        if(!mWindowAdded){
            ViewManager wm = getWindowManager();
            wm.addView(mDecor,getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
    }

到这里,Activity的Window创建过程已经分析完毕。

  • dialog的window创建过程
    dialog的window创建过程与activity基本类似,也是由以下几个步骤来完成的

    1. 创建window
    2. 初始化DecorView并将dialog视图添加到DecorView中
    3. 将DecorView添加到window中并显示

    但需要注意的是,普通的dialog需要用activity的context来创建,如果使用application的context,会报错。
    如果我们确实需要使用application的context来创建dialog的话,那么我们可以将dialog的window设置为系统级别,同时添加对应权限即可。

    dialog.getWindow().setType(LayoutParams.TYPE_SYSTEM_ERROR);

    同时在manifest中添加系统Window的权限:

    < uses-permission android:name=”android.permission.SYSTEM_ALLERT_WINDOW”/ >

参考资料:Android开发艺术探索

版权声明:本文为博主原创文章,转载请注明来源。

相关文章推荐

理解Window和WindowManager(二)

1、背景通过对前一篇文章的分析我们已经知道了Window的内部机制,其实主要就是对View进行添加、删除和更新。如果大家对Window的内部机制不是很清楚的可以先去了解一下理解Window和Windo...

Android Window 二 可移动悬浮窗口 WindowManager

一、效果演示 二、如何创建悬浮窗口      比较简单,主要是使用WindowManager API,以下是使用方法 [java] view plain ...

Window和WindowManager的工作原理

本文主要讲解Window和WindowManger的工作原理,其中包含如下内容: Window和WindowManger简介 通过WindowManager添加一个简单的Window以及Window的...

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

基本概念描述: 1.Activity用户最直接接触到的,Activity维护应用程序的生命周期,它依赖于Window 2.Window表示一个窗口的概念,类似360悬浮窗的东西就需要Window来实现...

利用Window和WindowManager实现悬浮窗效果——Android开发艺术探索笔记

Window表示一个窗口的概念,在某些特殊的时候,比如你需要在桌面或者锁屏上显示一些类似悬浮窗的东西时候就需要用到Window。Window是一个抽象类,Window的实现类是PhoneWindow。...

WindowManager和Window添加View的区别

WindowManager中有个添加View的函数: public void addView(View view, ViewGroup.LayoutParams params) Window中有个...

关于WindowManager$BadTokenException: Unable to add window异常

我在自定义View里面添加了一个动画,监听动画结束时弹出一个dialog对话框,但是遇到一个问题,就是当动画开始播放尚未结束时,我直接关掉App,会出现一个异常,这个异常大概意思是Activity已经...

开发艺术探索-- Window及WindowManager

第八章,理解Window及WindowManager Window及WindowManager Window内部机制 Window创建过程Window是一个抽象类,实现类是PhoneW...
  • wbwjx
  • wbwjx
  • 2016-12-24 23:50
  • 253

Window和WindowManager(一)

Window是一个抽象类,表示一个窗口,他的具体实现类是PhoneWindow。创建一个Window是很简单的事,只需要通过WindowManager即可完成。WindowManager是外界访问Wi...

理解Window和WindowManager

理解Window和WindowManagerWindow是一个抽象类,它的具体实现是PhoneWindow。WindowManager是外界访问Window的入口,Window的具体实现位于Windo...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)