通知短信+运营短信,5秒速达,支持群发助手一键发送🚀高效触达和通知客户 广告
### 我眼中的Android Framework 在开发中我们会遇到各种各样的非常奇怪的问题,有些问题是百思不得骑姐。其实这些问题大都是因为我们不了解安卓内部运行原理,知其所以然才是我们的目的。—前言 任何控制类程序都有一个入口,安卓程序也是。 framework包含三个部分:服务端、客户端、linux驱动。 ### 服务端 服务端主要包含两个重要的类:WindowManagerService和ActivityManagerService ### 客户端 包含以下类: - ActivityThread:是应用程序的主线程类,它所在的线程就是UI线程或者主线程。 - Activity:ActivityThread会根据用户操作选择加载哪个Activity对象。 - PhoneWindow:继承于Window类,内部包含一个DecorView对象,并提供了一些通用窗口操作API。 - Window:一个抽象类,提供了一些通用的窗口操作API。注意:WindowManagerService管理的窗口不是Window类,其实是View和ViewGroup。 - DecorView:FrameLayout的子类,DecorView是对FrameLayout进行了一些修饰,从名字就可以看出来。 - ViewRoot:继承于Handler,主要作用是把WindowManagerService的IPC调用转换为本地的一个异步调用。 - W类:继承于binder,是ViewRoot内部类。主要帮助ViewRoot实现把WindowManagerService的IPC调用转换为本地的一个异步调用。 - WindowManager:客户端如果想创建一个窗口先告诉WindowManager,然后它再和WindowManagerService交互,客户端不能直接和Wms交互。 ### Linux驱动 Linux启动和Framework相关的主要是两个部分:SurfaceFlingger和Binder。 每一个窗口都对应一个Surface,SF主要是把各个Surface显示到同一屏幕上。Binder是提供跨进程的消息传递。 ### 下面借助apk程序的运行过程去理解上面各个组件在何时起到何作用 ActivityThread从main()函数中执行,然后调用prepareMainLooper()为UI线程创建一个消息队列即MessageQueue。 然后创建ActivityThread对象,创建过程会创建一个Handler对象和一个Binder对象,其中Binder负责接收远程Ams的IPC调用,接收到调用后通过Handler把消息发送到消息队列,UI线程则会异步的从消息队列中取出消息并执行相应操作,比如 start、stop、pause。 然后UI线程调用Looper.loop()方法进入消息循环体,进入后就会不断地从消息队列中读取并处理消息。 当ActivityThread接收到Ams发送start某个Activity后就会创建指定的Activity对象。Activity会创建PhoneWindow->DecorView->创建相应的View或ViewGroup。创建完成后调用WindowManager把界面显示到屏幕上,然后创建ViewRoot,然后调用Wms提供的远程接口添加一个窗口并显示到屏幕上。 接下来就是用户的操作,事件线程不断的把消息放到事件队列中去,然后事件分发线程逐个取出消息,然后调用Wms中的相应函数处理该消息。 ### 上面的过程会涉及到很多线程,顺便讲一下关于线程的几个疑惑 1.安卓程序中都有哪些线程? 客户端程序至少包含三个线程,Activity启动后会创建一个ViewRoot.W对象,同时ActivityThread会创建一个ApplicationThread对象,这两个对象继承Binder,每个Binder对应一个线程,因此会启动两个,负责接收Linux Binder驱动发送的IPC调用。还有一个当然是UI线程。 2.UI线程是什么? 用户交互线程,因为所有的处理用户消息,以及绘制页面的工作都在该线程中完成。 3.自定义的线程和UI线程有什么区别? UI线程是从ActivityThread运行的,在该类的main()方法中已经使用了Looper.prepareMainLooper()为该线程添加了Looper对象,即已经为该线程创建了消息队列,因此,我们才可以在Activity中去定义Handler对象,因为创建Handler对象时其线程必须已经创建了消息队列。而普通的Thread则没有默认创建消息队列,所以不能直接在Thread中直接定义Handler,这个就是我们不懂程序运行原理导致的困惑。 转载注明出处,如有问题请留言。