Service学习-Service启动过程

2025-06-27

在新进程中启动Service的过程

时序图

sequenceDiagram
    autonumber

    box Client Process

    participant Client
    participant ActivityManagerProxy

    end 

    box System Server
    participant ActivityManagerService
    participant ApplicationThreadProxy
    end

    box Client Process

    participant ApplicationThread
    participant ActivityThread
    participant H

    end

    Client->>ActivityManagerProxy: startService
    ActivityManagerProxy->>ActivityManagerService: startService
    ActivityManagerService->>ActivityManagerService: startServiceLocked
    ActivityManagerService->>ActivityManagerService: bringUpServiceLocked
    ActivityManagerService->>ActivityManagerService: startProcessLocked
    ActivityManagerService->>ActivityManagerService: startProcessLocked
    ActivityManagerService->>ActivityThread: main
    ActivityThread->>ActivityManagerProxy: attachApplication
    ActivityManagerProxy->>ActivityManagerService: attachApplication
    ActivityManagerService->>ActivityManagerService: attachApplicationLocked
    ActivityManagerService->>ActivityManagerService: realStartServiceLocked
    ActivityManagerService->>ApplicationThreadProxy: scheduleCreateService
    ApplicationThreadProxy->>ApplicationThread: scheduleCreateService
    ApplicationThread->>ActivityThread: queueOrSendMessage
    ActivityThread->>H: handleMessage
    H->>ActivityThread: handleCreateService

详细过程

step 1 调用ActivityManagerProxystartService方法:

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;
}

,向ActivityManagerService发送一个START_SERVICE_TRANSACTION请求

step 2 ActivityManagerSerive继承了ActivityManagerNative,并实现了Binder,实现了onTransact方法:

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
        case START_SERVICE_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            Intent service = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            ComponentName cn = startService(app, service, resolvedType);
            reply.writeNoException();
            ComponentName.writeToParcel(cn, reply);
            return true;
        }
    }
}

,调用了startService方法:

public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType) {
    ...
    synchronized(this) {
        final int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        ComponentName res = startServiceLocked(caller, service,
                resolvedType, callingPid, callingUid);
        Binder.restoreCallingIdentity(origId);
        return res;
    }
}

,设置了创建Service的进程Pid和用户Uid,并调用startServiceLocked方法

step 3 执行startServiceLocked方法:

ComponentName startServiceLocked(IApplicationThread caller,
        Intent service, String resolvedType,
        int callingPid, int callingUid) {
    synchronized(this) {
        ...
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType,
                    callingPid, callingUid);
        ...
        ServiceRecord r = res.record;
        ...
        if (!bringUpServiceLocked(r, service.getFlags(), false)) {
            return new ComponentName("!", "Service process is bad");
        }
        return r.name;
    }
}

,方法首先调用retieveServiceLocked查找是否存在service对应的ServiceRecord,否则就创建一个ServiceRecord对象,并调用bringUpServiceLocked方法

step 4 执行bringUpServiceLocked方法:

private final boolean bringUpServiceLocked(ServiceRecord r,
        int intentFlags, boolean whileRestarting) {
    ...
    mRestartingServices.remove(r);
    
    final String appName = r.processName;
    ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
    ...
    if (startProcessLocked(appName, r.appInfo, true, intentFlags,
            "service", r.name, false) == null) {
        ...
    }
    

    
    return true;
}

,由于service声明的进程不存在,于是调用startProcessLocked创建一个指定的进程,然后调用add方法将r保存在mPendingServices中,表示其正在等待启动

step 5 执行startProcessLocked方法:

final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
    ProcessRecord app = getProcessRecordLocked(processName, info.uid);
    ...
    
    if (app == null) {
        app = newProcessRecordLocked(null, info, processName);
        mProcessNames.put(processName, info.uid, app);
    } 
    ...
    startProcessLocked(app, hostingType, hostingNameStr);
    return (app.pid != 0) ? app : null;
}

,创建一个ProcessRecord,并调用startProcessLocked方法运行该Process

step 6

private final void startProcessLocked(ProcessRecord app,
        String hostingType, String hostingNameStr) {
    ...
    try {
        ...
        int pid = Process.start("android.app.ActivityThread",
                mSimpleProcessManagement ? app.processName : null, uid, uid,
                gids, debugFlags, null);
        ...
    } 
    ...
}

,查看Process.start方法:

    public static final int start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int debugFlags,
                                  String[] zygoteArgs)
    {
        ...
        else {
            ...
            Runnable runnable = new Runnable() {
                        public void run() {
                            Process.invokeStaticMain(processClass);
                        }
            };
            
            if (niceName != null) {
                new Thread(runnable, niceName).start();
            } else {
                new Thread(runnable).start();
            }
            return 0;
        }
    }

,其创建了一个线程,并运行invokeStaticMain方法:

private static void invokeStaticMain(String className) {
    Class cl;
    Object args[] = new Object[1];
    args[0] = new String[0];     //this is argv

    try {
        cl = Class.forName(className);
        cl.getMethod("main", new Class[] { String[].class })
                .invoke(null, args);            
    } 
    ...
}

,由于之前传入的processClass"android.app.ActivityThread",于是在此通过反向代理调用其静态main方法

step 7 执行ActivityThread.main方法:

public static final void main(String[] args) {
    ...
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    ...
    Looper.loop();
    ...
}

,可以看到,创建了一个ActivityThread的实例,并调用了attach方法:

    private final void attach(boolean system) {
        sThreadLocal.set(this);
        mSystemThread = system;
        if (!system) {
            ...
            IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                ...
            }
        }      
        ...
    }

,调用了ActivityManagerProxyattachApplication方法

step 8 执行attachApplication方法,向ActivityManagerService发送ATTACH_APPLICATION_TRANSACTION请求:

public void attachApplication(IApplicationThread app) throws RemoteException
{
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(app.asBinder());
    mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
    reply.readException();
    data.recycle();
    reply.recycle();
}

step 9 ActivityManagerService执行onTransact方法:

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
        ...
        case ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IApplicationThread app = ApplicationThreadNative.asInterface(
                    data.readStrongBinder());
            if (app != null) {
                attachApplication(app);
            }
            reply.writeNoException();
            return true;
        }
        ...
    }
    ...
}

,调用attachApplication方法:

public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        ...
        attachApplicationLocked(thread, callingPid);
        ...
    }
}

,调用attachApplicationLocked方法

step 10 执行attachApplicationLocked方法:

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid)  {
    ...
    if (!badApp && mPendingServices.size() > 0) {
        ServiceRecord sr = null;
        try {
            for (int i=0; i<mPendingServices.size(); i++) {
                sr = mPendingServices.get(i);
                if (app.info.uid != sr.appInfo.uid
                        || !processName.equals(sr.processName)) {
                    continue;
                }
                mPendingServices.remove(i);
                i--;
                realStartServiceLocked(sr, app);
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.w(TAG, "Exception in new application when starting service "
                    + sr.shortName, e);
            badApp = true;
        }
    }
    ...
}

,在attachApplicationLocked方法中,会从mPendingServices中查找要启动到相应进程的service,并调用realStartServiceLocked

step 11 执行realStartServiceLocked方法:

private final void realStartServiceLocked(ServiceRecord r,
        ProcessRecord app) throws RemoteException {
    if (app.thread == null) {
        throw new RemoteException();
    }
    r.app = app;
    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
    app.services.add(r);
    ...
    boolean created = false;
    try {
        ...
        app.thread.scheduleCreateService(r, r.serviceInfo);
        r.postNotification();
        created = true;
    } finally {
        ...
    }
    ...
}

,调用了schduleCreateService方法,app.threadApplicationThreadProxy类型的对象

step 12 执行scheduleCreateService方法:

public final void scheduleCreateService(IBinder token, ServiceInfo info)
        throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    info.writeToParcel(data, 0);
    mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
            IBinder.FLAG_ONEWAY);
    data.recycle();
}

,向ApplicatoinThread发送一个SCHEDULE_CREATE_SERVICE_TRANSACTION请求

step 13 接受到请求后,ApplicationThread执行ApplicationThreadNatvie::onTransact方法并调用

public final void scheduleCreateService(IBinder token,
        ServiceInfo info) {
    CreateServiceData s = new CreateServiceData();
    s.token = token;
    s.info = info;
    queueOrSendMessage(H.CREATE_SERVICE, s);
}

,向mH发送一个CREATE_SERVICE请求

step 14 执行queueOrSendMessage方法:

private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
    synchronized (this) {
        ...
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        mH.sendMessage(msg);
    }
}

,调用sendMessagemH发送消息

step 15 mH接受到消息后,执行handleMessage方法:

public void handleMessage(Message msg) {
    case CREATE_SERVICE:
    handleCreateService((CreateServiceData)msg.obj);
    break;
}

,调用ActivityThread::handleCreateService方法

step 16 执行handleCreateService方法:

private final void handleCreateService(CreateServiceData data) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    LoadedApk packageInfo = getPackageInfoNoCheck(
            data.info.applicationInfo);
    Service service = null;
    try {
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = (Service) cl.loadClass(data.info.name).newInstance();
    } catch (Exception e) {
        ...
    }
    try {
        ...
        service.attach(context, this, data.info.name, data.token, app,
                ActivityManagerNative.getDefault());
        service.onCreate();
        mServices.put(data.token, service);
        ...
    } catch (Exception e) {
        ...
    }
}

,首先通过反射创建了一个Service实例,并调用其attach方法,然后调用其onCreate方法

step 17 执行attach方法

step 18 执行service.onCreate方法

s