天天看点

Android之Framework框架:重要类,APK运行过程,客户端的线程

Framework框架

包含三个主要部分:服务端,客户端,Linux驱动

服务端

两个重要类:

1.WindowManagerService (Wms) 窗口管理系统

为所有的应用程序分配窗口,并且管理这些窗口[View,Viewgroup,Decorview]。(分配窗口大小,调节窗口叠放顺序,隐藏和显示)

2.ActivityMnagerService(Ams) 活动管理系统

管理所有的应用程序中的Activity

两个重要消息处理类:

1.KeyQ类

作为Wms的内部类,KeyQ启动一个线程,不断的去读取用户的ui操作,按键触摸..,并且把这些消息放到消息队列QueueEvent类中。

2.InputDispatcherThread输入调度线程

启动线程,不断从QueueEvent里面读取用户消息,过滤,将消息发送到当前活动客户端。

客户端

重要类

1.ActivityThread 应用程序主线程类(也就是UI线程)

所有的APK程序都有且仅有一个ActivityThread类,程序的入口就是该类的static main() 函数.

2.Activity活动类

作为APK程序的一个最小运行单元,一个APK程序可以包含多个Activtity。ActivityThread会根据选择运行对应的Activity对象。

4.Window窗口类

该类提供一组通用的窗口window操作API,窗口仅仅是程序层面上的。(Wms管理的窗口,并不是window类)

5.PhoneWindow.DecorView 修饰View

FrameLayout 的子类,PhoneWindow 的内部类,对FrameLayout进行修饰封装。

6.PhoneWindow extends Window

对FrameLayout的封装,并且提供一系列通用窗口操作接口。

7.WindowManager 窗口管理

客户端需要申请创建一个窗口,具体创建任务由Wms完成。WindowManger接收客户端申请,和Wms交互,客户端不可直接和Wms交互。

(client –> windowmanager –>Wms )

8.ViewRoot extends Hanlder

Wms管理客户端窗口时候,需要通知客户端进行某种操作,这些通过异步消息完成,实现方式handler,其作用主要是接收Wms的通知。

这个ViewRoot的名字容易让人误解,他和view没有任何关系。这里可以理解viewroot是view树的管理者。他有一个成员mview,指向他所管理的view树的根。

9.W exends Binder

作为ViewRoot的内部类

Apk程序运行过程

1.从AcitivityThread 的mian 函数开始,调用prepareMainLooper 为UI线程创建一个消息队列MessageQueue。

2.创建ActivityThread对象,初始化中创建H(handler)和ApplicationThread(Binder)对象。

UI线程调用Looper.loop()进入消息循环体,进入后不断从消息队列读取并且处理消息。

远程Ams的IPC(调用)–>Binder(接收并且发出消息)–>消息队列–>UI线程(获取消息并处理)。

UI线程异步从消息队列取出操作[start,stop,pause…]

3.当ActivityThread接收到Ams发时start某个Activity后,就会创建指定的Activity对象。紧随Activity会去创建PhoneWindow类–>DecorView类–>创建相应的view和viewgoup。(创建好界面)

Activity调用WindowManager类,创建ViewRoot对象和ViewRoot.W对象。WindowManager调用Wms远程接口,完成添加创建好的界面窗口并且显示在屏幕上。

4.KeyQ不断读取用户界面操作消息并且存储到QueueEvent消息队列。InputDispatcherThread逐个取出消息,然后调用Wms相应的函数处理消息。Wms发现某消息属于客户端某窗口时,就会调用相应窗口的W接口。

W是一个Binder类,接收到Wms的IPC调用,并且把调用消息传递给ViewRoot,ViewRoot把消息传递给UI主线程,UI主线程解析消息并处理消息。

在客户端,首先处理消息的是DecorView,如果DecorView不想处理某个消息,可以把消息传递给其内部包含的子view或viregroup.如果还没处理,就会传递给PhoneWindow,最后在传递给Activity。

Android APK客户端至少有三个线程(每一个Binder都会对应一个线程)

1.ActivityThread会创建一个ApplicationThread(Binder)。

2.Activity会创建ViewRoot.W(Binder)。

3.程序本身的UI主线程。

由此,自定义线程和UI线程是有区别的,UI线程是从ActivityThread运行的,在main 函数中,已经使用了Looper.prepareMainLooper()为线程添加Looper对象,也就是已经为该线程创建了消息队列MessageQueue。因此,才可以在Activity中自定义handler对象。

而普通的thread中是不能直接定义handler对象的。

Looper.prepare(),主线程使用handler,系统默认prepare了

而子线程中创建handler必须在前面Looper.prepare(),后面加上Looper.loop();

new Thread(new Runnable() {

@Override

public void run() {

Looper.prepare()

handler2 = new Handler();

Looper.loop()

}

}).start();

否则会报提示的错误信息为 Can’t create handler inside thread that has not called Looper.prepare()

继续阅读