Android 10 Service 启动分析

·  阅读 378

本文将基于Android 10的源码,从client 调用 bindService方法开始,到service成功绑定为止,逐步追溯中间的关键流程,了解framework 如何启动一个Service,又是在何时调用了service的哪些生命周期方法。通过本文的分析,希望能使各位读者进一步加深对Service的理解。

我们从入口函数 bindService 开始追踪:

ContextImpl.java

public boolean bindService(Intent service, ServiceConnection conn, int flags) {
	warnIfCallingFromSystemProcess();
	return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
			getUser());
}
复制代码

请注意此时的mMainThread.getHandler(),它在后面将派上用场。

ContextImpl.java

 private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
            String instanceName, Handler handler, Executor executor, UserHandle user) {
        // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
        IServiceConnection sd;
        ...
        if (mPackageInfo != null) {
            if (executor != null) {
                sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
            } else {
		//excutor 为null ,会走这个分支
                sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
            }
        } else {
            throw new RuntimeException("Not supported in system context");
        }
        validateServiceIntent(service);
        try {
            IBinder token = getActivityToken();
            if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
                    && mPackageInfo.getApplicationInfo().targetSdkVersion
                    < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                flags |= BIND_WAIVE_PRIORITY;
            }
            service.prepareToLeaveProcess(this);
            int res = ActivityManager.getService().bindIsolatedService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
            if (res < 0) {
                throw new SecurityException(
                        "Not allowed to bind to service " + service);
            }
            return res != 0;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
 }
复制代码

上述方法有三个关键步骤:

  1. mPackageInfo.getServiceDispatcher --- 通过LoadedApk获取一个IServiceConnection 对象。
  2. validateServiceIntent --- 校验service Intent的有效性,Android 5.0以上service不能使用隐式intent启动。
  3. ActivityManager.getService().bindIsolatedService --- 调用AMS中的bindIsolatedService方法。

上面有提到IServiceConnection ,这个接口是干嘛用的呢?

IServiceConnection 的实现类是InnerConnection,它的源码如下所示:

LoadedApk.java

    private static class InnerConnection extends IServiceConnection.Stub {
            @UnsupportedAppUsage
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

            InnerConnection(LoadedApk.ServiceDispatcher sd) {
                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
            }

            public void connected(ComponentName name, IBinder service, boolean dead)
                    throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service, dead);
                }
            }
        }
复制代码

可以看到,InnerConnection的代码内容非常简单,它仅仅只作为一个IPC的桥梁,提供了一个connected方法,并将connected任务转发给ServiceDispatcher去实现。

我们先跳过ServiceDispatcherconnected方法,等到真正调用它的时候再来分析。接下来按流程是走到了AMS的bindIsolatedService方法:

ActivityManagerService.java

 public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags, String instanceName,
            String callingPackage, int userId) throws TransactionTooLargeException {

      ...

        synchronized(this) {
            return mServices.bindServiceLocked(caller, token, service,
                    resolvedType, connection, flags, instanceName, callingPackage, userId);
        }
    }
复制代码

我们继续往下看:

ActiveServices.java

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String instanceName, String callingPackage, final int userId)
            throws TransactionTooLargeException {
       
       ...
	//判断ActivityStack中是否存在要bind的Activity

        ActivityServiceConnectionsHolder<ConnectionRecord> activity = null;
        if (token != null) {
            activity = mAm.mAtmInternal.getServiceConnectionsHolder(token);
            if (activity == null) {
                Slog.w(TAG, "Binding with unknown activity: " + token);
                return 0;
            }
        }

        int clientLabel = 0;
        PendingIntent clientIntent = null;
        final boolean isCallerSystem = callerApp.info.uid == Process.SYSTEM_UID;

       
	//一些特殊的Flags判断,不重要,略过
 	...

        final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
        final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0;
        final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0;

	//根据intent 搜索目标Service
        ServiceLookupResult res =
            retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
                    Binder.getCallingPid(), Binder.getCallingUid(), userId, true,
                    callerFg, isBindExternal, allowInstant);
        if (res == null) {
            return 0;
        }
        if (res.record == null) {
            return -1;
        }
        ServiceRecord s = res.record;

        boolean permissionsReviewRequired = false;

       
        if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                s.packageName, s.userId)) {

         //权限审查的代码,Android M以下才生效,不重要,可以忽略
	...
        }

        final long origId = Binder.clearCallingIdentity();

        try {
	    //如果service 正在重启中,取消restart任务
            if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "BIND SERVICE WHILE RESTART PENDING: "
                        + s);
            }

            ...


            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
		//这个flag是我们最常用的flag,首先它会先执行创建service的流程
                s.lastActivity = SystemClock.uptimeMillis();
                if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                        permissionsReviewRequired) != null) {
                    return 0;
                }
            }

            ...
            
            if (s.app != null && b.intent.received) {
               ...
            } else if (!b.intent.requested) {
	       //第一次启动service不会走到这里,如果service已启动但未绑定,则会走此分支
                requestServiceBindingLocked(s, b.intent, callerFg, false);
            }
            getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }

        return 1;
    }
