App启动过程导图

  1. 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求
  2. system_server进程接收到请求后,向zygote进程发送创建进程的请求
  3. Zygote进程fork出新的子进程,即App进程
  4. App进程,通过Binder IPC向sytem_server进程发起attachApplication请求
  5. system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求
  6. App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息
  7. 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法
  8. App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面

Android开机流程导图

BootLoader引导

当按开机键的时候,引导芯片开始从固化在ROM的预设代码开始执行,然后加载引导程序到RAM
BootLoader,又称为引导程序。它是在操作系统运行之前运行的一段程序
BootLoader负责初始化软件运行所需要的最小硬件环境,最后加载内核到内存

启动Kernel

这个入口的函数是start_kernel函数
start_kernel函数执行到最后调用了reset_init函数进行后续的初始化
start_kernel最终启动用户空间的init程序

启动Android

当初始化内核之后,init进程负责解析init.rc配置文件, 就会启动一个相当重要的祖先进程,也就是init进程,在Linux中所有的进程都是由init进程直接或间接fork出来的

* /system/bin/app_process_Zygote服务启动的进程名
* --start-system-server 表明Zygote启动完成后,需要启动System_Server进程
* socket zygote stream 666在Zygote启动时,创建一个权限为666的socket。此socket用来请求zygote创建新进程
* socket的fd保存在名称为"ANDROID_SOCKET_zygote"的环境变量中

init进程负责创建系统中最关键的几个核心daemon(守护)进程,尤其是zygote和System_Server进程

1. zygote进程 android启动的第一个Dalvik 虚拟机,它将负责启动Java世界的进程
2. zygote虚拟机启动子进程system_server,同时也可以看出zygote中定义了一个Socket,绑定666端口,用于接收ActivityManagerService启动应用程序的请求
3. System_Server进程  Binder通信的基础,它还提供了property service(属性服务),类似于windows系统的注册表服务
4. 系统里面重要的服务都是在这个进程里面开启的,例如AMS, WindowsManager, PackageManagerService等等都是由这个System_Server fork出来的
5. 在System_Server进程开启的时候,就会初始化ActivityManagerService 。同时,会加载本地系统的服务库,调用createSystemContext()创建系统上下文,创建ActivityThread及开启各种服务等等
6. system_server中开启了核心系统服务,并将系统服务添加到ServiceManager中,然后系统进入SystemReady状态

启动Home Activity

  1. 在systemReady状态,ActivityManagerService会与zygote的Socket通信,请求启动Home
  2. zygote收到AMS的连接请求后,执行runSelectLoopMode处理请求
  3. zygote处理请求会通过forkAndSpecialize启动新的应用进程,并最终启动Home
概况
1. 系统加电,执行bootloader。Bootloader负责初始化软件运行的最小硬件环境,最后加载内核到内存
2. 内核加载到内存后,进入内核引导阶段,在内核引导的最后,调用start_kernel进入内核启动阶段。start_kernel最终启动用户空间的init程序
3. init负责解析init.rc配置文件,开启系统守护进程。2个最重要的守护进程是zygote进程和serverManager进程。zygote是android启动的第一个Dalvik虚拟机,ServiceManager服务是Binder通信的基础
4. zygote虚拟机启动子进程system_server,在system_server中启动了核心系统服务,并将系统服务添加到ServiceManager中,然后系统进入SystemReady状态
5. 在SystemReady状态,ActivityManagerService与zygote中的socket通信,通过zygote启动home应用,进入系统界面* 从步骤3开始, init启动后,上层的实现
1. init启动的核心Daemon服务包括Android的第一个Dalvik虚拟机Zygote
2. zygote定义一个socket,用于接受ActivityManangerService启动应用的请求
3. zygote通过fork系统调用创建system_server进程
4. 在system_server进程中,将会启动系统核心服务以及其他服务
5. 系统服务启动后会注册到ServiceManager中,用于Binder通信
6. ActivityManagerService进入systemReady状态
7. 在systemReady状态,ActivityManangerService会与zygote的Socket通信,请求启动Home
8. zygote收到AMS的连接请求后,执行runSelectLoopMode处理请求
9. zygote处理请求会通过forkAndSpecialize启动新的应用进程,并最终启动Home

