男儿欲遂平生志,五经勤向窗前读。这篇文章主要讲述Android 启动绘制显示过程相关的知识,希望能为你提供帮助。
Activity 启动过程:
startActivity()->
Instrumentation.execStartActivity()->
Binder->
ActivityManagerService->
Zygote fork app ->
Binder ->
ApplicationThread.scheduleLaunchActivity() - >
Handler ->
ActivityThread.handleLaunchActivity() ->
performLauncherActivity ->
Instrumentation create Activity ->
设置 application ,创建 ContextImpl,调用 attatch 方法,调用 Instrumentation 的 callActivityOnCreate->
Activity.onCreate()
->
setContentView() ->
PhoneWindow.setContentView() ->
DecorView . setContentView();
->
handleLaunchActivity()->
handleResumeActivity()->
Instrumentation.callActivityonResume()->
Activity.onResume();
->
handleLaunchActivity() ->
Activity.makeVisibile() ;
->
Activity.makeVisibile()->
WindowManager.addView() - >
WindowManagerImpl.addView()->
WindowManagerGlobal.addView()->
ViewRootImpl.setView() ->
requestLayout ->
scheduleTranversals()->
Runable->
doTranversals()->
performTranversales()->
measure()->
layout()->
draw();
涉及到进程间通讯 Binder
涉及到线程间通讯 Handler
涉及到 View 的绘制流程
关键类还有 Window, PhoneWindow ,WindowManager ,WindowManagerImpl, WindowManagerGlobal, ViewRootImpl, DecorView
启动过程
- 不论是通过从桌面上点击还是通过 startActivity 都会调用到 startActivitForResult 方法,然后会调用 Instrumentation 的方法, Instrumentation 是应用和系统服务的一个桥梁),Instrumentation 的方法会通过 Binder 方式调用 ActivityManagerService 的 startActivity 方法。同时会把 ApplicationThread 这个 Binder 传入给 ActivityManangerService 。这样 ActivityManangerService 就可以通过 ApplicaitonThread 与 ActivityThread 进行通讯了。
- ActivityManagerService 收到了 startActivity ,会向 zygote 进程发送创建进程的请求
- Zygote 创建子进程成功,即 app 进程
- 然后经过一系列的准备,会通过 Binder 方式调用 ApplicationThread , 通过 Handler 调用 ActivityThread 的 handleLaunchActivity 。在 handleLaunchActivity 中调用 performLaunchActivity 这个方法,在这个方法中会通过 Instumention 使用 classloader 创建 Activity 对象,然后初始化 application ,ContextImpl ,设置主题,调用 attatch 方法,然后通过调用 Instrumentation 来调用 activity 的生命周期方法 onCreate()。 在 ActivityThread 的 handleLaunchActivity 的方法中,在调用 performLaunchActivity以后 会继续调用 handleResumeActivity 方法,该方法会通过 Instrumentation 调用 activity 的生命周期方法 onResume().
- 在启动过程中,通过 ActivityThread 的 handlerLauncherActivity 方法,会调用到 activity 的生命周期方法 onCreate()。在 onCreate() 中调用 setContentView() 方法,设置布局文件,该方法会调用 getWindow.setContentView() 方法, getWindow() 拿到的是 window 对象,Window 的实现类是 PhoneWindow ,所以调用的是 PhoneWindow 的 setContentView() 方法,在 PhoneWindow 的 setContentView() 中会调用 installDecorView() 方法来创建 DecorView ,然后通过 layoutinflate 的 inflate 方法把布局文件加载到 DecorView 的 ContentView 中,虽然已经把布局添加到了 Decorview ,但是还没有显示出来。
- 在启动过程中,handlerLauncherActivity() 方法中,在调用 performLauncherActivity 方法以后,会调用 handleResumeActivity 方法,该方法会调用 activity 的 makeVisible() 方法,使 DecorView 通过 WindowManager 加载到屏幕上显示。那布局怎么绘制出来的呢,看下面。
- 在 调用 activity 的 makeVisible() 方法后,把 DecorView 通过 addView 方法添加到了 WindowManager 中,WindowManager 的实现类是 WindowManagerImpl ,WindowManagerImpl 的 addView 方法调用了 WindowManagerGlobal 的 addView 方法,在 WindowManagerGlobal 的 addView 方法中,初始化了 ViewRootImpl 类,并通过 setView 方法把 View 和参数注入,然后调用了 requestLayout 方法, requestLayout 会调用 scheduleTraversal 然后调用一系列方法以后,会调用 measure ,layout ,draw 方法,完成布局的测量,布局和绘画。以上就完成了布局的绘制,这时手机上就显示出来了设置的布局。
ViewGroup-------------------------------> View
performMeasure -> measuer -> onMeasure -> measure
performLayout -> layout -> onLayout -> layout
performDraw -> draw -> onDraw -> draw
- Instrumentation: 应用程序与系统服务的桥梁。为什么是桥梁呢,首先是 startActivity ,会通过 Instrumentation 的 execStartActivity 方法调用 ActivityManagerService 的方法。然后在 acitivty 的生命周期方法的调用,都是由 Instrumentation 调用的。
推荐阅读
- man -k :nothing appropriate.
- android保持服务不休眠(持续运行)以及唤醒屏幕的方法
- [转] Android中的设计模式-备忘录模式
- appium移动端自动化测试环境搭建windows-appium-android
- Android开发环境部署
- Android ViewPager的简单使用
- Android之布局LinearLayout
- Android集成讯飞语音百度语音阿里语音识别
- fcgiapp