Service启动流程源码分析之startService(一)

1、概要

我们平时在开发Android应用时,一般会将一些需要计算的逻辑放到独立进程的Service中处理,这样主进程就可以响应用户的其他操作从而提高用户体验。Android在此为我们提供了Service服务,我们只需实现继承Service的子类,然后通过startService来启动这个服务就可以了。
接下来我们将开始详细的介绍在主线程中如何通过startService来启动新进程中的服务(本文主要阐述启动新进程的服务,在同一进程中的服务我们也会稍微提及)。

由于Service的启动流程和Activity比较相似,所以在开始分析之前,希望大家可以先了解一下Activity的启动方式Activity启动流程源码分析之入门(一)。

2、startService启动流程时序图

Service启动流程源码分析之startService(一)_第1张图片

以上就是通过startService来启动Service的流程时序图,接下来我们将对照该图详细的讲解其启动流程。

3、startService源码分析

由于大家平时在开发Android应用时,通过startService启动Service这种方式应该用的比较多了,所以这里我就不举示例了,但是我们要注意一点,今天我们是在新进程中启动Service,所以需要在AndroidManifest文件中把Service配置android:process属性,那样才能启动新进程。

好啦,话不多说让我们进入startService方法吧(顺便说一下,本次源码是基于Android5.1)。

大家首先要明白一个问题,在Activity中使用的startService方法是定义在Context的抽象类中,它的真正实现者是ContextImpl,所以我们首先进入ContextImpl类,大家如果不是很清楚可以看下我的另外一篇博客Android中的Context源码分析。

(1)ContextImpl.startService()

源码:frameworks/base/core/java/android/app/ContextImpl.java

 @Override
    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, mUser);
    }

private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess();
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
            //......
            return cn;
        } catch (RemoteException e) {
            return null;
        }
    }

从ContextImpl类的startService开始,然后进入本类的startServiceCommon方法,并最终调用ActivityManagerNative.getDefault()对象的startService方法。其实这里的ActivityManagerNative.getDefault()就是ActivityManagerProxy对象,如果不是很清楚可以看我的另外一篇博客ActivityManagerService与应用程序通信分析。

(2)ActivityManagerProxy.startService()

源码:frameworks/base/core/java/android/app/ActivityManagerNative.java

public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, int userId) 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);
        data.writeInt(userId);
        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        ComponentName res = ComponentName.readFromParcel(reply);
        data.recycle();
        reply.recycle();
        return res;
    }

通过Binder调用ActivityManagerNative类中onTransact方法,其识别码为START_SERVICE_TRANSACTION,并最终调用ActivityManagerNative的实现类ActivityManagerService的startService方法。

(3)ActivityManagerService.startService()

源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

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

在这里调用mServices对象的startServiceLocked方法,这里的mServices对象是ActiveServices类。

(4)ActiveServices.startServiceLocked()

源码:frameworks/base/services/java/com/android/server/am/ActiveServices.java

ComponentName startServiceLocked(IApplicationThread caller,
            Intent service, String resolvedType,
            int callingPid, int callingUid, int userId) {

    //......
    ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType,
                    callingPid, callingUid, userId, true, callerFg);
    ServiceRecord r = res.record;
    //......
    return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}

首先通过retrieveServiceLocked方法来解析service这个Intent,就是解析前面我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中,最后在调用startServiceInnerLocked方法。

(5)ActiveServices.startServiceInnerLocked()

源码:frameworks/base/services/java/com/android/server/am/ActiveServices.java

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
            ServiceRecord r, boolean callerFg, boolean addToStarting) {

        //......
        synchronized (r.stats.getBatteryStats()) {
            r.stats.startRunningLocked();
        }
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
        //......
}

这里紧接着会调用bringUpServiceLocked方法。

(6)ActiveServices.bringUpServiceLocked()

源码:frameworks/base/services/java/com/android/server/am/ActiveServices.java

private final String bringUpServiceLocked(ServiceRecord r,
            int intentFlags, boolean execInFg, boolean whileRestarting) {

    //(1)这里如果当前的ProcessRecord不为null,那就不需要重新创建进程,而是调用realStartServiceLocked方法来启动Service
    if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
                }

                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }

    //(2)如果是需要创建新进程,那么将调用ActivityManagerService.startProcessLocked方法来启动新进程
    if (app == null) {
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {
                //......
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }

    //最后将ServiceRecord保存到成员变量mPendingServices中
    if (!mPendingServices.contains(r)) {
            mPendingServices.add(r);
    }
}

这个方法比较重要,这里有两种选择,当Service所在的进程存在时,将调用realStartServiceLocked方法来启动Service,否则的话调用startProcessLocked方法来启动新进程。

(7)ActivityManagerService.startProcessLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {

    boolean isActivityProcess = (entryPoint == null);
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            checkTime(startTime, "startProcess: asking zygote to start proc");
            //通过processName,uid等启动新进程
            Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);
}

这里通过Process的start方法启动ActivityThread的新进程,我们进入该类的main方法。

(8)ActivityThread.main()

源码:frameworks/base/core/java/android/app/ActivityThread.java

