Framework框架概述

Framework框架

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

服务端

服务端主要包含两个重要类,分别是WindowManagerService(WmS)和ActivityManagerService(AmS)。

  • KeyQ类:该类为WmS的内部类,继承自KeyInputQueue类,KeyQ对象一旦创建,就立即启动一个线程,该线程会不断地读取用户的UI操作消息,比如按键,触摸屏,等,并把这些消息放到一个消息队列QueueEvent类中。
  • InputDispatcherThread类:该类的对象一旦创建,也会立即启动一个线程,该线程会不断地从QueueEvent中取出用户消息,并进行一定的过滤,过滤后,再将这些消息发送给当前活动的客户端程序中。

客户端

客户端中重要的类:

  • ActivityThead:应用程序主线程类。
  • Activity:apk程序的一个最小运行单元,ActivityThead根据用户操作选择动态加载哪个Activity对象。
  • PhoneWindow:该类继承Window类,内部包含DecorView对象,因此,可以说内含一个View对象。
  • Window:该类提供了一组通用的窗口操作,WmS所管理的窗口并不是Window类,而是一个View或者ViewGroup类。
  • DecorView:该类是FrameLayout的子类。DecorView就是对普通的 FrameLayout 进行了一定的修饰,比如添加一个通用的TitleBar,并响应特定的按键消息等。
  • ViewRoot:继承于Handler,其作用主要是把WmS的IPC调用转换为本地的一个异步调用。(WmS管理客户端窗口时,需要通知客户端进行某种操作,这些都是通过IPC调用完成的,而在客户端窗口收到IPC调用后,都会把该调用转换为本地的一个异步调用,实现的方式就是使用Handler)
  • W:该类继承自Binder类,并且是 ViewRoot的一个内部类。WmS通知客户端窗口时,是通过IPC调用,也就是调用到该Binder类,然后改Binder内部的处理函数一般会给该类所在的ViewRoot类发送一个Handler消息,以便进行异步处理。
  • WindowManager:客户端要申请创建一个窗口,而具体的创建窗口的任务是由WmS完成的,由它和WmS进行交互,客户端不能直接和WmS进行交互。

Linux驱动

Linux驱动和framework相关的主要包含两部分,分别是SurfaceFlingger(SF)和Binder。每一个窗口都对应一个Surface,SF驱动的作用是把各个Surface显示在同一个屏幕上。
Binder驱动的作用是提供跨进程的消息传递。


APK程序的运行过程

首先,ActivityThread从main函数开始执行,调用prepareMainLooper()为UI线程创建一个消息队列(MessageQueue)。然后创建一个 ActivityThread 对象,在 ActivityThread 的初始化代码中会创建一个 Handler 对象和一个 ApplicationThread(Binder) 对象。其中Binder负责接收远程AmS的IPC调用,接收到调用后,则通过Handler把消息发送给消息队列,UI线程会异步从消息队列中取出消息并执行相应的操作,比如start,stop,pause等。 接着,UI线程调用Looper.loop()方法进入消息循环体,进入后就会不断地从消息队列中读取并处理消息。

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

接下来,用户开始在程序界面上操作。KeyQ线程不断把用户消息存储到QueueEvent队列中, InputDispatcherThread 线程逐个取出消息,然后调用WmS中的相应函数处理该消息。当WmS发现该消息属于客户端某个窗口时,就会调用相应窗口的W接口。
W类是个Binder ,负责接收WmS的IPC调用,并把调用消息传递给ViewRoot,ViewRoot在把消息传递给UI线程ActivityThread,ActivityThread解析该消息并作相应的处理。在客户端程序中,首先处理消息的是DecorView,如果DecorView不想处理某个消息,则可以将该消息传递给其内部包含的子View或者ViewGroup,如果还没有处理,则传递给PhoneWindow,最后再传递给Activity。


客户端中的线程

首先,包含有Activity的客户端程序至少包含三个线程。每个Binder对象都对应一个线程,Activity启动后会创建一个ViewRoot.W对象,同时ActivityThead会创建一个ApplicationThread对象,这两个对象都继承于Binder,因此会启动两个线程,负责接收Linux Binder驱动发送IPC调用。最后一个主要线程就是程序本身所在的线程,也就是UI线程。

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

以上内容记录Framework的学习理解。参考《Android内核剖析》。

发布了28 篇原创文章 · 获赞 27 · 访问量 13万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章