Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1521855
  • 博文数量: 465
  • 博客积分: 8915
  • 博客等级: 中将
  • 技术积分: 6365
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-30 15:05
文章分类

全部博文(465)

文章存档

2017年(33)

2016年(2)

2015年(4)

2014年(29)

2013年(71)

2012年(148)

2011年(178)

分类: IT业界

2011-09-23 17:12:26

Android Framework内核之旅

6.1  Framework框架

Framework定义了客户端组件和服务端组件功能及接口。以下阐述中,“应用程序”一般是指“.apk”程序。

框架中包含三个主要部分,分别为服务端、客户端和Linux驱动。

6.1.1  服务端

服务端主要包含两个重要类,分别是WindowManagerServiceWmS)和ActivityManagerService
(AmS)
WmS的作用是为所有的应用程序分配窗口,并管理这些窗口。包括分配窗口的大小,调节各窗口的叠放次序,隐藏或者显示窗口。AmS的作用是管理所有应用程序中的Activity

除此之外,在服务端还包括两个消息处理类。

KeyQ类:该类为WmS的内部类,继承于KeyInputQueue类,KeyQ对象一旦创建,就立即启动一个线程,该线程会不断地读取用户的UI操作消息,比如按键、触摸屏、trackball、鼠标等,并把这些消息放到一个消息队列QueueEvent类中。

InputDispatcherThread类:该类的对象一旦创建,也会立即启动一个线程,该线程会不断地从QueueEvent中取出用户消息,并进行一定的过滤,过滤后,再将这些消息发送给当前活动的客户端程序中。

6.1.2  客户端                        

客户端主要包括以下重要类。

ActivityThread类:该类为应用程序的主线程类,所有的APK程序都有且仅有一个ActivityThread类,程序的入口为该类中的static main()函数。

Activity类:该类为APK程序的一个最小运行单元,一个APK程序中可以包含多个Activity对象,ActivityThread主类会根据用户操作选择运行哪个Activity对象。

PhoneWindow类:该类继承于Window类,同时,PhoneWindow类内部包含了一个DecorView对象。简而言之,PhoneWindow是把一个FrameLayout进行了一定的包装,并提供了一组通用的窗口操作接口。

Window类:该类提供了一组通用的窗口(Window)操作API,这里的窗口仅仅是程序层面上的,WmS所管理的窗口并不是Window类,而是一个View或者ViewGroup类,一般就是指DecorView类,即一个DecorView就是WmS所管理的一个窗口。Window是一个abstract类型。

DecorView类:该类是一个FrameLayout的子类,并且是PhoneWindow中的一个内部类。Decor的英文是Decoration,即“修饰”的意思,DecorView就是对普通的FrameLayout进行了一定的修饰,比如添加一个通用的Title bar,并响应特定的按键消息等。

ViewRoot类:WmS管理客户端窗口时,需要通知客户端进行某种操作,这些都是通过异步消息完成的,实现的方式就是使用HandlerViewRoot就是继承于Handler,其作用主要是接收WmS的通知。

W类:该类继承于Binder,并且是ViewRoot的一个内部类。

WindowManager类:客户端要申请创建一个窗口,而具体创建窗口的任务是由WmS完成的,WindowManager类就像是一个部门经理,谁有什么需求就告诉它,由它和WmS进行交互,客户端不能直接和WmS进行交互。

6.1.3  Linux驱动

Linux驱动和Framework相关的主要包含两部分,分别是SurfaceFlinggerSF)和Binder。每一个窗口都对应一个SurfaceSF驱动的作用是把各个Surface显示在同一个屏幕上。

Binder驱动的作用是提供跨进程的消息传递。

APK程序的运行过程

首先,ActivityThreadmain()函数中开始执行,调用prepareMainLooper()UI线程创建一个消息队列(MessageQueue)

然后创建一个ActivityThread对象,在ActivityThread的初始化代码中会创建一个HHandler)对象和一个ApplicationThreadBinder)对象。其中Binder负责接收远程AmSIPC调用,接收到调用后,则通过Handler把消息发送到消息队列,UI主线程会异步地从消息队列中取出消息并执行相应操作,比如startstoppause等。

接着UI主线程调用Looper.loop()方法进入消息循环体,进入后就会不断地从消息队列中读取并处理消息。

ActivityThread接收到AmS发送start某个Activity后,就会创建指定的Activity对象。Activity又会创建PhoneWindow类→DecorView类→创建相应的View或者ViewGroup。创建完成后,Activity需要把创建好的界面显示到屏幕上,于是调用WindowManager类,后者于是创建一个ViewRoot对象,该对象实际上创建了ViewRoot类和W类,创建ViewRoot对象后,WindowManager再调用WmS提供的远程接口完成添加一个窗口并显示到屏幕上。

接下来,用户开始在程序界面上操作。KeyQ线程不断把用户消息存储到QueueEvent队列中,InputDispatcherThread线程逐个取出消息,然后调用WmS中的相应函数处理该消息。当WmS发现该消息属于客户端某个窗口时,就会调用相应窗口的W接口。

W类是一个Binder,负责接收WmSIPC调用,并把调用消息传递给ViewRootViewRoot再把消息传递给UI主线程ActivityThreadActivityThread解析该消息并做相应的处理。在客户端程序中,首先处理消息的是DecorView,如果DecorView不想处理某个消息,则可以将该消息传递给其内部包含的子View或者ViewGroup,如果还没有处理,则传递给PhoneWindow,最后再传递给Activity

6.3  客户端中的线程

在多任务操作系统中,任何程序都运行在线程之中。系统首先会为客户端程序分配一个线程,然后该线程从程序的入口处开始执行。那么,请思考以下问题。

Android APK程序中都有哪些线程?

什么是UI线程?

程序中自定义ThreadUI线程的区别是什么?

首先,很明确地讲,包含有Activity的客户端程序至少包含三个线程,如图6-1所示。每个Binder对象都对应一个线程,Activity启动后会创建一个ViewRoot.W对象,同时ActivityThread会创建一个ApplicationThread对象,这两个对象都继承于Binder,因此会启动两个线程,负责接收Linux Binder驱动发送IPC调用。最后一个主要线程也就是程序本身所在的线程,也叫做用户交互(UI)线程,因为所有的处理用户消息,以及绘制界面的工作都在该线程中完成。

为了验证这一点,可以在Eclipse中新建一个Hello Android的程序,然后以debug的方式运行,在debug窗口中会看到如图6-1所示的界面。

 

自定义ThreadUI线程的区别在于,UI线程是从ActivityThread运行的,在该类中的main()方法中,已经使用Looper.prepareMainLooper()为该线程添加了Looper对象,即已经为该线程创建了消息队列(MessageQueue),因此,程序员才可以在Activity中定义Handler对象(因为声明Handler对象时,所在的线程必须已经创建了MessageQueue)。而普通的自定义Thread是一个裸线程,因此,不能直接在Thread中定义Handler对象,从使用场景的角度讲,即不能直接给Thread对象发消息,但是却可以给UI线程发消息。

 

本文选自《Android内核剖析 》一书

图书详细信息:http://blog.chinaunix.net/space.php?uid=13164110&do=blog&id=2897431

 

阅读(1392) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~