复制代码

bindServiceLocked方法主要做了以下两件事情:

  1. 根据intent,搜索目标Service。
  2. 如果Flag为BIND_AUTO_CREATE,则创建Service。

我们按照顺序,一步一步来看,先看看retrieveServiceLocked方法:

ActiveServices.java

    private ServiceLookupResult retrieveServiceLocked(Intent service,
            String instanceName, String resolvedType, String callingPackage,
            int callingPid, int callingUid, int userId,
            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
            boolean allowInstant) {
        ServiceRecord r = null;
         ...
        final ComponentName comp;
        if (instanceName == null) {
			//从intent中获取ComponentName
            comp = service.getComponent();
        } else {
            ...
        }
        if (comp != null) {
	    //如果ComponentName不为空,尝试从缓存中取出ServiceRecord
            r = smap.mServicesByInstanceName.get(comp);
            if (DEBUG_SERVICE && r != null) Slog.v(TAG_SERVICE, "Retrieved by component: " + r);
        }
        if (r == null && !isBindExternal && instanceName == null) {
	    //这里同样尝试从缓存中取出ServiceRecord,不同的是筛选条件
            Intent.FilterComparison filter = new Intent.FilterComparison(service);
            r = smap.mServicesByIntent.get(filter);
            if (DEBUG_SERVICE && r != null) Slog.v(TAG_SERVICE, "Retrieved by intent: " + r);
        }
        ...
        if (r == null) {
            try {
             	//缓存中没找到,开始走创建流程了
		//在PMS中搜索匹配的ResolveInfo,Activity启动和Service启动时都有这么关键的一步,在此不做进一步分析,考虑后续再开文章单独讲解
                ResolveInfo rInfo = mAm.getPackageManagerInternalLocked().resolveService(service,
                        resolvedType, flags, userId, callingUid);
                ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
                if (sInfo == null) {
		    //没找到匹配Intent的Service,在此中断
                    Slog.w(TAG_SERVICE, "Unable to start service " + service + " U=" + userId +
                          ": not found");
                    return null;
                }

                ...

                if (r == null && createIfNeeded) {
                    final Intent.FilterComparison filter
                            = new Intent.FilterComparison(service.cloneFilter());
                    final ServiceRestarter res = new ServiceRestarter();
                    final BatteryStatsImpl.Uid.Pkg.Serv ss;
                    final BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
                    synchronized (stats) {
                        ss = stats.getServiceStatsLocked(
                                sInfo.applicationInfo.uid, name.getPackageName(),
                                name.getClassName());
                    }
		    //创建新的ServiceRecord,并存入缓存,下次就不用走重新创建ServiceRecord流程了
                    r = new ServiceRecord(mAm, ss, className, name, definingPackageName,
                            definingUid, filter, sInfo, callingFromFg, res);
                    res.setService(r);
                    smap.mServicesByInstanceName.put(name, r);
                    smap.mServicesByIntent.put(filter, r);

                    //PendingService相关的内容,不重要
                    for (int i=mPendingServices.size()-1; i>=0; i--) {
                        final ServiceRecord pr = mPendingServices.get(i);
                        if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
                                && pr.instanceName.equals(name)) {
                            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Remove pending: " + pr);
                            mPendingServices.remove(i);
                        }
                    }
                    if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Retrieve created new service: " + r);
                }
            } catch (RemoteException ex) {
                // pm is in same process, this will never happen.
            }
        }
        if (r != null) {
	    //这里都是一些限制条件的检查,可以不看
           	...
            return new ServiceLookupResult(r, null);
        }
        return null;
    }

复制代码

上文我们看到它创建了ServiceRecord这么一个类的对象,ServiceRecord这个类是干嘛用的呢?它其实是用于存储正在运行的Service的一些关键信息,类似于ActivityRecordProcessRecord这些类。

下面进入关键性的第二步,create service:

ActiveServices.java

 private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
        ...

        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
        final String procName = r.processName;
        HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
        ProcessRecord app;

        if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
                    //start service
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } catch (TransactionTooLargeException e) {
                    throw e;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
                }
            }
        } else {
           ...
        }

        // Not running -- get it started, and enqueue this service record
        // to be executed when the app comes up.
        if (app == null && !permissionsReviewRequired) {
	    //如果进程未启动,先启动进程。这篇文章不做进一步的分析,感兴趣的读者可以自行探究
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingRecord, false, isolated, false)) == null) {
                String msg = "Unable to launch app "
                        + r.appInfo.packageName + "/"
                        + r.appInfo.uid + " for service "
                        + r.intent.getIntent() + ": process is bad";
                Slog.w(TAG, msg);
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }

        if (r.fgRequired) {
            if (DEBUG_FOREGROUND_SERVICE) {
                Slog.v(TAG, "Whitelisting " + UserHandle.formatUid(r.appInfo.uid)
                        + " for fg-service launch");
            }
            mAm.tempWhitelistUidLocked(r.appInfo.uid,
                    SERVICE_START_FOREGROUND_TIMEOUT, "fg-service-launch");
        }
	//所有正在启动的Service都会记录在mPendingServices中,这个记录将是进程完成启动工作后拉起service的关键依据
 	    if (!mPendingServices.contains(r)) {
            mPendingServices.add(r);
        }

       ...

        return null;
    }
复制代码

我们继续看realStartServiceLocked这个方法:

ActiveServices.java

  private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
       ...
         //这个方法向主线程发送了一条SERVICE_TIMEOUT_MSG的延时消息,如果前台service 在10s后,后台service 在20s后仍未启动完成,则会触发ANR机制
  	bumpServiceExecutingLocked(r, execInFg, "create");
        boolean created = false;
        try {
         ...
	    //进入到ActivityThread中开始create service了
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                    app.getReportedProcState());
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
            Slog.w(TAG, "Application dead when creating service " + r);
            mAm.appDiedLocked(app);
            throw e;
        } finally {
           ...
        }

        if (r.whitelistManager) {
            app.whitelistManager = true;
        }
	// bind service
        requestServiceBindingsLocked(r, execInFg);

        updateServiceClientActivitiesLocked(app, null, true);

        if (newService && created) {
            app.addBoundClientUidsOfNewService(r);
        }

        // If the service is in the started state, and there are no
        // pending arguments, then fake up one so its onStartCommand() will
        // be called.
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null, 0));
        }
	//这里调用了service的onStartCommand方法
        sendServiceArgsLocked(r, execInFg, true);

        ...
    }
复制代码

realStartServiceLocked中完成了以下三项关键性的工作:

  1. 通过ActivityThread create service。
  2. 如果有必要,bind service。
  3. 调用service的onStartCommand方法。

scheduleCreateService方法将create service的请求转发到主线程中执行,我们直接去看转发后的handleCreateService这个方法就行了:

ActivityThread.java
 private 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, data.compatInfo);
        Service service = null;
        try {
	    //通过ClassLoader创建Service实例
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = packageInfo.getAppFactory()
                    .instantiateService(cl, data.info.name, data.intent);
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
	    //创建Application(如果没有的话,已存在Application会直接返回该实例)
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
	    //在这里调用了Service的onCreate生命周期方法
            service.onCreate();
            mServices.put(data.token, service);
            try {
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }

复制代码

上述这段方法,完成了service的create流程,并调用了onCreate生命周期方法,我们回到ActiveServices.java这个类中,继续看看 requestServiceBindingsLocked(r, execInFg);这句话,了解一下bind service的细节。

ActiveServices.java
 private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {

        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind");
                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.getReportedProcState());
                if (!rebind) {
                    i.requested = true;
                }
                i.hasBound = true;
                i.doRebind = false;
            } catch (TransactionTooLargeException e) {
             	 ...
                throw e;
            } catch (RemoteException e) {
            	...
                return false;
            }
        }
        return true;
    }
复制代码

和create service流程一样,它调用了ActivityThread类里的scheduleBindService方法去执行bind业务。

ActivityThread.java

   private void handleBindService(BindServiceData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess();
                try {
                    if (!data.rebind) {
                        IBinder binder = s.onBind(data.intent);
                        ActivityManager.getService().publishService(
                                data.token, data.intent, binder);
                    } else {
                        s.onRebind(data.intent);
                        ActivityManager.getService().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to bind to service " + s
                            + " with " + data.intent + ": " + e.toString(), e);
                }
            }
        }
    }

复制代码

上面这一段代码,请各位读者特别关注一下这段话语: IBinder binder = s.onBind(data.intent); 这里调用了service的onBind生命周期方法,并把返回的IBinder对象传递到了AMS的publishService中。

根据我们的编码经验可知,onBind方法返回的IBinder对象,可以在ServiceConnectiononServiceConnected方法里获取到,以作为客户端与服务端通讯的桥梁。 为什么可以在onServiceConnected中获取到这个IBinder对象呢?我们接着往下看:

ActivityManagerService.java
    public void publishService(IBinder token, Intent intent, IBinder service) {
        // Refuse possible leaked file descriptors
        if (intent != null && intent.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }

        synchronized(this) {
            if (!(token instanceof ServiceRecord)) {
                throw new IllegalArgumentException("Invalid service token");
            }
            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
        }
    }
复制代码
ActiveServices.java
 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
        final long origId = Binder.clearCallingIdentity();
        try {
            if (r != null) {
                Intent.FilterComparison filter
                        = new Intent.FilterComparison(intent);
                IntentBindRecord b = r.bindings.get(filter);
                if (b != null && !b.received) {
                    b.binder = service;
                    b.requested = true;
                    b.received = true;
                    ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
                    for (int conni = connections.size() - 1; conni >= 0; conni--) {
                        ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
                        for (int i=0; i<clist.size(); i++) {
                            ConnectionRecord c = clist.get(i);
                            if (!filter.equals(c.binding.intent.intent)) {
                                continue;
                            }
                            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
                            try {
                                //attetion here!!!
                                c.conn.connected(r.name, service, false);
                            } catch (Exception e) {
                                Slog.w(TAG, "Failure sending service " + r.shortInstanceName
                                      + " to connection " + c.conn.asBinder()
                                      + " (in " + c.binding.client.processName + ")", e);
                            }
                        }
                    }
                }
		//这个方法主要是做收尾的工作,其中最重要的一点是,移除SERVICE_TIMEOUT_MSG这条延时消息,以防触发ANR。
                serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }
复制代码

上面这段代码,请各位读者关注一下这句话: c.conn.connected(r.name, service, false); 其中c.connconn指的是什么?读者不妨往前翻一翻,我在文章的最开始,提到了InnerConnection这个类,它有一个connected方法,它实际上却是委托给了ServiceDispatcherconnected方法去负责实现的。前文有说,等到真正调用它的时候再来分析这个方法,现在我们便来看看它。

LoadedApk.java

  public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityExecutor != null) {
                mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
            } else if (mActivityThread != null) {
                //它会走这个分支
		//mActivityThread == mMainThread.getHandler(),即主线程,不清楚的读者可以将文章翻到最开始的地方再回顾一下
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
                doConnected(name, service, dead);
            }
        }
复制代码
LoadedApk.java

   private final class RunConnection implements Runnable {
            RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
                mName = name;
                mService = service;
                mCommand = command;
                mDead = dead;
            }

            public void run() {
                if (mCommand == 0) {
		    //mCommand == 0 ,mDead == false
                    doConnected(mName, mService, mDead);
                } else if (mCommand == 1) {
                    doDeath(mName, mService);
                }
            }

            final ComponentName mName;
            final IBinder mService;
            final int mCommand;
            final boolean mDead;
        }

复制代码

重点来了,我们来看看doConnected这个方法:

LoadedApk.java

 public void doConnected(ComponentName name, IBinder service, boolean dead) {
            ServiceDispatcher.ConnectionInfo old;
            ServiceDispatcher.ConnectionInfo info;

           ...
            // If there is a new viable service, it is now connected.
            if (service != null) {
                mConnection.onServiceConnected(name, service);
            } else {
                // The binding machinery worked, but the remote returned null from onBind().
                mConnection.onNullBinding(name);
            }
        }
复制代码

它调用了mConnectiononServiceConnected方法,第二个参数service,正是我们在onBind生命周期返回的IBinder对象,经过层层透传,最终在此被调用。这样,我们便将客户端和服务端通信的桥梁IBinder,成功的从服务端转发到了客户端。


最后,我们来看下realStartServiceLocked方法里的sendServiceArgsLocked(r, execInFg, true);这条语句:

ActiveServices.java

  private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {

        ...

        ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
        slice.setInlineCountLimit(4);
        Exception caughtException = null;
        try {
	    //attation here!!!
            r.app.thread.scheduleServiceArgs(r, slice);
        } catch (TransactionTooLargeException e) {
          ...
        } catch (RemoteException e) {
           ...
        } catch (Exception e) {
          ...
        } 
    }

复制代码

类似的,它调用了ActivityThreadscheduleServiceArgs方法。

ActivityThread.java

private void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess();
                }
                int res;
                if (!data.taskRemoved) {
		    //在此调用了service的onStartCommand生命周期方法
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }

                QueuedWork.waitToFinish();

                try {
		  //在此处理onStartCommand方法返回的值,如
		  //Service.START_STICKY、Service.START_NOT_STICKY等等
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to start service " + s
                            + " with " + data.args + ": " + e.toString(), e);
                }
            }
        }
    }

复制代码

至此,Servcie的启动流程已全部结束。

分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改