Handler机制与底层实现原理

概念:

Message - Message代表一个行为what或者一串动作Runnable, 每一个消息在加入消息队列时,都有明确的目标Handler
ThreadLocal - 线程本地存储区(Thread Local Storage,简称为TLS),每个线程都有自己的私有的本地存储区域,不同线程之间彼此不能访问对方的TLS区域。ThreadLocal的作用是提供线程内的局部变量TLS,这种变量在线程的生命周期内起作用,每一个线程有他自己所属的值(线程隔离)
MessageQueue (C层与Java层都有实现) - 以队列的形式对外提供插入和删除的工作, 其内部结构是以双向链表的形式存储消息的
Looper (C层与Java层都有实现) - Looper是循环的意思,它负责从消息队列中循环的取出消息然后把消息交给Handler处理
Handler - 消息的真正处理者, 具备获取消息、发送消息、处理消息、移除消息等功能

普通的线程是没有looper的,如果需要looper对象,那么必须要先调用Looper.prepare方法,而且一个线程只能有一个looper
Handler是如何完成跨线程通信的

* Android中采用的是Linux中的管道通信
* 关于管道,简单来说,管道就是一个文件
* 在管道的两端,分别是两个打开文件文件描述符,这两个打开文件描述符都是对应同一个文件,其中一个是用来读的,别一个是用来写的
* 消息队列创建时,会调用JNI函数,初始化NativeMessageQueue对象。NativeMessageQueue则会初始化Looper对象
* Looper的作用就是,当Java层的消息队列中没有消息时,就使Android应用程序主线程进入等待状态,而当Java层的消息队列中来了新的消息后,就唤醒Android应用程序的主线程来处理这个消息

整个消息机制流程

Handler通过sendMessage()发送Message到MessageQueue队列
Looper通过loop(),不断提取出达到触发条件的Message,并将Message交给target来处理
经过dispatchMessage()后,交回给Handler的handleMessage()来进行相应地处理
将Message加入MessageQueue时,处往管道写入字符,可以会唤醒loop线程;如果MessageQueue中没有Message,并处于Idle状态,则会执行IdelHandler接口中的方法,往往用于做一些清理性地工作

ContentProvider原理

Android绘制原理

Activity的window组成,Activity内部有个Window成员,它的实例为PhoneWindow,PhoneWindow有个内部类是DecorView,这个DecorView就是存放布局文件的,里面有TitleActionBar和我们setContentView传入进去的layout布局文件

  1. Window类时一个抽象类,提供绘制窗口的API
  2. PhoneWindow是继承Window的一个具体的类,该类内部包含了一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View
  3. DecorView继承FrameLayout,里面id=content的就是我们传入的布局视图
  4. ContentView必须是一个ViewGroup
  5. ViewGroup 开始递归执行以下逻辑进行绘制
+ measure, 递归测量view的大小。有3种测量模式- MeasureSpec.EXACTLY表示确定大小- MeasureSpec.AT_MOST表示最大大小- MeasureSpec.UNSPECIFIED不确定
+ layout,递归布局view的位置
+ draw,递归绘制view- ViewRootImpl中的代码会创建一个Canvas对象,然后调用View的draw()方法来执行具体的绘制

AsyncTask源码分析

Binder机制及底层实现

进程空间分配

  1. 进程间,用户空间的数据不可共享,所以用户空间 = 不可共享空间
  2. 进程间,内核空间的数据可共享,所以内核空间 = 可共享空间
  3. 进程内用户与内核进行交互称为系统调用

Binder跨进程通信(IPC)的原理

  1. 先通过进程间的内核空间进行数据交互
  2. 再通过进程内的用户空间&内核空间进行数据交互,从而实现进程间的用户空间的数据交互
  3. 而Binder,就是充当连接两个进程(内核空间)的通道

使用步骤:
注册服务

* Server进程向Binder驱动发起服务注册请求
* Binder驱动将注册请求转发给ServiceManager进程
* ServiceManager进程添加该服务
* 此时ServiceManager进程拥有该服务信息

