Skip to content

Latest commit

 

History

History
125 lines (55 loc) · 10.2 KB

3.Android Framework框架.md

File metadata and controls

125 lines (55 loc) · 10.2 KB

3.Android Framework框架

Framework框架

Framework定义了客户端组件和服务端组件功能及接口。

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

服务端

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

WmS的作用是为所有应用程序分配窗口,并管理这些窗口。包括分配窗口的大小,调节各窗口的叠放次序,隐藏或显示窗口。

AmS的作用是管理所有应用程序中的Activity。

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

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

客户端

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

  • ActivityThread类:该类为应用程序的主线程类,所有的APK程序都有且仅有一个ActivityThread类,程序的入口为该类中的static main()函数。ActivityThread是Android Framework中一个非常重要的类,它代表一个应用进程的主线程,其职责就是调度及执行在该线程中运行的四大组件。

    注意到此处的ActivityThread创建于SystemServer进程中。

    由于SystemServer中也运行着一些系统APK,例如framework-res.apk、SettingsProvider.apk等,因此也可以认为SystemServer是一个特殊的应用进程。

    AMS负责管理和调度进程,因此AMS需要通过Binder机制和应用进程通信。

    为此,Android提供了一个IApplicationThread接口,该接口定义了AMS和应用进程之间的交互函数。

  • 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进行了一定的装饰,比如添加一个通用的Titlebar,并响应特定的按键消息等。

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

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

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

Linux驱动

Linux驱动和Framework相关的主要包含两部分:

  • SurfaceFlingger(SF)驱动:每一个窗口都对应一个Surface,SF驱动的作用是把各个Surface显示在同一个屏幕上。
  • Binder驱动:Binder驱动的作用是提供进程间的消息传递。

APK程序的运行过程

  1. 首先,ActivityThread从main()函数开始执行,调用prepareMainLooper()为UI线程创建一个消息队列(MessageQueue)。
  2. 创建一个ActivityThread对象,在ActivityThread的初始化代码中会创建一个H(Handler)对象和一个ApplicationThread(Binder)对象。其中Binder负责接收远程AmS的IPC调用,接收到调用后,则通过Handler把消息发送到消息队列,UI主线程会异步地从消息队列中取出消息并执行相应的操作,比如start、stop、pause等。
  3. UI主线程调用Looper.loop()方法进入消息循环体,进入后就会不断地从消息队列中读取并处理消息。
  4. 当ActivityThread接收到AmS发送发送start某个Activity后,就会创建指定的Activity对象。Activity又会创建PhoneWindow类 ==》 DecorView类 ==》 创建相应的View或ViewGroup。创建完成后,Activity需要把创建好的界面显示到屏幕上,于是调用WindowManager类,后者于是创建一个ViewRoot对象,该对象实际上创建了ViewRoot类和W类,创建ViewRoot对象后,WindowManager再调用WmS提供的远程接口完成添加一个窗口并显示到屏幕上。
  5. 接下来,用户开始在程序界面上操作。KeyQ线程不断把用户消息存储到QueueEvent队列中,InputDispatch而Thread线程逐个去除消息,然后调用WmS中的相应函数处理该消息。当WmS发现该消息属于客户端某个窗口时,就会调用相应窗口的W接口。W类是一个Binder,负责接收WmS的IPC调用,并把调用消息传递给ViewRoot,ViewRoot再把消息传递给UI主线程ActivityThread,ActivityThread解析该消息并作出相应的处理。在客户端程序中,首先处理消息的是DecorView,如果DecorView不想处理某个消息,则可以将该消息传递给其内部包含的子View或者ViewGroup,如果还没有处理,则传递给PhoneWindow,最后再传递给Activity。

上面启动完后会有几个线程? 每个Binder对象都对应一个线程,Activity启动后会创建一个ViewRoot.W对象,同时ActivityThread会创建一个ApplicationThread对象,这两个对象都继承于Binder,因此会启动两个线程,负责接收Binder驱动发送IPC调用。最后一个主要线程也就是程序本身所在的线程,也叫做用户交互(UI)线程,因为所有的处理用户消息,以及绘制界面的工作都在该线程中完成。

窗口相关概念

窗口、Window类、ViewRoot类以及W类的区别和联系:

  • 窗口(Window):这是一个纯语义的说法,即程序员所看到的屏幕上的某个独立的界面,比如一个带有TitleBar的Activity界面、一个对话框、一个Menu菜单等,这些都称之为窗口。从WmS的角度来讲,窗口是接收用户消息的最小单元,WmS内部用特定的类表示一个窗口,以实现对窗口的管理。WmS接收到用户消息后,首先要判断这个消息属于哪个窗口,然后通过IPC调用把这个消息传递给客户端的ViewRoot类。
  • Window类:该类在android.view包中,是一个abstract类,该类是对包含有可视界面的窗口的一种包装,所谓的可视界面就是指各种View或者ViewGroup,一般可以通过res/layout目录下的xml文件描述。
  • ViewRoot类:该类是android.view包中,客户端申请创建窗口时需要一个客户端代理,用以和WmS进行交互,这个就是ViewRoot的功能,每个客户端的窗口都会对应一个ViewRoot类。ViewRoot类在Android2.2之后就被ViewRootImpl替换了。但是为了方便,后面还是会用ViewRoot类来介绍。
  • W类:该类是ViewRoot类的一个内部类,继承于Binder,用于想WmS提供一个IPC接口,从而让WmS控制窗口客户端的行为。

描述一个窗口之所以有这么多类的原因在于,窗口的概念存在于客户端和服务端(WmS)之中,客户端所理解的窗口和服务端理解的窗口是不同的,因此,在客户端和服务端会用不同的类来描述窗口。比如在客户端,用户能看到的窗口一般是View或者ViewGroup组成的窗口,而与Activity对应的窗口却是一个DecorView类,而具备常规Phone操作的接口却又是一个PhoneWindow类。所以无论是在客户端还是服务端,对窗口都有不同层面的抽象。

Context

Context在应用程序开发中会经常被使用,在一般的计算机书记中,Context被翻译为“上下文”,但是在Android中感觉翻译为“场景”更容易理解一些。

一个Context意味着一个场景,一个场景就是用户和操作系统交互的一种过程。比如当你打电话时,场景包括电话程序对应的界面以及隐藏在界面后的数据。当你看短信时,场景包括短信界面以及隐藏在后面的数据。这也就是为什么一个Activity就是一个Context,一个Service也是一个Context。因为Android程序员把“场景”抽象为Context类,他们认为用户和操作系统的每一次交互都是一个场景,比如打电话、发短信,这些都是有界面的场景,还有一些没有界面的场景,比如后台运行的服务(Service)。一个应用程序可以认为是一个工作环境,用户在这个工作环境汇总会切换到不同的场景,这就像一个前台秘书,她可能需要接待客人,可能要打印文件,还可能要接听客户电话,而这些就称之为不同的场景,前台秘书可称之为一个应用程序。

Context的创建

在创建Application、Activity、Service时,AmS通过远程调用到ActivityThread的bindApplication()方法或ActivityThread的scheduleLaunchActivity()或ActivityThread.scheduleCreateService()方法,这里面会去创建ContextImpl并初始化。