activity生命周期与task启动方式

[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对象,什么时候被创建的