当前位置: 58彩票app下载 > 编程技术 > 正文

主意开拓搜求第八章笔记

时间:2019-09-18 11:13来源:编程技术
Window表示三个窗口的概念,Window是三个抽象类,它的切实落到实处是PhoneWindow。创立三个Window,供给通过WindowManager就可以实现,WindowManager是外部访谈Window的进口,Window具体贯彻位于Wi

Window表示三个窗口的概念,Window是三个抽象类,它的切实落到实处是PhoneWindow。创立三个Window,供给通过WindowManager就可以实现,WindowManager是外部访谈Window的进口,Window具体贯彻位于WindowManagerService中,WindowManager和WindowManagerService的互动是叁个IPC的经过。Android中,全部的视图都以因此Window来呈现,不管是Activity、Dialog、依旧Toast,它们的视图实际上都以增大在Window上,因此Window是实际上View的第一手领导,单击事件由Window传递给DecorView,然后再由DecorView传递给我们的View,就连Activity的设置视图方法setContentView在尾巴部分也是通过Window来实现的。

理解Window和WindowManager

Window是八个抽象类,它的求实完毕是PhoneWindow。WindowManager是外部采访Window的进口,Window的有血有肉落到实处位于WindowManagerService中,WindowManager和WindowManagerService的互相是贰个IPC进程。Android中有着的视图都以经过Window来表现的,不管是Activity、Dialog照旧Toast,它们的视图实际上都以增大在Window上的,因而Window实际是View的直接领导。

Window和WindowManager

累加一个Window的历程,入眼代码是:

mWindowManager.addView(mFLoatingButton,mLayoutParams);

WindowManager.LayoutParams中有三个flags和type参数。

Flags参数有八个Window属性

  • FLAG_NOT_FOCUSABLE。表示Window不须要获得关节,也没有要求抽取种种输入事件,最后事件会直接传送给下层的富有标准的Window
  • FLAG_NOT_TOUCH_MODAL。在此情势下,系统会将方今Window区域以外的单击事件传递给底层的Window,当前Window区域以内的单击事件则温馨管理,那些符号十分重大,一般的话都亟需敞开此标识,不然其余Window将不能收到单击事件
  • FLAG_SHOW_WHEN_LOCKED。开启此格局能够让Window展现在锁屏的分界面上。

Type参数表示Window的种类,有三种类型,分别是使用Window,子Window和系列Window,应用类Window对应二个Activity,子Window不能够独立存在,它必要附属在一定的父Window之中,比如大面积的Dialog正是二个子Window,系统Window是急需申明权限在能制造的Window,比如Toast和种类状态栏这一个都以系统Window。

Window是分段的,各样Window都有对应的z-ordered,层级大的会覆盖在层级小的Window的方面,在三类Window中,应用类的Window的层级范围是1-99,子Window的层级范围是一千-壹玖玖陆,系统Window的层级的限量是三千-2999,这一个层级范围对应着WindowManager.LayoutParams的Type参数。如想要Window位于全体Window的最顶层,那么采取非常大的层级就能够。很鲜明系统Window层级是最大的,并且系统层级有无数值。

WindowManager所提供的功力很简短,常用有多少个法子,即增多View,更新View和删除View,这多个办法定义在ViewManager中,而WindowManager承袭了ViewManager。

8.1 Window和WindowManager

为了深入分析Window的干活机制,先经过代码通晓怎么使用WindowManager增加多少个Window,上边一段代码将一个Button增多到显示屏坐标为(100, 300)的岗位上

mFloatingButton = new Button(this);
mFloatingButton.setText("test button");
mLayoutParams = new WindowManager.LayoutParams(
        LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0,
        PixelFormat.TRANSPARENT);//0,0 分别是type和flags参数,在后面分别配置了
mLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
        | LayoutParams.FLAG_NOT_FOCUSABLE
        | LayoutParams.FLAG_SHOW_WHEN_LOCKED;
mLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR;
mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
mLayoutParams.x = 100;
mLayoutParams.y = 300;
mFloatingButton.setOnTouchListener(this);
mWindowManager.addView(mFloatingButton, mLayoutParams);