获取服务

* Client向Binder驱动发起获取服务的请求,传递要获取的服务名称(service name)
* Binder驱动将该请求转发给ServiceManager进程
* ServiceManager查找到Client需要的Server对应的服务信息
* 通过Binder驱动将上述服务信息返回给Client进程
* 此时client进程与server进程已经建立了连接

使用服务

* Client进程将参数数据发到Server进程1. client 进程将需要的传送的数据放到client进程的共享内存;(当前线程被挂起)2. Binder驱动从client的共享内存中读取数据,并根据ServiceManager进程里面的Server信息找到对应的Server进程3. Binder驱动将数据copy到Server进程的共享内存里,并通知Server进程解包
* Server进程根据Client进程要求,调用目标方法1. 接到Binder驱动通知后,Server进程从线程池中取出线程,进行数据解包和调用目标方法2. 将最终方法结果写到自己的共享内存
* Server进程将目标方法的结果,返回给Client进程1. Binder驱动程序将Server进程的共享内存里面的数据(方法执行结果) copy 到client进程的共享内存2. 通知client进程获得返回结果(此时client进程之前被挂起的线程被重新唤醒)

Client进程、Server进程 & Service Manager 进程之间的交互 都必须通过Binder驱动(使用 open 和 ioctl文件操作函数),而非直接交互
Client进程、Server进程 & Service Manager进程属于进程空间的用户空间,不可进行进程间交互
Binder驱动 属于 进程空间的 内核空间,可进行进程间 & 进程内交互

Binder驱动 & Service Manager进程 属于 Android基础架构(即系统已经实现好了);而Client 进程 和 Server 进程 属于Android应用层(需要开发者自己实现)

ActivityThread工作原理

Window 、WMS的工作原理

ThreadLocal原理,实现及如何保证Local属性

每个Thread维护一个ThreadLocalMap映射表,这个映射表的key是ThreadLocal实例本身,value是真正需要存储的Object

Android线程有没有上限

android本身就是linux系统 所以查看命令和linux一样

Android内存限制

dalvik.vm.heapstartsize 表示 初始内存大小是8m
dalvik.vm.heapgrowthlimit 表示标准内存大小是96m 一般应用都是这么大
dalvik.vm.heapsize 表示 在manifest配置文件中application标签下配置 android:largeHeap="true"时的内存大小

Android apk大小限制

apk安装包大小理论上没有限制。但是各个应用商店为了有大小限制google play 要求小于50M , 扩展包可以扩展到2g
压测: 800M的apk是没问题的只是安装的时间比较长。1.6G的apk包则把手机弄死机

线程池有没有上限

ThreadPoolExecutor构造函数的maximumPoolSize决定

AndroidToast原理分析

Art和Dalvik对比

ART 的机制与 Dalvik 不同。在Dalvik下,应用每次运行的时候,字节码都需要通过即时编译器(just in time ,JIT)转换为机器码,这会拖慢应用的运行效率,而在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。这个过程叫做预编译(AOT,Ahead-Of-Time)。这样的话,应用的启动(首次)和执行都会变得更加快速。

BlockCanaryEx原理

即整个应用的主线程,只有这一个looper,不管有多少handler,最后都会回到这里

