4.Android内核 Framework概述



   想过没?Android程序的入口在哪里?Android Framework都包含哪些必需的系统服务?这些系统

服务时怎样与Android APK程序配合的?





Framework 框架


   Framework定义了客户端组件和服务端组件功能及接口。在Android中,"应用程序"一般是指".apk"程序。


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




服务端

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

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

藏或者显示窗口AmS的作用管理所用应用程序中的Activity



   除以上(WmS和AmS)以外,服务端还包括两个消息处理类


   KeyQ类:WmS的内部类,继承于KeyInputQueue类KeyQ对象一旦创建了,就立即启动一个线程,该

线程会不断地读取用户的UI操作消息,比如按键、触摸屏、trackball、鼠标等,并把这些消息放在消息队列

QueueEvent类中


   InputDispatcherThread类该类的对象一旦创建,也会立即启动一个线程,该线程会不断地从QueueEvent

中取出用户的消息,并进行一定的过滤,过滤后,再将这些消息发送给当前活动的客户端程序中





客户端


   客户端主要包含几个重要类:


   ActivityThread类:应用程序的主线程类,所有的APK程序都有且仅有一个ActivityThread类,程

                 序的入口就是ActivityThread类中的static main()函数。 


   Activity类:APK程序的最小运行单元。一个APK程序中可以包含多个Activity对象,ActivityThread

     主类会根据用户操作选择运行哪个Activity对象。


   PhoneWindow类:该类继承于Window类,同时,PhoneWindow类内部包含了一个DecorView对象。

        简而言之,PhoneWindow是把一个FrameLayout进行了一定的包装,并提供了一

组通用的的窗口操作接口。


   Window类:该类提供了一组通用的窗口(Window)操作API,这里的窗口仅仅是程序层面上的,Wms

      所管理的窗口并不是Window类,而是一个View类或者ViewGrop类,一般就是指DecorView

      类,即一个DecorView就是Wms所管理的一个窗口。Window是一个abstract类型。


   DecorView类:该类是FrameLayout的子类。并且是PhoneWindow中的一个内部类。Decor的英文是

  Decoration,即"修饰"的意思,DecorView就是对普通的FrameLayout进行了一定的

  修饰,不如添加一个通用的Title bar,并响应特定的按键消息等。


   ViewRoot类:Wms管理客户端窗口时,需要通知客户端进行某种操作,这些都是通过异步消息完成的,

        实现方式就是Handler,ViewRoot就是继承于Handler,其作用主要是接收Wms的通知。


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


   WindowManager类:客户端要申请创建一个窗口,而具体创建窗口的任务是由Wms完成的

                                    WindowManager类就像是一个部门经理,谁有什么需求就告诉它,由它和

    Wms进行交互,客户端不能直接和Wms交互。




Linux驱动


Linux驱动和Framework相关的主要包含两个部分。分别是SurfaceFlingger(SF)Binder每一个

窗口都对应一个Surface,SF驱动的作用是把各个Surface显示同一个屏幕上。


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类WindowManager于是创建一个ViewRoot对

象,该对象实际上创建了ViewRoot 类W 类,创建ViewRoot对象后,WindowManager再调用WmS

提供的远程接口完成添加一个窗口并显示到屏幕上


   5.接下来,用户开始在程序界面上操作。KeyQ线程不断把用户消息存储到QueueEvent队列

InputDispatcherThread线程逐个取出消息,然后调用WmS中的相应函数处理该消息。当WmS发现该消

息属于客户端某个窗口时,就会调用相应窗口的W 接口


  6. W类是一个Binder,负责接收Wms的IPC调用,并把调用消息传递给ViewRoot,ViewRoot再把消息传

递给UI主线程ActivityThread,ActivityThread解析该消息并做相应的处理。在客户端程序中,首先处理消

息的是DecorView,如果是DecorView不想处理某个消息,则可以将该消息传递给其内部包含在子View或

则ViewGroup,如果还没处理,则传递给PhoneWindow,最后再传递给Activity





1、2、3 图示

4.Android内核 Framework概述_第1张图片

4 图示:

4.Android内核 Framework概述_第2张图片


5 图示:

4.Android内核 Framework概述_第3张图片


6 图示:

4.Android内核 Framework概述_第4张图片










客户端中的线程


   很明确的说!包含有Activity的客户端程序至少包含三个线程


4.Android内核 Framework概述_第5张图片



   每一个Binder对象都对应一个线程,Activity启动后会创建一个ViewRoot.W 对象,同时ActivityThread

会创建一个ApplicationThread对象,这两个对象都是继承于Binder,因此会启动两个线程,负责接收Linux