Flags参数表示Window的属性,以下列举常用的选项:

  • FLAG_NOT_FOCUSABLE:表示Window没有须要获得关节,也无需接受各样输入事件,此标志会同一时间运行FLAG_NOT_TOUCH_MODEL,最后事件会传送给下层的富有规范的Window
  • FLAG_NOT_TOUCH_MODAL:在此方式下,系统会将前段时间Window区域以外的单击事件传递给底层的Window,当前Window区域以内的单击事件则要好处理。那么些符号很关键,一般的话都亟需敞开此标识,不然别的Window将无法接受单击事件。
  • FLAG_SHOW_WHEN_LOCKED:开启此格局能够让展现在锁屏的分界面

Type参数表示Window的等级次序,Window有三种类型,分别是应用Window、子Window和体系Window。应用类Window对应着贰个Activity。子Window不可能独立存在,它须要附属在一定的父Window之中,比方大范围的一些Dialog正是五个子Window。系统Window是供给注明权限才具创立的Window,譬喻Toast和连串状态栏这么些都以系统Window。

Window是分段的,各个Window都有相应的z-ordered,层级最大的会覆盖在层级小的Window上边,那和HTML中的z-index的定义是完全一致的。在三类Window中,应用Window的层级范围是199,子Window的层级范围是1000一九九六,系统Window的层级范围是2000~2999,那么些层级属性范围对应着WindowManager.LayoutParams的type参数。

譬喻使用TYPE_SYSTEM_EGL450RO哈弗,只供给为type参数内定这么些层级就可以:

mLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR

何况声明权限:

<uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW" />

WindowManager所提供的效率很简单,常用的独有七个艺术,即增加View、更新View和删除View,那四个情势定义在ViewManager中,而WindowManager承袭了ViewManager。

Window的里边机制

Window是二个虚无的概念,每八个Window都对应着三个View和多少个ViewRootImpl,Window和View通过ViewRootImpl来创建联系,表明View才是Window存在的实业,在实质上接纳中无法直接访谈Window,对Window的拜访必得透过WindowManager。

Window的增加进度

Window的丰裕进度须求经过WindowManager的addView来达成,WindowManager是多少个接口,它的实在贯彻是WindowManagerImpl类。

@Overridepublic void addView(View view,ViewGroup.LayoutParams params){ mGlobal.addView(view,params,mDisplay,mParentWindow);}@Overridepublic void updateViewLayout(View view,ViewGroup.LayoutParams params){ mGlobal.updateViewLayout(view,params);}@Overridepublic void removeView(View view){ mGlobal.removeView(view,false);}

能够看来,WindowManagerImpl并从未一向实现Window的三大操作,而是全部交由了WindowManagerGlobal来管理,WindowManagerGlobal以工厂的花样向外提供自个儿的实例。WindowManagerGlobal的addView方法首要分为如下几步:

  • 检查参数是或不是合法,要是是子Window那么还索要调动部布满局参数
  • 开创ViewRootImpl并将View增添到列表中
  • 经过ViewRootImpl来更新分界面并成功Window的拉长进程

Window的去除进度

Window的去除进度和增加进度同样,都是先通过WindowManagerImpl后,在更加的通WindowManagerGlobal来贯彻的。里面用到多个dispatchDetachedFromWindow方法内部贯彻,这些艺术首要做了四件事:

  • 污源回收相关的办事,举例清除数据和新闻、移除回调
  • 经过Session的remove方法删除Window
  • 调用View的dispatchDetachedFromWindow方法,在里头会调用View的onDetachedFromWindow()以及onDetachedFromWindowInternal()
  • 调用WindowManagerGlobal的doRemoveView方法刷新数据

Window的更新进度

最首借使用到updateViewLayout方法,首先它须求立异View的LayoutParams并替换掉老的LayoutParams,接着再立异ViewRootImpl中的LayoutParams,这一步是经过ViewRootImpl的setLayoutParams方法来兑现的。在ViewRootImpl中会通过scheduleTraversals方法对View实行重复布局,包蕴衡量、布局、重绘那四个经过。

