AMS(ActivityManagerService) 在SystemServer的进程中,是SystemServer中的一个对象;
作用:
管理activity的生命周期
启动activity
与PMS进行交互
Activity->AMS:
调用activity.startActivity()
通过ActivityManage.getService("activity")
得到AMS的BpBinder;
通过BpBinder发送请求,调用AMS的startActivity()
AMS->PMS:
AMS和PMS都在SystemServer
进程中,都是SystemServer
中一个对象
通过包名和PMS里的缓存mPackage
查询到App对应的Package
使用activity的类名通过PMS里的内部类PackageManagerInternalImpl
查询到activity对应的包装类ResolveInfo; ps:ResolveInfo
这个javabean里有activityInfo、ServiceInfo
等变量,查询啥就给哪个变量赋值,再返回ResolveInfo;
得到ResolveInfo
里的activityInfo;
将activityInfo
返回给App进程的ActivityThread;`
ActivityThread
中发送事件
ActivityThread
中的Handler对象mH收到159事件,处理
通过反射创建Activity对象
将Activity对象放到activtes启动记录中
ActivityThread
ActivityThread中重要的对象:
点击桌面App图标发生了什么?
ActivityThread.main()
静态函数,main中创建 ActivityThread
对象ActivityThread.attch()
中创建了一个ApplicationThread
对象,作为和AMS通信时,返回结果的桥梁;attachApplication(thread)
请求AMS获取应用对应的Applaction和栈顶中activity节点信息(步骤4),此时给AMS传过去了一个thread,这个thread就是ApplicationThread
thread.bindApplaction
(data数据…)传给ActivityThread;
(此时代码还会继续往下执行,去获取栈顶activity的节点信息)BIND_APPLICATION(110)
给Handler,Handler调用handleBindApplication(data)
new Applaction
对象appInstrumentation.callApplactionOnCreate(app)
Applaction.onCreate()
thread.scheduleTransaction
(事务数据);(thread为ActivityThread中的ApplicationThread
)ApplicationThread
回调scheduleTransaction
函数中,发送`EXECUTE_TRANSACTION(159)消息EXECUTE_TRANSACTION
消息,从事务数据中取出LaunchActivity
信息,并调用hanldeLaunchActivity
(activity数据)newActivity()
出对象activityactivity.attach()
,在attach中创建WMS的桥接代理类;(绘制流程会用到)Instrumentation
调用callActivityOnCreate(activity)
Activty.onCreate();
下图中4-5中少了上面7-23的步骤:
7-15创建并启动了Application;
16-22创建并启动了Activity;
应用内activity与activity的跳转是跨进程通信,还是同一个进程内通信?
是跨进程通信;
跳转流程参考上面的:省去了application的创建过程;
步骤3 +步骤16-23;
SystemServer: Android一切服务的启动者;
SystemServer.java
的main函数,frok出SystemServer进程(java进程)SystemServer.java
的main函数里执行SystemServer的run方法,main函数里只有一句代码:new SystemServer().run();
ps:SystemManager: 是SystemServer的叔叔,SystemServer把所有服务都交给了SystemManager管理;
SystemManager
中,addService("key",AMS/PMS)
getService()
时,取的是个binder;有一个缓存中心:mPackages;是一个Map,key为应用的包名,value为每个应用的Package;
在手机启动的时候,做了三件事,且只做一次:
AndroidMnifest.xml
,并缓存;作用:只解析每个Apk中的AndroidMnifest.xml
中的信息,而不是去解析节点中每个xxxActivity.java
文件;解析到的信息缓存到mPackages中,相当于“注册表”,方便之后AMS快速定位到相应的APP;
PackageManagerService.java
中会去两个目录做扫描scanDirTracedLI
:用户安装的所有APP目录sAppInstallDir:data/app/;
和系统应用所有APP的目录systemAppDir:System/app/
new PackageParse(),
赋值给包解析工具类PackageParse;AndroidMnifest.xml
,xml解析完会返回Package对象,每个APK对应一个Package对象,得到这个Package对象后,缓存到PackageManagerService的mPackages
这个ArrayMap里;key为应用的包名,value为应用的Package;解析AndroidMnifest.xml
流程:
AndroidMnifest.xml
tagname=="applacation"
tagname=="activity","reciver","service","provide"
等等parseActivity,parseActivity
(reciver和activity的结构一样,就用同样的javabean接收),parseService,parseProvide
Linux事件机制:
事件都是储存在文件中;
如触摸屏幕事件:存储在dev/input/event0的文件中,每次触摸都会以 16进制 数据储存;
INotify:监听文件状态,有变化则产生FD值
epoll机制:
epoll_create:注册监听事件类型
epoll_ctl:监听FD值,FD改变则唤醒epoll_wait()
epoll_wait:没事件则阻塞,有事件则分发;
将INotify和epoll封装为一个对象EventHub;
SystemServer进程启动时,创建了InputManagerService
服务,这个IMS在native层创建了InputManager对象;
InputManager里有一个对象EventHub;
同时InputManager里面又开启了两个线程:
InputReaderThread
:不断去读取EventHub里的事件;有事件时把数据封装后添加到队列,立马从队列里读取交给InputDispatcher
进行分发;
InputDispatcherThread:InputDispatcher
里面保存了wms中所有的window信息(wms会将window信息实时更新到InputDispatcher
中),InputDispatcher就可以将事件分发给对应合适的window;
App进程中的ViewRootImpl和SystemServer中的IMS通过socketpair通信,因为事件产生的非常快且非常多使用binder通信不适合
在ViewRootImpl
中setView后new了一个监听FD文件的回调,new WindowInputEventReceiver();
在回调中,底层使用epoll_ctl()
函数监听FD是否变化,有变化则会回调至java层,dispatchInputEvent();
这里就是Activity-》Viewgroup->View的事件分发前置;
底层事件信号传递总结:
inotify()
和epoll机制的对象EventHub,来监控dev/input文件夹下面的事件信号文件;和
InputDispatherThread;`InputReaderThread
中开启循环,对EventHub对象进行getEvent();
getEvent()
中有epoll_wait;
相当于wait-notif机制;唤醒的触发点时dev/input下的文件被改变;InputReaderThread
将dev/input文件夹下面的事件信号文件数据进行 提取、封装,然后交给InputDispatherThread;
InputDispatherThread
最终选择到对应的ViewRootImpl(window)
进行分发数据;ViewRootImpl
中对于Channel连接的文件进行监控(epoll_ctr),从而是上层接收到touch信号;主角:ViewRootImpl、Choreographer、Surfaceflinfer
WMS扮演了什么角色?
作为协调者,协调view布局,绘制;
activity.attach()
时,创建一个窗体对象PhoneWindowWindowManagerImpl
对象,作为WMS在app中的代表;WindowManagerImpl
对象中的(mGlobal)WindowManagerGlobal
专门和WMS通信,在mGlobal里面获取了到了WMS的Binder:getWindowSession()->WMS::openSession();
setContentView()
PhoneWindow.setContentView(resouseID)
mContentParent
:官方主题布局中提供给用户装载布局的容器:id为content;mLayoutInflater.inflater(resouseID,mContentParent)
:mContentParent
加载用户的根布局;ps:这里递归调用,若嵌套层级太多,会导致栈溢出;因为递归调用不会释放栈;
ViewRootImpl 单例,管理所有View的绘制策略;
注意onCreate.setContentView
后view数据已解析并实例化了;
mGlobal.addView(view)
ViewRootImpl root=new ViewRootImpl()
:root.setView(view);
requestLayout()
requestLayout()
请求绘制,编舞者出场帧速率: CPU/GPU出图速率;
刷新率: 屏幕刷新速率;
Vsync: 垂直同步绘制信号; 因可能硬件帧速率和刷新率不一致,用来同步刷新的问题;
Choreographer编舞者: 负责管理帧率节奏;
Looper.myLooper==mLooper
判断是否是主线程,是的话去调同步绘制信号,不是的话发送消息,走主线程去调同步绘制信号ViewRootImpl.performTraversals()
真正的绘制: ViewRootImpl.performTraversals()
relayoutWindow()
:performMeasure(对应view的onMeasure)、performLayout(onLayout)、performDraw(onDraw);
在performDraw()
中:
简单版总结: Activity.setContentView(R.layout.resId)
:
解析xml并实例化;
phoneWindow.setContentView(resId)
mLayoutInflater.inflate(resId,mContentParent)
:mContentParent;
绘制发生时间: 在AMS回调ActivityThread中的handleResumeActivity
时,也就是Resume时,而不是onCreate()
;
requestLayout()
requestLayout()
中依次调用:performMeasure()、performLayout()、performDraw()
Android Framework 学习手册:https://qr18.cn/AQpN4J
1.Handler 机制实现原理部分:
2.Binder 原理
3.Zygote
4.AMS源码分析
6.深入PMS源码
7.WMS
8.……
下一篇:六、JDBC操作数据库