从手机启动到View显示
2021-01-19 本文已影响0人
zgfei
Android系统启动流程
Android系统启动流程:
init进程:init是所有Linux程序的起点,是Zygote的父进程。解析init.rc文件孵化出Zygote进程
Zygote进程:Zygote是所有Java进程的父进程,所有的APP进程都是由Zygote进程fork生成的。
SystemServer进程:SystemServer是Zygote孵化的第一个进程。SystemServer负责启动和管理整个Java Framework,包含AMS、PMS(PackageManagerService)等服务
Launcher:Zygote进程孵化的第一个APP进程
1. 启动电源以及系统启动
当电源按下时【引导芯片】代码开始从【预定义】的地方(固化在ROM)开始执行。加载【引导程序BootLoader】到RAM,然后执行。
2. 引导程序BootLoader
【引导程序BootLoader】是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。
3、Linux内核启动
内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置,它首先在系统文件中寻找【init.rc】文件,
并启动【init进程】
4. init进程启动
初始化和启动属性服务,并且启动【Zygote进程】
5. Zygote进程启动
创建【JavaVM】并为JavaVM注册JNI,创建服务端Socket,OS层采用Socket进行IPC通信,启动【SystemServer进程】。
6. SystemServer进程启动
启动【Binder线程池】和【SystemServiceManager】,并且启动各种系统服务。
7. Launcher启动
被【SystemServer进程】启动的【ActivityManagerService】会启动【Launcher】,【Launcher】启动后会将已安装应用的快捷图标显示到界面上。
Activity启动流程
Activity
ActivityThread
运行在UI线程,APP的真正入口。一个ActivityThread对应于一个进程,每个应用程序的入口是该类中的main()函数
H:Handler
APP进程的跨线程通信。ApplicationThread接收AMS的消息后,通过H传递到APP进程。
ActivityManager(AM)
ActivityManagerNative(低版本)(AMN)
app进程通过ActivityManager.getService() 或者 ActivityManagerNative.getDefault() 获取 IActivityManager 来调用系统进程AMS中的方法。
ActivityManagerNative运行在Server端,实现了Binder类,具体功能有子类AMS实现。
IActivityManager
ActivityManagerService在app进程的binder代理对象,抽象出跨进程通信需要实现的功能。
ActivityManagerService(AMS)
运行在system_server中,AMN的子类,负责管理四大组件和进程,包括生命周期和状态切换。
ActivityManagerProxy(AMP)
AMS的Client端代理,AMP和AMS通过binder通信
Instrumentation
仪表盘,负责调用Activity和Application生命周期。该类用于具体操作某个Activity的功能,单向调用AMS以及统计、测量该应用程序的所有开销。
一个Instrumentation类对应于一个进程。每个Activity内部都有一个该Instrumentation对象的引用。
ActivityStack
Activity在AMS的栈管理,用来记录以及启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
ActivitySupervisor
管理Activity任务栈
ActivityStackSupervisor
负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。
其中,mHomeStack管理的是Launcher相关的Activity栈;
mFocusedStack管理的是当前显示在前台Activity的Activity栈;
mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。
Application
ApplicationThread(AT)
ActivityThread的内部类,是ApplicationThreadProxy的具体实现,用于接受从AMS传递过来的消息。
ApplicationThreadProxy(ATP)
ApplicationThread在服务端的代理。AMS通过该代理与ActivityThread进行通信。
Activity启动流程:
a、Launcher启动Activity
1、Launcher通知AMS要启动新的Activity(Launcher进程中)
2、AMS先校验一下Activity的正确性,如果正确的话,会暂存一下Activity的信息。然后,AMS通知Launcher进程pause Activity(AMS进程)
3、Launcher pause Activity,并通知AMS已经paused(Launcher进程)
4、AMS检查Activity所在进程是否存在(AMS进程)
如果存在,直接通知这个进程,在该进程中启动Activity
不存在,会调用Process.start创建一个新进程
5、创建ActivityThread,执行一些初始化操作,并绑定Application。如果Application不存在,
会调用LoadedApk.makeApplication创建一个新的Application对象。之后进入Loop循环。(新创建的APP进程)
6、处理新的应用进程发出的创建进程完成的通信请求,并通知新应用进程启动目标Activity组件(AMS进程)
7、加载MainActivity类,调用onCreate声明周期方法(新创建的APP进程)
简化后:
1、请求执行启动Activity
2、AMS接收启动Activity的请求
3、执行栈顶Activity的onPause()
4、启动Activity所属的应用进程
5、执行启动Activity
6、栈顶Activity执行onStop()
b、其他Activity启动当前Activity(同一个进程内)
1、请求执行启动Activity
2、AMS接收启动Activity的请求
3、执行栈顶Activity的onPause()
4、执行启动Activity
5、栈顶Activity执行onStop()
c、整体方法调用流程(以这个为准)
1、Launcher通知AMS要启动新的Activity(Launcher进程中)
2、AMS先校验一下Activity的正确性,如果正确的话,会暂存一下Activity的信息。然后,AMS通知Launcher进程pause Activity(AMS进程)
3、Launcher pause Activity,并通知AMS已经paused(Launcher进程)
4、AMS检查Activity所在进程是否存在(AMS进程)
如果存在,直接通知这个进程,在该进程中启动Activity
不存在,会调用Process.start创建一个新进程
5、Process.start会创建一个新进程,并导入ActivityThread类,执行入口main()方法
6、main()中调用Looper.prepareMainLooper(),然后ActivityThread.attach(),最后Looper.loop()开始遍历消息
7、ActivityThread.attach()中会获取IActivityManager,然后执行IActivityManager.attachApplication(),将ApplicationThread与IActivityManager建立连接,
用于ApplicationThread和ActivityManagerService进行通信。
8、ActivityThread.attach()接着会初始化Instrumentation
9、ActivityManagerService发消息给ApplicationThread进行创建Activity,调用ApplicationThread.scheduleLaunchActivity()
10、通过Handler消息机制调用handleLaunchActivity()
注意:
1、startActivity()最后都会调用startActivityForResult()
2、AMS是通过socket与Zygote进程进行通信的。
3、AMS将执行创建Activity的通知告诉ActivityThread,然后通过反射机制创建出Activity对象,并执行Activity的onCreate()、onStart()、onResume()方法
通过mInstrumentation.newActivity()方法创建的Activity
Activity的生命周期方法是同Instrumentation类调用callActivityOn***()方法最终调用Activity的onCreate()等方法,这些方法会调用scheduleTraversals
调用时机为ActivityThread.performLaunchActivity()
4、ActivityThread执行完onResume()之后,会告诉AMS执行完onResume()了,然后执行栈顶Activity的onStop()
5、执行handleResumeActivity()(即onResume())方法之后系统开始获取DecorView,执行addView()方法,最终调用ViewRootImpl.performTraversals()
6、ActivityThread的main()方法是在生成一个新的APP进程过程中调用的,具体是通过与Zygote通信,之后通过RuntimeInit类采用反射的方式调用ActivityThread.main()方法
7、ActivityThread执行performLaunchActivity()时,执行activity.attach(),在activity.attach()方法里面创建的PhoneWindow
触发刷新的过程
ViewRootImpl、Window(PhoneWindow)、DecorView之间绑定和触发刷新的过程
DecorView
所有布局的根布局,包含TitleView(ActionBar)和ContentView,如果Activity设置FEATURE_NO_TITLE,则只包含ContentView一个子View
Window(PhoneWindow)
WindowManager
继承ViewManager,本身也是一个接口,负责管理Window,实际是管理PhoneWindow里面的DecorView,
最后的实现者是WindowManagerImpl,WindowManagerImpl没有直接实现操作View的相关方法,而是交给了WindowManagerGlobal来处理。
WindowManagerGlobal
单例类,
通过getWindowManagerService()来获取WindowManagerService的客户端实现对象IWindowManager
WindowManagerService
方法调用流程:
activityThread.handleLaunchActivity()
->activityThread.performLaunchActivity()
->activity.attach()->activity.onCreate()
->activityThread.handleResumeActivity()
->activityThread.performResumeActivity()
->activity.onResume()
->windowManager.addView()
0、ActivityThread.handleLaunchActivity()会调用activityThread.performLaunchActivity()
1、在activityThread.performLaunchActivity()中会调用mInstrumentation.newActivity()方法
2、mInstrumentation.newActivity()通过反射的方式创建一个新的Activity,
3、再在makeApplication()通过mActivityThread.mInstrumentation.newApplication()通过反射的方式创建一个Application
4、mActivityThread.mInstrumentation.newApplication()通过LoadedApk.getAppFactory()方法获取AppComponentFactory,工厂模式
5、然后makeApplication()中通过instrumentation.callApplicationOnCreate()调用application.onCreate()
6、activityThread.performLaunchActivity()中接着调用activity.attach()方法
7、activity.attach()方法里面创建了PhoneWindow
8、activityThread.performLaunchActivity()接着执行mInstrumentation.callActivityOnCreate()方法,执行了activity.onCreate()
9、在Activity在执行onCreate的时候会调用setContentView(),实际是getWindow().setContentView(),在这个方法中会去初始化DecorView以及TitleView和mContentParent,
并将TitleView和mContentParent添加到DecorView中
10、activityThread.handleResumeActivity()会调用activityThread.performResumeActivity(),在activityThread.performResumeActivity()中会调用activity.onResume(),
11、activityThread.handleResumeActivity()会先设置DecorView为INVISIBLE,然后会将DecorView通过windowManager.addView()绑定一起,然后再调用activity.makeVisible()显示DecorView
12、windowManager.addView()实际调用的WindowManagerImpl.addView()方法,WindowManagerImpl.addView()方法中调用WindowManagerGlobal.addView()方法
13、WindowManagerGlobal.addView()中会创建ViewRootImpl,然后通过ViewRootImpl.setView()将DecorView传入,然后调用view.assignParent(this),DecorView将mParent指向为ViewRootImpl
14、ViewRootImpl.setView()内部的执行过程为:
viewRootImp.setView()
->viewRootImp.requestLayout()
->viewRootImp.scheduleTraversals()
->viewRootImp.doTraversal()
->viewRootImp.performTraversals()
->进入View的绘制流程
View的绘制流程
View的绘制流程
View
在View调用相关刷新的方法时(invalidate()、requestLayout()等),会请求parent Layout对应的方法,View的父View为ViewGroup,
因此会调用ViewGroup对应的方法(通过直接调用或者遍历找到最终的父类),所有View的最终父类是ViewRootImpl,ViewRootImpl与
View进行绑定是在Activity的onResume()之后WindowManager.addView()中处理的。
ViewRootImpl ViewParent
所有View或者ViewGroup最终的父类,用于发起视图树的测量、布局、绘制的起点。所有View发起的刷新最终都会走到ViewRootImpl的
invalidateChild()、invalidateChildInParent()、requestLayout()、requestChildFocus()等方法,这些方法会调用scheduleTraversals()
方法。
scheduleTraversals():
1、设置mTraversalScheduled=true,表示当前帧已有刷新请求
2、发送同步消息屏障,用于消息队列能及时处理异步刷新消息
3、mChoreographer发送callbackType=CALLBACK_TRAVERSAL类型的屏幕刷新消息,并将TraversalRunnable传递到Choreographer中
Choreographer调用postCallback()发送callbackType=CALLBACK_TRAVERSAL类型的消息,同时在mCallbackQueues中对应于CALLBACK_TRAVERSAL的队列,
将TraversalRunnable保存到队列CallbackRecord的aciton中,mCallbackQueues队列保存的是CallbackRecord对象。
TraversalRunnable:ViewRootImpl内部类,用来接收Choreographer的回调
CallbackRecord:
链表的节点对象,保存有下一个链表的对象、dueTime、action(FrameCallback或Runnable)、token
然后判断如果是同一个线程中直接调用scheduleFrameLocked()方法,如果不是同一个线程,通过handler消息机制
切换到同一个线程调用scheduleFrameLocked()方法。
scheduleFrameLocked():
1、开启同步信号情况下,如果是同一个线程调用scheduleVsyncLocked()
2、开启同步信号情况下,不是同一个线程通过handler的消息机制切换线程调用scheduleVsyncLocked()
3、没有开启同步信号情况下,通过handler消息机制调用doFrame()方法。
scheduleVsyncLocked():mDisplayEventReceiver.scheduleVsync()通过native向底层注册监听屏幕vsync信号
当下一个屏幕刷新信号(vsync)到来
FrameDisplayEventReceiver
Choreographer内部类,继承自DisplayEventReceiver并实现了Runnable接口,本身就是一个Runnable
用于接收底层屏幕vsync信号的回调,当接收到vsync信号后,会回调onVsync()方法,然后将自己作为一个Runnable通过handler消息发送出去,最终会调用run()方法。
在run()方法中调用doFrame()方法
doFrame():
会依次调用doCallBacks()方法来执行对应的callbackType类型的回调
doCallBacks():
从mCallbackQueues队列中取出对应的callbackType的CallbackRecord,然后执行CallbackRecord.run()方法,最后会执行CallbackRecord里面action.run()
即执行的就是FrameCallback或Runnable的run()方法。
因为callbackType=CALLBACK_TRAVERSAL通过postCallback()方法保存的action是TraversalRunnable对象,因此会调用TraversalRunnable.run()
TraversalRunnable.run(): 会执行doTraversal()方法
doTraversal():
1、设置mTraversalScheduled = false,表示当前帧已经结束,可以接收下一帧的请求
2、移除同步消息屏障,用于主线程可以处理其他同步消息
3、调用performTraversals()方法
performTraversals():计算是否需要重新进行测量、布局、绘制,从上往下遍历视图树进行刷新布局
1、performMeasure()
2、performLayout()
3、performDraw()
Choreographer:协调动画、输入和绘图的计时
1、向底层注册vsync信号的监听
2、接收底层的vsync信号,然后分发给ViewRootImpl
3、监听帧
SurfaceFlinger
底层vsync信号的实现