public static void loop() {...for (;;) {...// This must be in a local variable, in case a UI event sets the loggerPrinter logging = me.mLogging;if (logging != null) {logging.println(">>>>> Dispatching to " + msg.target + " " +msg.callback + ": " + msg.what);}msg.target.dispatchMessage(msg);if (logging != null) {logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);}...}
}

设置Printer对象,判断是否超过预期时间,notifyLog

Android GC探究

虚拟机原理,如何自己设计一个虚拟机(内存管理,类加载,双亲委派)

对于Activity 的 onCreate 等生命周期的函数为什么不会因为 Looper.loop()里的死循环卡死而永无机会执行

View 的绘制到底是怎样完成的,它又为什么不会因为 Looper.loop()里的死循环卡死而永无机会刷新

子线程真的不能刷新UI

Android Framework内部启动流程相关推荐

  1. 结合源码探讨Android系统的启动流程

    结合源码探讨Android系统的启动流程 由于本人能力有限,所考虑或者疏忽错漏的地方或多或少应该存在.同时,Android从启动过程开始,实际上就涉及多个技术难点和多种通信机制的知识点. 基于上面两个 ...

  2. Android Q 开机启动流程

    https://www.it610.com/article/1304931662924124160.htm Android Q 开机启动流程 开机启动概述: step 1: 上电开机 长按power键 ...

  3. Android系统的启动流程简要分析

    这是我结合网上的资料以及自己分析android4.4的源码整理的笔记,对整个安卓系统的流程启动进行了梳理,很多细节并未展开,只是简要的进行了介绍. 一.Android系统的架构介绍 Android的整 ...

  4. c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...

    在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析​zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...

  5. (四十四)Android O WiFi启动流程梳理

    前言:最近又重新拿起来WiFi模块,从WiFi 各个流程梳理开始复习一下. 参考博客:https://blog.csdn.net/csdn_of_coder/article/details/51541 ...

  6. (七十)Android O Service启动流程梳理——bindService

    前言:最近在处理anr问题的时候迫切需要搞清楚service的启动流程,抽时间梳理一下. 1.service启动简述 service启动分三种,比较简单的就是startService,Android ...

  7. Android系统 lk启动流程简析

    本篇文章是对初步学习Android系统lk启动流程的一个大致简介.方便掌握lk启动流程的大致框架,具体细节后续再进行更新 1. 前言 需要了解的文件类型: 1)编译LK的链接文件(.ld) 2)汇编文 ...

  8. Android开机向导启动流程分析

    Android开机向导启动流程 首先来看Android启动流程: 1.Bootloader(系统启动加载器,将Linux加载到RAM): 2.Kernel 3.init进程 4.Zygote(Zygo ...

  9. Cocos2d-x3.3RC0的Android编译Activity启动流程分析

    http://www.itnose.net/detail/6142692.html 本文将从引擎源码Jni分析Cocos2d-x3.3RC0的Android Activity的启动流程,下面是详细分析 ...

最新文章

  1. 使用XML与远程服务器进行交互
  2. 为了OFFER,我加深学习队列,现在还一脸懵逼
  3. Spring 3.2矩阵变量是什么? - 第1部分
  4. js给标签添加属性和值_jquery节点属性
  5. 几位阿里朋友重写的Java并发编程,牛逼了
  6. java队列_java集合入门和深入学习(详解),看这篇就差不多了
  7. c#winform演练 ktv项目 实现上一曲和下一曲的播放功能
  8. 闩锁电流_IGBT——闩锁(Lanchup)效应
  9. 正则去除包裹的大括号
  10. zoom怎么解除静音_如何召开一场Zoom视频会议
  11. adb安装apk到智能TV上
  12. C++实现 利用前序序列和中序序列构建二叉树
  13. 【Web】CSS(No.18)Css经典案例(二)《畅销书排行榜》
  14. sql-server(模式创建)
  15. 命名空间“Microsoft”中不存在类型或命名空间名“AspNet”(是否缺少程序集引用?)
  16. android+video+自动播放源码,华为手机浏览器使用Video.js无法自动播放
  17. python美元和人民币双向兑换程序_Python:程序练习题(二)
  18. 【vue】Storage二次封装
  19. Java中双冒号(::)运算操作符
  20. 创业者该怎么快准狠抓住知识付费项目这个机会变现?

热门文章

  1. 尼葛洛庞帝:《数字化生存》
  2. 刚刚,正式宣布:再见,摩拜单车!
  3. B站腾讯纷纷选择Steam发行 海外平台能成为端游厂商的救命稻草吗
  4. 【Linux】在Ubuntu上安装和使用miniconda
  5. 阿米巴经营的核心要义
  6. PHP实现微信提现V3版本2022-5更新接口:商家转账到零钱
  7. 基于SpringBoot vue的茶叶商城平台源码和论文含支付宝沙箱支付
  8. 再说长恨歌的爱情主题
  9. Python网络编程socket
  10. 苹果系统和安卓系统的区别_MIUI12发布—安卓系统最接近苹果系统的一次