8.2 Window的内部机制

Window是二个虚幻的定义,并不是实在存在的,它是以View的款式存在,每二个Window都对应着二个View和多少个ViewRootImpl,Window和View通过ViewRootImpl来建立联系。在事实上行使中不可能直接待上访谈Window,对Window的拜候必得通过WindowManager。

Window的始建过程

View是Android中的视图显示格局,但是View不能够独立存在,它必得附上在Window这么些抽象的概念上边,由此有视图的地方就有Window。

Activity的Window创立进程

何以创建,需求通晓Activity运转进程,比较复杂,但它最后由ActivityThred中的perfromLaunchActivity()来成功全部运维进程,在这些格局内部会通过类加载器成立Activity的实例对象,并调用其attach方法为其关联运转进度中所注重的一二种上下文意况变量。

在Activity的attach方法里,系统会创制Activity所属的Window对象并为其安装回调接口,Window对象的创制是由此PolicyManager的makeNewWindow方法达成的,对于Activity的setContentView的达成能够见见,Activity将现实完成交给了Window管理,而Window的实际贯彻是PhoneWindow,所以只须求看PhoneWindow相关逻辑就能够,大致以下多少个步骤:

  • 比如未有DecorView,那么就创办它。DecorView是一个FrameLayout,是Activity的一流View,一般的话它的里边含有标题栏和里面栏。
  • 将View添加到DecorView的mContentParent中。
  • 回调Activity的onContentChanged方法文告Activity视图已经爆发变动。Activity的onContentChanged是贰个空达成。

通过地点多少个步骤,DecorView已经被创设初叶化完成,Activity的布局文件已经成功加多到了DecorView的mContentParent中,不过今年DecorView还从未被WindowManager正式增多到Window中,真正被视图调用是在Activity的onResume方法,接着会调用Activity的makeVisible(),就是在makeVisible方法中,DecorView真正地产生了增加和呈现那五个经过。

Dialog的Window创立进度

Dialog的Window的创建进度和Activity类似,有以下多少个步骤:

  • 创建Window。同样是经过PolicyManager的makeNewWindow方法来完结的。
  • 最早化DecorView并将Dialog的视图增添到DecorView中。
  • 将DecorView加多到Window中并呈现。在Dialog的show方法中,会通过WindowManager将DecorView增加到Window中。

普普通通的Dialog有八个特殊之处,那就是必需采纳Activity的Context,如若选用Application的Context,就能报错。

Toast的Window成立进程

Toast和Dialog分化,它的干活进度稍微复杂。首先Toast也是依照Window来兑现的,可是由于Toast具备按时撤除这一作用,所以系统利用了Handler。在Toast的个中有两类的IPC过程,第一类是Toast访问NotificationManagerService,第二类是NotificationManagerService回调Toast的TN接口。

Toast属于系统Window,它里面包车型客车视图有三种办法钦定,一种是系统默许的体裁,另一种是因此setView方法来钦点八个自定义View,不管什么,它们都对应Toast的贰个View类型的个中成员mNextView。Toast提供了show和cancel分别用于展现和遮蔽Toast,它们的里边是贰个IPC进度。

8.2.1 Window的拉长进度

Window的丰硕进程必要通过WindowManager的addView来达成,WindowManager是四个接口,它的着实落到实处是WindowManagerImpl类。WindowManager的完结类对于addView、updateView和removeView方法都是委托给WindowManagerGlobal类。

WindowManagerGlobal的addView方法分为如下几步:

  1. 检查参数是或不是合法,倘使是子Window那么还索要调动部分布局参数
  2. 创办ViewRootImpl并将View增加到列表中
  3. 经过ViewRootImpl来更新界面并产生Window的增加进度

8.2.2 Window的删除进度