public static void main(String[] args) {
        //......

        Process.setArgV0("");

        Looper.prepareMainLooper();
        //创建ActivityThread对象,并调用其attach方法
        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

    private void attach(boolean system) {
        final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                //这里调用了ActivityManagerProxy.attachApplication方法。
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
    }

在Android应用程序中,每一个进程对应一个ActivityThread实例,然后这里创建了ActivityThread对象并调用了其attach方法,在attach方法中又调用了ActivityManagerProxy.attachApplication方法。

(9)ActivityManagerProxy.attachApplication()

源码:frameworks/base/core/java/android/app/ActivityManagerNative.java

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

通过Binder机制会调用ActivityManagerNative中的onTransact方法,其识别码为ATTACH_APPLICATION_TRANSACTION,并最终调用ActivityManagerService中的attachApplication方法。

(10)ActivityManagerService.attachApplication()

源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

@Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);

            //......
        }
    }

这里调用attachApplicationLocked方法来进一步处理。

(11)ActivityManagerService.attachApplicationLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

    // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

    // Find any services that should be running in this process...
        if (!badApp) {
            try {
            //这里会调用ActiveServices对象的attachApplicationLocked方法
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }
}

这里如果是启动Service将调用ActiveServices对象的attachApplicationLocked方法,而如果是启动Activity将调用ActivityStackSupervisor对象的attachApplicationLocked方法。

(12)ActiveServices.attachApplicationLocked()

源码:frameworks/base/services/java/com/android/server/am/ActiveServices.java

boolean attachApplicationLocked(ProcessRecord proc, String processName)
            throws RemoteException {

    boolean didSomething = false;
        // Collect any services that are waiting for this process to come up.
        if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
            try {
                for (int i=0; i
                    sr = mPendingServices.get(i);
                    if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                            || !processName.equals(sr.processName))) {
                        continue;
                    }

                    mPendingServices.remove(i);
                    i--;
                    proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,mAm.mProcessStats);

                    //这里调用realStartServiceLocked方法
                    realStartServiceLocked(sr, proc, sr.createdFromFg);
                    didSomething = true;
                }
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception in new application when starting service "+ sr.shortName, e);
                throw e;
            }
        }
    //......
}

(13)ActiveServices.realStartServiceLocked()

源码:frameworks/base/services/java/com/android/server/am/ActiveServices.java

private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {

    if (app.thread == null) {
            throw new RemoteException();
        }

    //......

    app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
}

此处的app.thread是一个IApplicationThread对象,而IApplicationThread的代理类是ApplicationThreadProxy,我们进入app.thread对象的scheduleCreateService方法。

(14)ApplicationThreadProxy.scheduleCreateService()

源码:frameworks/base/core/java/android/app/ApplicationThreadNative.java

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

通过Binder对象调用ApplicationThreadNative的onTransact方法,在其方法中调用子类的scheduleCreateService方法,即最终调用ApplicationThreadNative的子类ApplicationThread的scheduleCreateService方法。

(15)ApplicationThread.scheduleCreateService()

源码:frameworks/base/core/java/android/app/ActivityThread.java

public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;

            sendMessage(H.CREATE_SERVICE, s);
        }

通过Handler发送Message来处理该操作,并进入到H的handleMessage方法中,其识别码为CREATE_SERVICE。

(16)H.handleMessage()

源码:frameworks/base/core/java/android/app/ApplicationThread.java

private class H extends Handler {

    public void handleMessage(Message msg) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
        //这里调用handleCreateService方法
        handleCreateService((CreateServiceData)msg.obj);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}

我们继续进入handleCreateService方法。

(17)ApplicationThread.handleCreateService()

源码:frameworks/base/core/java/android/app/ActivityThread.java

private void handleCreateService(CreateServiceData data) {

    Service service = null;
        try {
            //(1)通过类加载器来加载Service对象
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            //......
        }

    //(2)这里创建ContextImpl对象
    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
    context.setOuterContext(service);

    Application app = packageInfo.makeApplication(false, mInstrumentation);
    service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
    //(3)这里调用Service的onCreate方法
    service.onCreate();
    mServices.put(data.token, service);
}

(1)处通过类加载器ClassLoader来加载Service对象,此处的data.info.name就是我们要启动的Service,加载完成后需要将其强转换为Service对象,也就是说我们的Service必须要继承于Service基类。
(2)处这里先创建一个ContextImpl对象,每个Activity和Service都有一个Context对象。
(3)处这里调用Service的OnCreate方法。

好啦,到此整个Service通过startService的方式就启动起来了,接下来我们总结一下步骤。

4、总结

1、(1)-(7)从主进程调用到ActivityManagerService进程中,并调用其startProcessLocked方法来启动新的进程。
2、(8)-(11)从新进程调用到ActivityManagerService进程中,获取要启动的服务的相关信息。
3、(12)-(17)从ActivityManagerService进程回到新进程中并最终将服务启动起来。

好啦,本篇通过startService来启动新进程服务就介绍到这里啦,下篇我们将分析通过bindService来启动服务Service启动流程源码分析之bindService(二)。

你可能感兴趣的:(Android底层分析)