Binder驱动发送IPC调用。最后一个主要线程也就是程序本身所在的线程,也叫做用户交互(UI)线程因为

所有的处理用户消息,以及绘制界面的工作都在该线程中完成的。




   自定义Thread和UI线程的区别在于:UI线程是从ActivityThread运行的,在该类中的main()方法中,已经使用

Looper.prepareMainLooper()为该线程添加了Looper对象,即已经为该线程创建了消息队列(MessageQueue)

因此我们才可以直接在Activity中定义Handler对象(因为声明Handler对象时,所在的线程必须已经创建了

MessageQueue)而普通的自定义Thread是一个裸线程,因此,不能直接在Thread中定义Handler对象,从使

用场景的角度来讲,即不能直接给Thread对象发消息,但是却可以给UI线程发消息









Acitivity之间如何传递消息(数据)


有时候需要在不同的Activity之间传递数据,然而,这个问题本身就有问题。所谓“传递消息” 一般是指多个

线程之间,而Activity.本身并不是线程,ActivityThread才是一个线程,即UI线程。同一个程序中的多个Activity

都由ActivityThread进行调用, Activity本身只是一个Java类而已。


事实上,如果要在两个类中传递数据, 方法可以有很多。


方法一可以先实例化某个类,获得该类的引用,当其他类需要该对象的内部数据时,可以直接通
过该引用去访问该类的内部数据


  方法二对于A、B 两个类之间,可以先实例化一个第三方类C,然后两个类都可以把需要传递的
数据存入C 中,或从C 中取出




  这些方法理论上都可以用在Activity类之间传递数据。然而,与普通类传递数据有所不同普通类
的实例化都是程序员显式完成的,而Activity类的实例化却是由Framework完成的
程序员只能使用
startActivityO方法来告诉Framework去运行哪个Activity,这就意味着程序员不能得到Acitivity对象的
引用,那么就不能直接访问该对象的内部数据
解决的办法是使用Activity.getApplicationO函数,该函
数能够返回一个Application对象,该Application对象在该程序中是唯一的,同一程序中的不同Activity
调用该函数所返回的Application对象是相同的,该对象的名称可以在AndroidManifest.xml中指定。一
旦获取了该Application对象,就可以借助该对象,在不同的Activity之间传递数据


   除此之外,Framework本身也提供了标准的Activity之间传递数据的方法,即Intent类。该类作为

startActivity()的参数, 仅用于在启动Activity时传递给目标Activity, 同时, 如果调用

startActivityForResult(), 目标 Activity 在结束后, 也会返回一个 Intent 对象给原 Activity。



   从设计理念的角度来看,Android认为,两个Activity如果要共享数据可以通过Preference
Storage或者文件、数据库进行
,同时,在一般情况下,设备上只会有一个Activity在运行,因此,多
个Activity之间传递数据也不是必需的。如果某个Activity需要在停止后还能处理某些数据,那么,该
Activity似乎更应该被设计为一个后台的Thread或者一个Service,无论是Thread还是Service都很容易
获得其引用。







窗口相关的概念


窗口(Window)从WmS的角度来讲,窗口是接收用户消息的最小单元,WmS内部用特定的类表示一个

窗口,以实现对窗口的管理。WmS接收到用户消息后,首先要判断这个消息属于哪个窗口,然后通

过IPC调用把这个消息传递给客户端的ViewRoot类。


Window类该类在android.view包中,是一个abstract类,该类是对包含有可视界面的窗口的一种包装。

所谓的可视界面就是指各种View或者ViewGroup,一般可以通过res/layout目录下的xml文件描述。


ViewRoot类该类在android.view包中,客户端申请创建窗口时需要一个客户端代理,用以和WmS进行

交互,这个就是ViewRoot的功能,每个客户端的窗口都会对应一个ViewRoot类。


W 类该类是ViewRoot类的一个内部类,继承于Binder,用于向WmS提供一个IPC接口,从而让WmS控制

窗口客户端的行为。


描述一个窗口之所以使用这么多类的原因在于,窗口的概念存在于客户端和服务端(WmS)之中,客户

端所理解的窗口和服务端理解的窗口是不同的因此,在客户端和服务端会用不同的类来描述窗口。同时,无

论是在客户端还是服务端,对窗口都有不同层面的抽象,比如在客户端,用户能看到的窗口一般是View或者

ViewGroup组成的窗口,而与Activity对应的窗口却是一个DecorView类而具备常规Phone操作接口的窗口

却又是一个PhoneWindow类。





你可能感兴趣的:(4.Android内核 Framework概述)