思考activity和service的进程和线程关系

最近学习binder通讯的时候,突然发现想到一个问题,一般startservice启动一个服务如果没有指定进程的时候,启动的service和activity会存在于同一个进程吗?service和activity是同一个线程吗?在启动过程中,如果需要,是怎么控制重启进程和线程的?


基于上面的问题,我决定翻翻activity和service的启动过程。
直接翻android O源码!先看源码然,然后写一个程序看看打印出对应的PID和TID验证阅读代码的正确性。


先看startActivity启动过程,因为这个部分网上很多资料,依据资料,只作简单过程分析,了解启动过程中进程的启动和分离。
ContextImpl.startActivity------>Instrumentation.execStartActivity--------->ActivityManager.getService().startActivity(10)---->

ActivityManagerService.startActivityAsUser------>ActivityStarter.startActivityMayWait----->*.startActivityLocked-->*.startActivity(看了一个ActivityRecord类,做什么的呢?)----->ActivityStarter.startActivityUnchecked---->ActivityStack.startActivityLocked---->ActivityStackSupervisor.resumeFocusedStackTopActivityLocked-->ActivityStack.resumeTopActivityUncheckedLocked-->ActivityStack.resumeTopActivityInnerLocked-->ActivityStackSupervisor.startSpecificActivityLocked----

ActivityStarter.startActivityUnchecked---->ActivityStarter.postStartActivityProcessing(socket消息发送完成后返回这里继续处理ams的逻辑)

ActivityStackSupervisor.startSpecificActivityLocked---->ActivityManagerService.startProcessLocked---->Process.start--->ZygoteProcess.start----->*.zygoteSendArgsAndGetResult(通过socket发生消息给zygote发送启动命令)---->ZygoteServer.runSelectLoop(接受socket消息)--->ZygoteConnection.runOnce---->Zygote.forkAndSpecialize---->ZygoteConnection.handleChildProc--->ZygoteInit.zygoteInit(初始化runtime虚拟机)------>RuntimeInit.applicationInit(启动activityhread主线程,这里可以看出app的进程启动的main函数在这里)----->*.invokeStaticMain---->ActivityThread.attach()------>ActivityManagerService.attachApplication--->ActivityStackSupervisor.attachApplicationLocked---->ActivityStackSupervisor.realStartActivityLocked--->IApplicationThread.scheduleLauncherActivity---->ActivityThread.sendMessage---->ActivityThread.H.sendMessage----->ActivityThread.H.handleMessage----->ActivityThread.handleLauncherActivity---->ActivityThread.performLauncherActivity---->Instrumentation.callActivityOnCreate---->Activity.onCreate--->ActivityThread.handleResumeActivity--->ActivityThread.performResumeActivity---->Activity.performResume---->Instrumentation.callActivityOnResume--->Activity.onResume---->ActivityManagerNative.getDefault().activityResumed(token) 





总结下:启动一个app包含多个进程交互,进程A,ams进程,zygote进程,目标启动进程B:
1.由A启动activity,由于activity由ams维护,由于启动新的activity,因此给ams服务处理多个activity切换的逻辑;(binder进程通信)
2.ams发现需要启动一个新的进程,维护好当前的activity stack后,通过socket发送消息给zygote进程,让zygote进程启动新进程(socket进程通信)
3.zygote启动了新进程,由新进程通过binder调用ams的attachApplication方法,将启动进程前保存的activity信息取出,用来启动activity,进入activity的生命周期,activity启动完成后,新的进程在mainthread中不断loop执行消息


参考信息:http://blog.csdn.net/qq_23547831/article/details/51224992
        http://blog.csdn.net/xutao20170209/article/details/61925689


service的启动:
ActiveServices.startServiceLocked---->startServiceInnerLocked--->bringUpServiceLocked


bringUpServiceLocked这个方法中:
final boolea isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
realStartServiceLocked(r, app, execInFg);--->这接当前进程启动service。
app=mAm.startProcessLocked---->新进程启动service


realStartServiceLocked:
1.启动新进程也会调用这个函数,启动新进程基本操作流程就是在loop消息函数运行起来前,调用attach函数,最后到realStartServiceLocked函数,消息进入消息队列结束,然后消息循环loop开始工作,处理进入消息队列的消息。
2.在当前进程创建服务时,直接执行realStartServiceLocked,消息进入消息队列,处理消息即可,

有发现一个问题,都是消息机制在运行,那么activity和service在一个mainthread消息循环里面处理消息,activity的ANR超时时间是5s,service的超时时间是15S,那么在service中一个10秒的任务处理,理论上会导致activity ANR,而不会导致service ANR。是不是呢?

稍后代码验证。

ANR代码验证结果:

1. activity和service在同一个进程和线程中时;service的ANR超时时间变为5秒和activity时间一致,因为此时service和activity在同一个loop中处理消息队列,

2. 在不同进程中,service的超时时间变长相比较于activity,时间更加充裕。

找了下ANR的时间限制,这个和android的进程管理机制相关,关于进程的:

Activity----->5秒
Broadcast----->10秒

Service----->20秒

稍后看看ANR的实现原理,网上大致看了下这个超时时间可能会根据进程的状态不同ANR的时间也会存在差异。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值