【Android源码】Service的启动过程

通常情况下,我们启动或者绑定一个Service是通过如下代码:

Intent intent = new Intent(this, TestService.class);
startService(intent);
bindService(intent, mServiceConneftion, BIND_AUTO_CREATE);

Service的启动是从ContextWrapper的startService开始的:

@Override
public ComponentName startService(Intent service) {
   return mBase.startService(service);
}

上面代码中的mBase的类型是Context,而从Activity的启动流程我们知道了,ContextImpl对象就是Context的具体实现,Activity被创建的时候会通过attach方法将ContextImpl对象关联起来,而这个ContextImpl就是mBase。

// 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(this);
       ComponentName cn = ActivityManagerNative.getDefault().startService(
           mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                       getContentResolver()), getOpPackageName(), user.getIdentifier());
       if (cn != null) {
           if (cn.getPackageName().equals("!")) {
               throw new SecurityException(
                       "Not allowed to start service " + service
                       + " without permission " + cn.getClassName());
           } else if (cn.getPackageName().equals("!!")) {
               throw new SecurityException(
                       "Unable to start service " + service
                       + ": " + cn.getClassName());
           }
       }
       return cn;
   } catch (RemoteException e) {
       throw e.rethrowFromSystemServer();
   }
}

startService又会调用startServiceCommon,而在startServiceCommon中,又会通过ActivityManagerNative.getDefault().startService来启动一个服务。
ActivityManagerNative其实就是AMS:

@Override
public ComponentName startService(IApplicationThread caller, Intent service,
       String resolvedType, String callingPackage, int userId)
       throws TransactionTooLargeException {
   enforceNotIsolatedCaller("startService");
   // Refuse possible leaked file descriptors
   if (service != null && service.hasFileDescriptors() == true) {
       throw new IllegalArgumentException("File descriptors passed in Intent");
   }

   if (callingPackage == null) {
       throw new IllegalArgumentException("callingPackage cannot be null");
   }

   if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
           "startService: " + service + " type=" + resolvedType);
   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, callingPackage, userId);
       Binder.restoreCallingIdentity(origId);
       return res;
   }
}

其中通过mServices.startServiceLocked来完成后续的启动过程,mServicesActiveServices,是一个辅助AMS来管理Service的类,包括启动、绑定、停止等操作。

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
       int callingPid, int callingUid, String callingPackage, final int userId)
       throws TransactionTooLargeException {
    return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
       boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
   String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
   return r.name;
}

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
       boolean whileRestarting, boolean permissionsReviewRequired)
       throws TransactionTooLargeException {
    realStartServiceLocked(r, app, execInFg);       
}

通过不断的调用最终调用到了realStartServiceLocked(r, app, execInFg)方法,通过名称我们可以猜测这个就是最终创建Service的方法:

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

通过app.threadscheduleCreateService来创建Service对象并调用onCreate。

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

 case CREATE_SERVICE:
     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
     handleCreateService((CreateServiceData)msg.obj);
     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     break;

这个和Activity的处理几乎一样,都是通过H这个Handler对象来发送消息,并处理的创建过程的:

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 {
       java.lang.ClassLoader cl = packageInfo.getClassLoader();
       service = (Service) cl.loadClass(data.info.name).newInstance();
   } 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 app = packageInfo.makeApplication(false, mInstrumentation);
       service.attach(context, this, data.info.name, data.token, app,
               ActivityManagerNative.getDefault());
       service.onCreate();
       mServices.put(data.token, service);
       try {
           ActivityManagerNative.getDefault().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);
       }
   }
}

这个方法主要做了这样几件事:

  1. 通过类加载器创建Service实例。
  2. 创建Application对象,并通过service的attach方法关联Application。
  3. 调用service的onCreate方法将Service对象存到ActivityThread的管理Service的列表中。

我们在回到realStartServiceLocked中,在scheduleCreateService之后又调用了sendServiceArgsLocked(r, execInFg, true)方法。
scheduleCreateService方法是创建Service对象,并调用onCreate方法。
sendServiceArgsLocked方法则是调用了onStartCommand方法。

r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);

public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
  int flags ,Intent args) {
  ServiceArgsData s = new ServiceArgsData();
  s.token = token;
  s.taskRemoved = taskRemoved;
  s.startId = startId;
  s.flags = flags;
  s.args = args;

  sendMessage(H.SERVICE_ARGS, s);
}

 case SERVICE_ARGS:
     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
     handleServiceArgs((ServiceArgsData)msg.obj);
     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     break;
     
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) {
               res = s.onStartCommand(data.args, data.flags, data.startId);
           } else {
               s.onTaskRemoved(data.args);
               res = Service.START_TASK_REMOVED_COMPLETE;
           }

           QueuedWork.waitToFinish();

           try {
               ActivityManagerNative.getDefault().serviceDoneExecuting(
                       data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
           } catch (RemoteException e) {
               throw e.rethrowFromSystemServer();
           }
           ensureJitEnabled();
       } catch (Exception e) {
           if (!mInstrumentation.onException(s, e)) {
               throw new RuntimeException(
                       "Unable to start service " + s
                       + " with " + data.args + ": " + e.toString(), e);
           }
       }
   }
}

这个时候调用了res = s.onStartCommand(data.args, data.flags, data.startId)方法,也就是说Service的启动过程已经分析完了。

后篇: Service的绑定过程

你可能感兴趣的:(【Android源码】Service的启动过程)