美文网首页@IT·互联网Android知识Android进阶之旅
startService源码从AMS进程到service的新进程

startService源码从AMS进程到service的新进程

作者: umbrella1 | 来源:发表于2017-05-27 15:05 被阅读554次

在开发过程中,会单独把一些耗时的计算放到一个独立的进程中进行,这样就能不会影响到主进程的使用。

本文接着上一篇基础上介绍应用主进程到AMS进程的过程,介绍从AMS进程到service新进程的过程:

先回顾下从应用主进程到AMS进程流程图:

从AMS到service新进程的过程如下:

从类图的关系中,按照数字上调用顺序说明:

Step 1:ActivityManagerNative的onTransaction:

ActivityManagerService的startService:

此caller是主进程的IApplicationThread实例,其实就是ApplicationThreadProxy,

mServices是ActiveServices,

在ActiveServices类中的startServiceLocked:

其中retrieveServiceLocked来解析service的Intent,解析service在AndroidManifest.xml定义标签的intent-filter相关内容

在ActiveServices类中的startServiceInnerLocked:

bringUpServiceLocked:

这里的procName是在AndroidManifest.xml文件中定义service标签时指定的android:process属性值了如即“.remote”。

接着调用AMS的startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类

Step2:在ActivityManagerService.startProcessLocked()里调用Proccess创建service的新进程:

Step 3:startProcesslocked:

Process.start()会启动service的新进程,然后导入android.app.ActivityThread这个类,然后实行它的main函数,此时这个些动作都在新的进程里面,此时AMS所属的进程就先放着,后面新的进程会再和AMS通信。

在Android应用程序中,每一个进程对应一个ActivityThread实例,在实行main函数中,会创建一个thread实例。

Step4:ActivityThread类的main函数:

在main函数中,也会创建该进程的UI线程的Looper以及loop().

创建完ActivityThread调用ActivityThread.attach函数进一步处理。

Step5:ActivityThread attach函数:

在attach函数中,会调用ActivityManagerNative.getDefault().attachApplication(mAppThread)函数得到ActivityManagerService的远程接口,即ActivityManagerProxy。

mAppThread是ApplicationThread对象,这个对象是service新进程,通过Binder驱动程序传递给ActivityManagerService进程里,AMS进程跟service新进程通信,靠这个IApplicationThread对象,在AMS进程里面,会把这个mAppThread设置到代理ApplicationThreadProxy的mRemote。

ActivityManagerProxy:attachApplication(app)

Step 6:在AMS进程里,找onTransact()调用到父类父类ActivityManagerNative的onTransact(),标示为ATTACH_APPLICATION_TRANSACTION的即:

其中ApplicationThreadNative.asInterface(data.readStrongBinder()),返回是ApplicationThreadProxy的对象,把之前的IApplicationThread的实例mAppThread对象(通过Binder驱动放到data里面,即data.readStrongBinder())放到ApplicationThreadProxy的mRemote.

这样在AMS进程里,就会通过ApplicationThreadProxy中mRemote和service新进程通信。

我们接着看AMS中的attachApplication:

进一步attachApplicationLocked:

mSerices是ActiveServices实例对象

Step 7:ActiveServices:attachApplicationLocked:

这里主要是对成员变量mPendingServices处理,保存了一个ServiceRecordsr,通过进程uid和进程名称将它找出来,然后realStartServiceLocked函数来进一步处理

realStartServiceLocked():

其中app.thread就是ApplicationThreadProxy,接着我们在ApplicationThread.java文件中看

Step 8: ApplicationThreadProxy的scheduleCreateService:

其中mRemote就是service新进程的ApplicationThread对象,通过Binder驱动程序回到service新进程的ApplicationThread对象中去执行onTransact(),标示为SCHEDULE_CREATE_SERVICE_TRANSACTION,在ApplicationThread的父类ApplicationThreadNative的onTransact():

Step 9:接着调用ApplicationThread.scheduleCreateService,ApplicationThread在ActivityThread.java文件,

ApplicationThread类中:

Step 10:sendMessage这里调用成员变量mH的sendMessage函数进行消息分发。这里的mH的类型为H,它继承于Handler类,what为H.CREATE_SERVICE.这样就回到新进程的UI线程里了:

在H类handleMessage 中:

Step 11:handlerCreateService是在ActivityThread:

Step 12:

service.onCreate(),service就起来了。

附上整个流程图:

相关文章

网友评论

    本文标题:startService源码从AMS进程到service的新进程

    本文链接:https://www.haomeiwen.com/subject/kkfqfxtx.html