Android系统在新进程中启动自定义服务过程(startService)的原理分析

发布时间 : 星期日 文章Android系统在新进程中启动自定义服务过程(startService)的原理分析更新完毕开始阅读

?? public void run() { ??

?? ...... ??

?? // Critical services... ?? try { ??

?? ...... ??

?? context = ActivityManagerService.main(factoryTest); ??

?? ...... ??

?? ActivityManagerService.setSystemProcess(); ??

?? ...... ??

?? } catch (RuntimeException e) {

?? Slog.e(\, \, e); ?? } ??

?? ...... ?? ?? } ??

?? ...... ?? ??? }

首先是调用ActivityManagerService.main函数来创建一个ActivityManagerService实例,然后通过调用ActivityManagerService.setSystemProcess函数把这个Binder实例添加Binder进程间通信机制的守护进程ServiceManager中去:

view plain

??? public final class ActivityManagerService extends ActivityManagerNative ??? implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ???

??? ...... ???

??? static ActivityManagerService mSelf; ???

??? ...... ???

??? public static void setSystemProcess() { ??? try {

??? ActivityManagerService m = mSelf; ???

??? ServiceManager.addService(\, m); ??? ??? ...... ???

??? } catch (PackageManager.NameNotFoundException e) { ??? ...... ??? } ??? } ???

??? ...... ???

??? public static final Context main(int factoryTest) { ??? ??? ...... ???

??? ActivityManagerService m = thr.mService; ??? mSelf = m; ???

??? ...... ??? ??? } ??? }

这样,ActivityManagerService就启动起来了。

回到

ActivityManagerProxy

类的

startService

函数中,它定义在

frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

view plain

??? class ActivityManagerProxy implements IActivityManager ??? {

??? ...... ???

??? public ComponentName startService(IApplicationThread caller, Intent service,

??? String resolvedType) throws RemoteException

??? {

??? Parcel data = Parcel.obtain(); ??? Parcel reply = Parcel.obtain();

??? data.writeInterfaceToken(IActivityManager.descriptor);

??? data.writeStrongBinder(caller != null ? caller.asBinder() : null); ??? service.writeToParcel(data, 0); ??? data.writeString(resolvedType);

??? mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0); ??? reply.readException();

??? ComponentName res = ComponentName.readFromParcel(reply); ??? data.recycle(); ??? reply.recycle(); ??? return res; ??? } ???

??? ...... ??? }

参数service是一个Intent实例,它里面指定了要启动的服务的名称,就是前面我们所说的“shy.luo.ashmem.server”了。

参数caller是一个IApplicationThread实例,它是一个在主进程创建的一个Binder对象。在Android应用程序中,每一个进程都用一个ActivityThread实例来表示,而在ActivityThread类中,有一个成员变量mAppThread,它是一个ApplicationThread实例,实现了IApplicationThread接口,它的作用是用来辅助ActivityThread类来执行一些操作,这个我们在后面会看到它是如何用来启动服务的。

参数resolvedType是一个字符串,它表示service这个Intent的MIME类型,它是在解析Intent时用到的。在这个例子中,我们没有指定这个Intent 的MIME类型,因此,这个参数为null。

ActivityManagerProxy类的startService函数把这三个参数写入到data本地变量去,接着通过mRemote.transact函数进入到Binder驱动程序,然后Binder驱动程序唤醒正在等待Client请求的ActivityManagerService进程,最后进入到ActivityManagerService的startService函数中。

ActivityManagerService的startService函数的处理流程如下图所示:

点击查看大图

在这个序列图中,一共有20个步骤,下面说明每一步。 Step 1. ActivityManagerService.startService 这文件中:

view plain

个函数定义在

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

联系合同范文客服:xxxxx#qq.com(#替换为@)