Android系统启动流程分析(核心框架、大致流程分析版)


阅读前言:欢迎评论、一起交流学习,如有错误及不足,望海涵,如这篇文章对您有用,麻烦帮忙点点小蛋糕,谢谢您的喜欢~


1.电源开机BootLoder加载到内存中

2.BootLoder将Linux系统拉动

(1)Linux系统内内核配置中找到init.rc文件,通过init方法开启进程

3.init进程初始化zygote进程

(1)zygote进程去创建JVM,JNI方法注册

4.zygote进程开启SystemServer.java(Java层入口)

(1)开启 Binder线程池

(2)开启SystemServiceManager

5.利用zygote、SystemServer、SystemServiceManager三者合作共同开启AMS、WMS、PMS、CS等80多个服务

6.通过MS将桌面应用程序启动,将Launcher.java启动,桌面就会启动  

7.点击桌面图标Launcher.java会走onClick方法

onClick()方法可以进行操作,比如设置用户权限或密码才能打开应用

如何修改代码?

a.room定制

b.Hook(无法直接修改)

c.改class文件(无法直接修改)

onClick()方法------(进入)----->

          startActivitySafely()-----(进入)---->

                      startActivity()根据是否要启动动画分为冷启动和热启动

8.冷启动

startActivity()------(进入)----->

          startActivityForResult()---(进入)--->

               Instrumentation.execStartActivity()---->

                              通过Binder机制这里会和AMS(Framework层)交互

9.热启动

通过Binder机制,通过AMS提供的BInder接口访问AMS,同时会把自己的Binder接口传送到AMS中去

10.AMS通过if---else语句区分冷启动还是热启动

如果是冷启动:

zygote--------fork()------------>ActivityThread

如果是热启动:

通过handler消息机制最后到 ActivityThread

11.冷/热启动都会进入ActivityThread

main()(APP层入口)------->

        thread.attach(false,startSeq)------->

                final IActivityManager mgr = ActivtyMAnager.getService()

                mgr.attachApplication(mAppThread,startSeq) 这里是进程间通信,Binder方式,与AMS交互,通过远端进程做事

......与framework层交互跑一点代码

handleBindApplication()-------->(处理、执行application)

        Applicaton app;

        app = data.info.makeApplication();   application初始化,通过make方法完成

        mInstrument.callApplicationOnCreate()-------->

                app.oncreate()

......与framework层交互跑一点代码

performLaunchActivity()-------->(处理、执行activity)

        Activity activity = null;

        activity = mInstrumentation.newActivity()    (将Activity绑定到WMS上)

        mInstrumentation.callActivityOnCreate()     (走至程序员写的代码)

12.进入Activity的setContentView()

phoneWindow类中——setContentView()方法


先总结,后解释拆分:

setContentView()-------->

        LayoutInflater.inflate() -----把XML布局文件转化成对应的视图对象---->

                inflate()-----attachToRoot参数的含义----->

                        createViewFromTag()----进行View的初始化---->

                        root.addView()--------保证View不会重复添加--------->

                                addview()--------->

                                        addViewInner()------->

                                rInflateChildren(parser, temp, attrs, true) ----布局嵌套能写多少层--->

                                        rinflate()----ViewGroup又会 rInflateChildren()---->


setContentView()-------->

        LayoutInflater.inflate() --------->

(把XML布局文件、标签,转化成对应的视图对象、对象,实现灵活的UI 设计)

                inflate()---------->

                有3个inflate()方法,最后一个:

                inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)

                其中attachToRoot的含义为:(1)true:自定义的View (2)false:Framework层的核心控件   将程序员的代码和源码分离,用来区分系统和自定义

                        createViewFromTag() 进行View的初始化-------->

                                constructor = clazz.getConstructor(mConstructorSignature);

                                final View view = constructor.newInstance(args);

                                static final Class<?>[] mConstructorSignature = new Class[] { Context.class, AttributeSet.class}; 

                                构造方法有这两个参数Context.class, AttributeSet.class,所以写自定义View或继承某一个View/ViewGroup,构造方法带两个参数的不能删除

                        root.addView() 保证View不会重复添加 ------->

                                addview()--------->

                                        addViewInner()------->

                                                if (child.getParent() != null) {
throw new IllegalStateException("The specified child already has a parent. " + "You must call removeView() on the child's parent first.");
} 如果父亲不为空,就会抛、出异常,告诉你已经添加过这个View了

布局嵌套能写多少层?

                inflate()----->

                        final View temp = createViewFromTag(root, name, inflaterContext, attrs); 走反射代码生成标签

                        rInflateChildren(parser, temp, attrs, true); 解析孩子-------->

                                rinflate()-------->

                                ((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) ----pull解析读取xml文件

                                如果是View直接添加

                                如果是ViewGroup:会走rInflateChildren(parser, view, attrs, true) 如果一直是ViewGroup会形成闭环 栈区中会有多层栈帧,造成栈溢出

        

        

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值