6.framework
framework定义了客户端组件和服务端组件及接口。
框架中主要包含三个部分:服务端和客户端、Linux驱动
6.1服务端
服务端主要包括两个类:WindowManagerService和ActivityManagerService
WindowManagerService控制各窗口的叠放次序,隐藏显示窗口。
AMS的作用管理所有应用程序的Activity。
还有两个消息处理类
1.keyQ类:WMS的内部类,继承KeyInputQueue类。KeyQ一旦创建,会启动一个线程,不断地读取用户的UI操作消息。如 按键、触摸屏,并把消息放到一个消息队列中QueueEvent类中。
2.InputDispatcherThread类;一旦创建,也是启动一个线程,不断从QueueEvent中取出用户消息。并进行一定的过滤,然后发送当前活动的客户端程序。
6.2 客户端
- ActivityThread;
app的主线程类,所有apk程序都有且仅有一个ActivityThread类,程序的入口为该类中的static main() - Activity
apk程序一个运行最小单元。activityThread类会根据用户操作选择加载哪个activity对象。 - PhoneWindow:
继承window类,内部包含DecorView,DecorView父类是FrameLayout - Window
提供了一组通用的窗口操作API。wms管理的窗口并不是window类,而是一个view或者viewgroup。 - ViewRoot
wms管理客户端窗口时,需要通知客户端进行某种操作,这些都是通过IPC调用完成。而在客户端收到IPC后,会把该调用转换为本地的一个异步调用,实现的方式就是使用Handler,ViewRoot就是继承于Handler,主要是把wms的IPC调用转换为本地的一个异步调用。 - W
继承Binder,且是viewroot的内部类。wms通知客户端窗口时,是通过IPC调用,也就是调用到该binder类,然后该binder内部的处理函数一般会给该类所在的viewroot类发送一个Handler消息,以便进行异步处理。 - windowManager
客户端要申请创建一个窗口,而具体创建窗口的任务是由wms完成的,客户端不能和WSM之间交互,只能通过windowManager。
6.3 linux
linux驱动和framework相关的主要两部分:surfaceFlingger和Binder.每一个窗口都对应一个surface,SF驱动的作用是把各个surface显示在同一个屏幕上。
6.4 apk程序的运行过程
1.activityThread的main执行,调用prepareMainLooper为UI线程创建队列MessageQueue
2.new ActivityThread (),同时会创建一个H 对象(Handler)和一个ApplicationThread(Binder)对象。其中binder 负责接收远程ams的IPC调用,收到后,通过handler吧消息发送到消息队列,UI线程会异步地从消息队列中取出消息,并执行对应操作,eg start stop pause。
3.UI线程调用looper.loop方法进入消息循环体,进入后不断从消息队列读取消息并处理消息。
4.当ActivityThread接收到ams发送start 某个Activity,创建指定的Activity对象,activity又会创建PhoneWindow—>DecorView–>创建viewgroup,
5.调用windowManager,创建一个viewroot对象和W类,创建viewroot对象后,windowManager调用wms的远程接口完成一个一个窗口并显示到屏幕上。
6.接下来,用户开始操作界面,KeyQ不断把消息储存到QueueEvent对列中,InputDispatcherThread不断读取消息,然后调用wms中的相应函数处理该消息。当wms反送属于某个客户端某个窗口,就会调用相应窗口的W接口。
W类属于Binder,负责接口wms的IPC调用,并把消息传递给viewroot,viewroot在把消息传递给ActivityThread,ActivityThread解析到该消息并做相应的处理。在客户端程序中,首先处理的DecorView,如果DecorView不想处理某个消息,则可以将该消息传递给内部的子类view及viewgroup,如果还没有处理,传递给phonewindow,最后再传递给Actvity。
6.5 客户端至少有几个线程
- 每个Binder都是一个线程,Activity启动后会创建一个
VIewRoot.W对象
,同时ActivityThread会创建一个ApplicationThread对象
,这两个对象都继承于Binder,因此会启动两个线程,负责接收Linux Binder驱动发送的IPC调用
。 - 最后一个程序本身所在的线程,叫UI线程。