和增长进度一样,都是先经过WindowManagerImpl后,再进一步通过WindowManagerGlobal来贯彻的。
确实删除View的逻辑在dispatchDetachedFromWindow方法的个中贯彻。dispatchDetachedFromWindow方法重要做四件事:

  1. 垃圾堆回收的干活,举个例子清除数据和消息,移除回调。
  2. 由此Session的remove方法删除Window,mWindowSession.remove(mWindow),那无差别于是八个IP C进度,最后会调用WindowManagerService的removeWindow方法
  3. 调用View的dispatchDetachedFromWindow方法,在中间调用View的onDetachedFromWindow()以及onDetachedFromWindowInternal()。
  4. 调用WindowManagerGlobal的doRemoveView方法刷新数据,满含mRoots、mParams以及mDyingViews,必要将近来Window所提到的那三类对象从列表中删去。

8.2.3 Window的更新进度

第一须要更新View的LayoutParams并替换掉老的LayoutParams,接着再立异ViewRootImpl中的LayoutParams,这一步是通过ViewRootImpl的setLayoutParams方法来达成的。在ViewRootImpl中会通过scheduleTrversals方法来对View重新布局,包罗度量、布局、重绘八个进程。除了View本人的重绘以外,ViewRootImpl还会因而WindowSession来更新Window的视图,那一个进度最终是由WindowManagerService的relayoutWindow()来具体落到实处的,一样是一个IPC进度。

Window的开创进程

8.3.1 Activity的Window成立进程

1、Activity的开发银行进程很复杂,最后会由ActivityThread中的performLaunchActivity()来产生整个运行进程,在那个艺术内部会由此类加载器创造Activity的实例对象,并调用其attach方法为其涉及运营进程中所正视的一多种上下文景况变量。

2、Activity达成了Window的Callback接口,当Window接收到外围的意况变化时就能够调用Activity的艺术,譬如onAttachedToWindow、onDetachedFromWindow、dispatchTouch伊芙nt等。

3、Activity的Window是由PolicyManager来创设的,它的确实兑现是Policy类,它会新建三个PhoneWindow对象,Activity的setContentView的贯彻是由PhoneWindow来落实的。
PhoneWindow方法大致服从如下多少个步骤:

  1. 要是没有DecorView,那么就创办它
  2. 将View添加到DecorView的mContentParent中
  3. 回调Activity的onCreateChanged方法布告Activity视图已经产生转移

8.3.2 Dialog的Window创设进度

Dialog的Window的创始进度和Activity类似,有如下步骤:

  1. 成立Window:Diolog中Window的创造一样是通过PolicyManager的makeNewWindow方法来成功的,创制后的靶子实际正是PhoneWindow。
  2. 初步化DecorView并将Dialog的视图增多到DecorView中
  3. 将DecorView增多到Window中并显示:普通的Dialog有二个异样之处,便是必得利用Activity的Context,倘诺利用Application的Context,那么就能够报错。应用token唯有Activity具备,所以这里只必要Activity作为Context来呈现对话框就能够。

8.3.3 Toast的Window创造进度

在Toast的内部有两类IPC进度,第一类是Toast访谈NotificationManagerService,第二类是NotificationManagerService回调Toast里的TN接口。

Toast属于系统Window,它里面包车型大巴视图由三种办法内定:一种是系统私下认可的身体力行,另一种是因此setView方法来钦赐三个自定义的View

Toast具有按期撤消成效,所以系统利用了Handler。Toast的来得和隐蔽是IPC进程,都亟待NotificationManagerService(NMS)来兑现,在Toast和NMS进行IPC进程时,NMS会跨进度回调Toast中的TN类中的方法,TN类是二个Binder类,运营在Binder线程池中,所以须求通过Handler将其切换成当下出殡和埋葬Toast央浼所在的线程,所以Toast不能在未曾Looper的线程中弹出。

对此非系统利用来讲,mToastQueue最多能同有时候存在50个ToastRecord,那样做是为了防备DOS(Denial of Service,拒绝服务)。因为若是有个别应用弹出太多的Toast会导致其余应用尚未机缘弹出Toast。

编辑:编程技术 本文来源:主意开拓搜求第八章笔记

关键词:

  • 上一篇:没有了
  • 下一篇:没有了