[TOC]
从四个视角理解android activity启动模式
操作系统角度,Task是什么
用户的角度
学东西,要总体来学,要以架构师角度来学东西
一开始学,都是学习4大组件
task是可以跨应用的, app是静态的,task的动态的,
task是属于android操作系统的
android service有任务栈吗,或者说service怎么存放的
新建,startActivity
要从结构上去学习,就会
静态的fragment和动态的fragment
如果activity启动不成功,就不会执行上个界面,onstop
onPause()不能做耗时操作,影响启动速度
standard不是每次都100%新建, launch启动的时候,如果已经存在了,就不会再创建了。
flag = 0x10200000
每个页面展示不同的数据
newTask
affinity 就是新task名字 affinity 要和newtask标志一起使用
有没有拉起进程的
管道机制
bander机制,binder就跟快递小哥一样,
用户放入到内存空间, copy_from_user 第一次
然后 copy_to_user
这是传统的
binder传输数据:
服务端的一个空间,内核空间都是 虚拟空间
实际操作是物理空间,mmap 内存,内存映射
就是数据放到内存,然后内存映射,去取,就是一次拷贝
共享内存是 三个共享化,
binder两个共享
c/s架构的,易用性高; 控制复杂
共享内存,在同一个空间,需要同步机制去处理,同步的开销大
同步延迟+内存开销
mmap 资料memory mapping
binder 安全性。 pid,进程的id,依赖上层协议,不安全,
相当于造假身份证去干坏事,就是用进程id去欺骗
访问接入点是开发的,不安全
为每个app分配UID,同时支持实名和匿名,
加上bean类,要求导包
为什么binderservice就能绑定服务,
客户端如何获取到AIDL的遥控器(句柄)的
通过这个遥控器是如何调到服务端的呢
服务端又是如何
每个服务要有一个aidl与之对应
发送数据proxy 发送数据
接收数据 stub 是用来接收数据的
或aidl对象的方法
LeoAidl.Stub.asInterface(binder) — 》 就会拿到 proxy的对象
服务端,一进来就会初始化,new了一个stub
如果进过判断是因为判断是不是同一个进程
_data 用来存储发送数据,就是调用方法的出入参数
_reply //服务端返回的数据
//就会把客户端线程挂起来,知道服务端返回结果
mRemote.transact()
flag 0 -
Flag 1 -> 客户端给服务端,服务端不能进行返回
transact后就到binder了 transact 到C里面去了, 可以去查查
服务端, onTransact方法接收处理
binder机制,看framework的源码有一定的理解
c端和 s端是如何捆绑再一起的
getSystemService
闹钟服务,通话服务等, 实际上也是跨进程的,
服务好比房子一样,
ServiceManager(相当于android中的间接),其实也是进程间的通信
通过proxy,
comtextImpl里面
bindService - > ContextImpl#bindServiceCommon
-> ActivityManagerNative.getdDefalut()-》proxy对象
ActivityManagerNative就是 == stub
IActivityManager= ILeoAidl 接口
getService() 获取了 IBinder, 然后返回proxy
我的理解是生成的单独为这个类服务的,所以用内部类,而谷歌的这个是通用的所以单独是个类
调用的是正在的服务
调用到了 activityManagerService。java
调用到真正的服务
ActivityManagerService#bindServiceLocked
bringupServiceLocked
1 | requestServiceBindingLocked 猜 |
1.进程B,整个进程没有启动
2.进程B启动了,service没有创建出来
2.启动了,也创建了,未绑定,onBInde
4.启动了,也创间了,也绑定了,onbinde
、、app
ActiveServices.java
每创建一个进程,都会有个进程,app.thread ,就是activityTHread,
如果启动了,app.thread肯定不为空
23的代码
ActivityThread的
handleCreateService, 通过反射, 创建了服务
binder只能绑定一次,创建一次,如果找到了,可以直接使用,
app没有创建
startProcesslocked
process.create
android是个消息驱动的系统
handleCreateService
handleBindService
课后自己手写,实现aidl
a 调用系统服务
ActivityManagerNative -> stub - > ontrnsact
ActivityManagerProxy -> proxy -> trnsact
ActivityManagerSerivce-> stub的实现类
IActivityManager -> AIDL接口
大型登录架构实现
支付宝纳入海量应用
四大主键,和activity启动流程,都是用了binder机制
3358434706
Clinet : 通过 asInterface()-> proxy对象, -> proxy# transact() -> 进行传递,到服务端的 onTransact上-> 因为stub是个抽象方法,被服务端的binder实现了,所以最后调用,服务端的binder实现aidl接口的方法->最后沿路返回
因为,两边的接口都是一模一样的,所以调取的时候传 个 1,2…n作为方法的标识
app每创建一个进程,都会启动一个 activityThread吗。怎么去验证一下。
activityManagerService:
android 7.0:
基于liunx内核开发的,
看两本liunx的相关书籍, liunx内核设计与实现, 深入理解liunx
进程管理,进程调度, io流操作, epoll, 底层读写靠的是这个
Init.rc
用户空间和内核空间
之间通信靠系统调用,创建android的进程鼻祖,zygote
然后拉起SystemServer,
加载系统预加载的类,加载服务
ams属于引导服务,然后其他服务。launch服务,启动
引导服务,
核心服务,
然后里面启动了ams -> launcher启动
其他服务
整体概念讲
rpc,rmi,socket和管道
ipc, socket, 管道, 型号量,binder, 共享内存
binder驱动,在内核内存中,通过binder,然后传到另外一个进程
SystemtServer里面有个binder列表
SystemtServer的binder地址是固定的,然后拿着这个binder,跟其他binder
进行通信
0号驱动,
serviceManager存放地址,
类似于 dns 或 路由表一样的东西,找到serviceManager就能找到所需要的binder
asInterface 判断是否在同一个进程, 同进程不走binder了
生成的代码,像动态代理
客户端不能直接访问对象,所以需要代理,
然后都实现共同的接口
android aidl的原理
android 为什么要使用binder,
稳定性,C/S模式,客户端挂了,不影响服务端。
安全考虑:传统的传统的不可靠, binder会调用进程,容易被中间者攻击
系统启动的时候,注册了各种,serviceManager,
通过binder驱动,然后服务端,ontrancsact,
LocalSocket,改变进程id等,zygote,复制了一个分身
launch启动应用,
ams socket与zygote进程通信, 然后zygote创建ActivityThread
activity启动
状态设计模式
AMS家族
xx record
android进程模型与优先级
可见进程(对话框弹窗),服务进程(后台进行播放,音乐播放),后台进程(stop状态了),空进程(加快下次创建数据)
startActivity的时序图
hook插件话
Instra ActivityThread, AMS
hook Activity 的启动
未注册的activity,
Activity的
ActivityThread
AMS的
applicationThread对象,什么时候被创建的