本篇和接下来的几篇我们来浅析一下Android的另外一个非常重要的组件:Service,看到这里我们的脑海里都会涌现出什么词语呢?诸如:无用户交互界面,耗时后台操作,服务(级别)进程,远程调用。
1、看看Service的代码,好干净的感觉,没错,它就定义了一些生命周期的方法以及一些成员,注意这些成员中并没有Window,所以Service是没有用户界面的。
2、Service能进行后台耗时操作只是因为她的进程级别,并不是因为这个组件本身,因为执行后台操作的根本是工作线程。做应用和系统的都很了解进程的五个级别。那就是前台进程,可见进程,服务进程,后台进程和空进程。可以这么说:Service的进程级别永远是服务进程级别和以上级别。
3、远程调用是一种完美实现CS模型的设计,整个系统Android系统中充斥着各种Service,比如ActivityManagerService。而我们的应用程序都是一个客户端使用这些服务提供的功能时就是远程调用。这里有两种调用,一种是应用开发常用的bindService方式也就是AIDL,还有一个当然也是这种代理模式的实现,但是不同的是获取到其本地代理的方式不同,它通过ServiceManager来间接获得。

以上只是关于Service的一些概述的东西,下面将参考源码将我们常说Service的一些特性进行说明:

(一)、Service的生命周期

启动服务开始,ContextImpl.startService()最终是ActivityManagerService服务端的startService方法在完成实际操作,而这个操作又是交给ActiveServices
来完成的。

[java] view plaincopy
  1. ComponentName startServiceLocked(IApplicationThread caller,
  2. Intent service, String resolvedType,
  3. int callingPid, int callingUid, int userId) {
  4. ................
  5. // 检索需要启动服务的信息
  6. ServiceLookupResult res =
  7. retrieveServiceLocked(service, resolvedType,
  8. callingPid, callingUid, userId, true, callerFg);
  9. if (res == null) {
  10. return null;
  11. }
  12. if (res.record == null) {
  13. return new ComponentName("!", res.permission != null
  14. ? res.permission : "private to package");
  15. }
  16. ServiceRecord r = res.record;
  17. final ServiceMap smap = getServiceMap(r.userId);
  18. boolean addToStarting = false;
  19. //下面判断当前启动服务的进程状态来确定是否需要延时启动这个服务
  20. if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
  21. ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
  22. if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
  23. // If this is not coming from a foreground caller, then we may want
  24. // to delay the start if there are already other background services
  25. // that are starting.  This is to avoid process start spam when lots
  26. // of applications are all handling things like connectivity broadcasts.
  27. // We only do this for cached processes, because otherwise an application
  28. // can have assumptions about calling startService() for a service to run
  29. // in its own process, and for that process to not be killed before the
  30. // service is started.  This is especially the case for receivers, which
  31. // may start a service in onReceive() to do some additional work and have
  32. // initialized some global state as part of that.
  33. if (r.delayed) {
  34. // This service is already scheduled for a delayed start; just leave
  35. // it still waiting.
  36. if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Continuing to delay: " + r);
  37. return r.name;
  38. }
  39. //还有考虑到后台启动服务的数目上线
  40. if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
  41. // Something else is starting, delay!
  42. Slog.i(TAG, "Delaying start of: " + r);
  43. smap.mDelayedStartList.add(r);
  44. r.delayed = true;
  45. return r.name;
  46. }
  47. addToStarting = true;
  48. } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
  49. // We slightly loosen when we will enqueue this new service as a background
  50. // starting service we are waiting for, to also include processes that are
  51. // currently running other services or receivers.
  52. addToStarting = true;
  53. if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Not delaying, but counting as bg: " + r);
  54. }
  55. }
  56. return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
  57. }
[java] view plaincopy
  1. ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
  2. ServiceRecord r, boolean callerFg, boolean addToStarting) {
  3. ProcessStats.ServiceState stracker = r.getTracker();
  4. if (stracker != null) {
  5. stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
  6. }
  7. r.callStart = false;
  8. synchronized (r.stats.getBatteryStats()) {
  9. r.stats.startRunningLocked();
  10. }
  11. String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
  12. if (error != null) {
  13. return new ComponentName("!!", error);
  14. }
  15. .................
  16. return r.name;
  17. }
[java] view plaincopy
  1. private final String bringUpServiceLocked(ServiceRecord r,
  2. int intentFlags, boolean execInFg, boolean whileRestarting) {
  3. //如果服务已经启动过了,执行以下操作
  4. //对于到生命周期来说,就是重复的startService不会重复执行oncreate,只是会重复执行onStartCommand
  5. if (r.app != null && r.app.thread != null) {
  6. sendServiceArgsLocked(r, execInFg, false);
  7. return null;
  8. }
  9. .......................
  10. // Service is now being launched, its package can't be stopped.
  11. try {
  12. AppGlobals.getPackageManager().setPackageStoppedState(
  13. r.packageName, false, r.userId);
  14. } catch (RemoteException e) {
  15. } catch (IllegalArgumentException e) {
  16. Slog.w(TAG, "Failed trying to unstop package "
  17. + r.packageName + ": " + e);
  18. }
  19. final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
  20. final String procName = r.processName;
  21. ProcessRecord app;
  22. if (!isolated) {
  23. app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
  24. if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
  25. + " app=" + app);
  26. //如果进程已经存在,直接启动服务
  27. if (app != null && app.thread != null) {
  28. try {
  29. app.addPackage(r.appInfo.packageName, mAm.mProcessStats);
  30. realStartServiceLocked(r, app, execInFg);
  31. return null;
  32. } catch (RemoteException e) {
  33. Slog.w(TAG, "Exception when starting service " + r.shortName, e);
  34. }
  35. // If a dead object exception was thrown -- fall through to
  36. // restart the application.
  37. }
  38. }
  39. ......................
  40. return null;
  41. }
[java] view plaincopy
  1. private final void realStartServiceLocked(ServiceRecord r,
  2. ProcessRecord app, boolean execInFg) throws RemoteException {
  3. if (app.thread == null) {
  4. throw new RemoteException();
  5. }
  6. if (DEBUG_MU)
  7. Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
  8. + ", ProcessRecord.uid = " + app.uid);
  9. r.app = app;
  10. r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
  11. app.services.add(r);
  12. bumpServiceExecutingLocked(r, execInFg, "create");
  13. mAm.updateLruProcessLocked(app, false, null);
  14. mAm.updateOomAdjLocked();
  15. boolean created = false;
  16. //这是服务的首次启动流程,先执行scheduleCreateService,其实到了本地端就是实例化服务类,然后调用了其onCreate方法
  17. try {
  18. String nameTerm;
  19. int lastPeriod = r.shortName.lastIndexOf('.');
  20. nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
  21. EventLogTags.writeAmCreateService(
  22. r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
  23. synchronized (r.stats.getBatteryStats()) {
  24. r.stats.startLaunchedLocked();
  25. }
  26. mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
  27. //调整进程的状态也就是优先级了
  28. app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
  29. app.thread.scheduleCreateService(r, r.serviceInfo,
  30. mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
  31. app.repProcState);
  32. r.postNotification();
  33. created = true;
  34. } finally {
  35. if (!created) {
  36. app.services.remove(r);
  37. r.app = null;
  38. scheduleServiceRestartLocked(r, false);
  39. }
  40. }
  41. //这里是处理bind服务的请求
  42. requestServiceBindingsLocked(r, execInFg);
  43. // If the service is in the started state, and there are no
  44. // pending arguments, then fake up one so its onStartCommand() will
  45. // be called.
  46. if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
  47. r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
  48. null, null));
  49. }
  50. //然后再执行后续的sendServiceArgsLocked方法
  51. sendServiceArgsLocked(r, execInFg, true);
  52. if (r.delayed) {
  53. if (DEBUG_DELAYED_STATS) Slog.v(TAG, "REM FR DELAY LIST (new proc): " + r);
  54. getServiceMap(r.userId).mDelayedStartList.remove(r);
  55. r.delayed = false;
  56. }
  57. if (r.delayedStop) {
  58. // Oh and hey we've already been asked to stop!
  59. r.delayedStop = false;
  60. if (r.startRequested) {
  61. if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Applying delayed stop (from start): " + r);
  62. stopServiceLocked(r);
  63. }
  64. }
  65. }
[java] view plaincopy
  1. private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
  2. boolean oomAdjusted) {
  3. //这个方法在后面流程可以注意到,在bindservice时也有进来,所以呢,这个pendingStarts就成了是否执行实际操作的判断条件
  4. //直接采用绑定方式创建服务时这个是没有的,start流程中才有添加过程
  5. final int N = r.pendingStarts.size();
  6. if (N == 0) {
  7. return;
  8. }
  9. while (r.pendingStarts.size() > 0) {
  10. try {
  11. ServiceRecord.StartItem si = r.pendingStarts.remove(0);
  12. //这里scheduleServiceArgs方法调用的是本地端服务的onStartCommand方法,这里的本地端是相对于ActivityManagerService来说的。
  13. r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
  14. } catch (RemoteException e) {
  15. // Remote process gone...  we'll let the normal cleanup take
  16. // care of this.
  17. if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
  18. break;
  19. } catch (Exception e) {
  20. Slog.w(TAG, "Unexpected exception", e);
  21. break;
  22. }
  23. }
  24. }

从start的启动流程看,得到结论是正常启动会先执行onCreate然后执行onStartCommand,重复启动服务只是会重复执行onStartCommand,并不会多次执行onCreate。特殊的是,如果之前有客户端绑定但是未自动创建服务的情况下,startService会执行完onCreate后执行onBind最后是onStartCommand,注意后面介绍中的绑定流程。
    下面来看下一种情况,直接bindservice看看又是如何执行的呢,其他调用流程省略,只看关键的部分

[java] view plaincopy
  1. int bindServiceLocked(IApplicationThread caller, IBinder token,
  2. Intent service, String resolvedType,
  3. IServiceConnection connection, int flags, int userId) {
  4. ....................
  5. ServiceLookupResult res =
  6. retrieveServiceLocked(service, resolvedType,
  7. Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
  8. ....................
  9. try {
  10. if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
  11. if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
  12. + s);
  13. }
  14. ...................
  15. <pre name="code" class="java">            //bindings中添加一起绑定请求,后续requestServiceBindingsLocked()流程中处理绑定接口
  16. AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
  17. ....................
  18. if ((flags&Context.BIND_AUTO_CREATE) != 0) {
  19. s.lastActivity = SystemClock.uptimeMillis();
  20. //如果携带的标志位中包含自动启动,则进行创建服务的操作,代码可以看前面,如果已经启动了,其实是什么操作也不干的
  21. if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
  22. return 0;
  23. }
  24. }
  25. if (s.app != null) {
  26. // This could have made the service more important.
  27. mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities, b.client);
  28. mAm.updateOomAdjLocked(s.app);
  29. }
  30. if (s.app != null && b.intent.received) {
  31. // Service is already running, so we can immediately
  32. // publish the connection.
  33. // 如果服务已经启动并且有绑定过了,直接返回binder对象,这个放到后面跨进程部分来说
  34. try {
  35. c.conn.connected(s.name, b.intent.binder);
  36. } catch (Exception e) {
  37. Slog.w(TAG, "Failure sending service " + s.shortName
  38. + " to connection " + c.conn.asBinder()
  39. + " (in " + c.binding.client.processName + ")", e);
  40. }
  41. // If this is the first app connected back to this binding,
  42. // and the service had previously asked to be told when
  43. // rebound, then do so.
  44. // 从这里可以看出,一般情况下,onBind只会执行一次,除非请求doRebind
  45. // 这个标志位是旧的客户端全部unbind之后自动设置上的,这个后面将Unbind的时候会看到
  46. if (b.intent.apps.size() == 1 && b.intent.doRebind) {
  47. requestServiceBindingLocked(s, b.intent, callerFg, true);
  48. }
  49. } else if (!b.intent.requested) {
  50. //服务还没有绑定者,则执行后续操作将调用到onBind操作
  51. requestServiceBindingLocked(s, b.intent, callerFg, false);
  52. }
  53. getServiceMap(s.userId).ensureNotStartingBackground(s);
  54. } finally {
  55. Binder.restoreCallingIdentity(origId);
  56. }
  57. return 1;
  58. }
[java] view plaincopy
  1. private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
  2. //这个方法在正常的start流程中也有执行到,就得靠bindings来作为判断执行条件,这里面存的是bindservice的请求,只有在bind服务时才会添加
  3. for (int i=r.bindings.size()-1; i>=0; i--) {
  4. IntentBindRecord ibr = r.bindings.valueAt(i);
  5. if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
  6. break;
  7. }
  8. }
  9. }
[java] view plaincopy
  1. private final boolean requestServiceBindingLocked(ServiceRecord r,
  2. IntentBindRecord i, boolean execInFg, boolean rebind) {
  3. if (r.app == null || r.app.thread == null) {
  4. // If service is not currently running, can't yet bind.
  5. return false;
  6. }
  7. if ((!i.requested || rebind) && i.apps.size() > 0) {
  8. try {
  9. bumpServiceExecutingLocked(r, execInFg, "bind");
  10. r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
  11. // 哇,又要去本地执行onBind方法咯
  12. r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
  13. r.app.repProcState);
  14. if (!rebind) {
  15. i.requested = true;
  16. }
  17. i.hasBound = true;
  18. i.doRebind = false;
  19. } catch (RemoteException e) {
  20. if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
  21. return false;
  22. }
  23. }
  24. return true;
  25. }

好了,到这里我们已经有了一定的结论,直接绑定服务时会先执行onCreate,然后执行onBind但不会执行onStartCommand(注意前面介绍中的sendServiceArgsLocked()方法注释);已经启动的服务直接执行onBind。剩下的bind后面的事情就留在讲解后面两个问题的时候再说吧就是返回binder对象和如何跨进程的事情。
       其他的生命周期分析方式类似,这里边有一个典型操作:绑定的服务先stopService然后unbind的执行次序,没开始之前可以猜一下结果。
执行stop操作执行到这里来

[java] view plaincopy
  1. private void stopServiceLocked(ServiceRecord service) {
  2. if (service.delayed) {
  3. // If service isn't actually running, but is is being held in the
  4. // delayed list, then we need to keep it started but note that it
  5. // should be stopped once no longer delayed.
  6. if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Delaying stop of pending: " + service);
  7. service.delayedStop = true;
  8. return;
  9. }
  10. ..............
  11. service.startRequested = false;
  12. service.callStart = false;
  13. bringDownServiceIfNeededLocked(service, false, false);
  14. }
[java] view plaincopy
  1. private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
  2. boolean hasConn) {
  3. // 先判断是否还需要这个服务存在
  4. if (isServiceNeeded(r, knowConn, hasConn)) {
  5. return;
  6. }
  7. // Are we in the process of launching?
  8. if (mPendingServices.contains(r)) {
  9. return;
  10. }
  11. bringDownServiceLocked(r);
  12. }
[java] view plaincopy
  1. private final boolean isServiceNeeded(ServiceRecord r, boolean knowConn, boolean hasConn) {
  2. // Are we still explicitly being asked to run?
  3. if (r.startRequested) {
  4. return true;
  5. }
  6. // Is someone still bound to us keepign us running?
  7. // 这个knowConn变量名起的有意思,是否知道有人连接,后面可以看到在解除绑定的时候再来这里,这个值就是true的
  8. if (!knowConn) {
  9. // 如果不知道是否有人绑定,则去获取一下是否有,这里很重要,大家看获取的是AutoCreate,也就是说绑定时带了Context.BIND_AUTO_CREATE标志位来的
  10. // 更多根其相关的r.bindings,这个在前面也有提出,在正常的start流程中执行oncreate之后会检测这个然后去执行onBind操作。
  11. hasConn = r.hasAutoCreateConnections();
  12. }
  13. if (hasConn) {
  14. //逻辑就是如果还有人绑定着就需要服务存在,bringDownServiceIfNeededLocked()这个方法也就直接返回了。
  15. return true;
  16. }
  17. return false;
  18. }
[java] view plaincopy
  1. private final void bringDownServiceLocked(ServiceRecord r) {
  2. // Report to all of the connections that the service is no longer
  3. // available.
  4. for (int conni=r.connections.size()-1; conni>=0; conni--) {
  5. ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
  6. for (int i=0; i<c.size(); i++) {
  7. ConnectionRecord cr = c.get(i);
  8. // There is still a connection to the service that is
  9. // being brought down.  Mark it as dead.
  10. cr.serviceDead = true;
  11. try {
  12. cr.conn.connected(r.name, null);
  13. } catch (Exception e) {
  14. Slog.w(TAG, "Failure disconnecting service " + r.name +
  15. " to connection " + c.get(i).conn.asBinder() +
  16. " (in " + c.get(i).binding.client.processName + ")", e);
  17. }
  18. }
  19. }
  20. // Tell the service that it has been unbound.
  21. if (r.app != null && r.app.thread != null) {
  22. for (int i=r.bindings.size()-1; i>=0; i--) {
  23. IntentBindRecord ibr = r.bindings.valueAt(i);
  24. if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
  25. + ": hasBound=" + ibr.hasBound);
  26. if (ibr.hasBound) {
  27. try {
  28. bumpServiceExecutingLocked(r, false, "bring down unbind");
  29. mAm.updateOomAdjLocked(r.app);
  30. ibr.hasBound = false;
  31. r.app.thread.scheduleUnbindService(r,
  32. ibr.intent.getIntent());
  33. } catch (Exception e) {
  34. Slog.w(TAG, "Exception when unbinding service "
  35. + r.shortName, e);
  36. serviceProcessGoneLocked(r);
  37. }
  38. }
  39. }
  40. }
  41. ..................
  42. unscheduleServiceRestartLocked(r, 0, true);
  43. // Also make sure it is not on the pending list.
  44. for (int i=mPendingServices.size()-1; i>=0; i--) {
  45. if (mPendingServices.get(i) == r) {
  46. mPendingServices.remove(i);
  47. if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
  48. }
  49. }
  50. ..................
  51. // Clear start entries.
  52. r.clearDeliveredStartsLocked();
  53. r.pendingStarts.clear();
  54. if (r.app != null) {
  55. synchronized (r.stats.getBatteryStats()) {
  56. r.stats.stopLaunchedLocked();
  57. }
  58. r.app.services.remove(r);
  59. if (r.app.thread != null) {
  60. updateServiceForegroundLocked(r.app, false);
  61. try {
  62. bumpServiceExecutingLocked(r, false, "destroy");
  63. mDestroyingServices.add(r);
  64. mAm.updateOomAdjLocked(r.app);
  65. r.app.thread.scheduleStopService(r);
  66. } catch (Exception e) {
  67. Slog.w(TAG, "Exception when destroying service "
  68. + r.shortName, e);
  69. serviceProcessGoneLocked(r);
  70. }
  71. }
  72. ....................
  73. }
  74. ......................
  75. if (r.bindings.size() > 0) {
  76. r.bindings.clear();
  77. }
  78. if (r.restarter instanceof ServiceRestarter) {
  79. ((ServiceRestarter)r.restarter).setService(null);
  80. }
  81. .....................
  82. }

再来看看解除绑定的操作时哪些

[java] view plaincopy
  1. boolean unbindServiceLocked(IServiceConnection connection) {
  2. IBinder binder = connection.asBinder();
  3. ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
  4. if (clist == null) {
  5. Slog.w(TAG, "Unbind failed: could not find connection for "
  6. + connection.asBinder());
  7. return false;
  8. }
  9. final long origId = Binder.clearCallingIdentity();
  10. try {
  11. while (clist.size() > 0) {
  12. ConnectionRecord r = clist.get(0);
  13. removeConnectionLocked(r, null, null);
  14. if (r.binding.service.app != null) {
  15. // This could have made the service less important.
  16. mAm.updateOomAdjLocked(r.binding.service.app);
  17. }
  18. }
  19. } finally {
  20. Binder.restoreCallingIdentity(origId);
  21. }
  22. return true;
  23. }
[java] view plaincopy
  1. void removeConnectionLocked(
  2. ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
  3. ...................
  4. //这里在没解绑一个就是取消一个connection
  5. //这个在本方法的最后,如果所有的都解绑connections为空,s.hasAutoCreateConnections()返回值是false的,
  6. //这个在判断服务是否还需要保留时会判断为不保留直接销毁
  7. ArrayList<ConnectionRecord> clist = s.connections.get(binder);
  8. if (clist != null) {
  9. clist.remove(c);
  10. if (clist.size() == 0) {
  11. s.connections.remove(binder);
  12. }
  13. }
  14. b.connections.remove(c);
  15. if (c.activity != null && c.activity != skipAct) {
  16. if (c.activity.connections != null) {
  17. c.activity.connections.remove(c);
  18. }
  19. }
  20. ..................
  21. if (!c.serviceDead) {
  22. if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
  23. + ": shouldUnbind=" + b.intent.hasBound);
  24. if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
  25. && b.intent.hasBound) {
  26. try {
  27. bumpServiceExecutingLocked(s, false, "unbind");
  28. if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
  29. && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
  30. // If this service's process is not already in the cached list,
  31. // then update it in the LRU list here because this may be causing
  32. // it to go down there and we want it to start out near the top.
  33. mAm.updateLruProcessLocked(s.app, false, null);
  34. }
  35. mAm.updateOomAdjLocked(s.app);
  36. b.intent.hasBound = false;
  37. // Assume the client doesn't want to know about a rebind;
  38. // we will deal with that later if it asks for one.
  39. b.intent.doRebind = false;
  40. s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
  41. } catch (Exception e) {
  42. Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
  43. serviceProcessGoneLocked(s);
  44. }
  45. }
  46. if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
  47. boolean hasAutoCreate = s.hasAutoCreateConnections();
  48. if (!hasAutoCreate) {
  49. if (s.tracker != null) {
  50. s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
  51. SystemClock.uptimeMillis());
  52. }
  53. }
  54. //如果是绑定时创建的,还需要看看是否需要执行stop。
  55. bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
  56. }
  57. }
  58. }

好了,看完应该也有结论了,那就是如果服务是先创建,然后被绑定的,直接stop后,会通知每个绑定客户端服务将销毁,然后执行onUnbind,最后执行onDestroy销毁服务

如果是绑定时创建的服务,直接stop是不会销毁的,直到所有的带有auto_create标志的客户端都解除绑定之后会直接执行onDestroy进行销毁。一句话:服务的各种异样死法都跟这个标志Context.BIND_AUTO_CREATE有关,有了它,管你谁先谁后我都是老大,没有它start操作才最NB,因为单纯bind压根起不来还得等待start来。

到这里我觉得生命周期的一些特殊问题已经阐述的差不多了,在上面的代码中时不时就会出现关于ReStart的字眼,这就是我下篇将要说的一个问题,服务的重启问题。

后续内容预告:

(二)、Service的自动重启问题

(三)、Service与其客户端的绑定如何实现,即跨进程调用问题。

原文地址:http://blog.csdn.net/hehui1860/article/details/37530641

Android的服务(Service)(一)生命周期相关推荐

  1. Android复习10【Service与Thread的区别、Service的生命周期、Service生命周期解析(相关方法详解、启动方式的不同、绑定)、音乐播放器+服务】

    音乐播放器Android代码下载:https://wws.lanzous.com/ifqzihaxvij 目   录 Service与Thread的区别 Service的生命周期 Service生命周 ...

  2. 18_Android中Service的生命周期,远程服务,绑定远程服务,aidl服务调用,综合服务案例,编写一个应用程序调用远程支付宝远程服务场景

    ============================================================================ 服务的生命周期: 一.采用start的方式开始 ...

  3. Android开发笔记(四十一)Service的生命周期

    与生命周期有关的方法 onCreate : 创建服务 onStart : 开始服务,Android2.0以下版本使用 onStartCommand : 开始服务,Android2.0及以上版本使用.该 ...

  4. 【Android】Android Service的生命周期

    Managing the Lifecycle of a Service 原文来自: http://www.cnblogs.com/mengdd/archive/2013/03/24/2979944.h ...

  5. Activity和Service的生命周期-----Activity学习笔记(一)

    1.Activity的生命周期 情形一.一个单独的Activity的正常的生命过程是这样的:onCreate->onStart->onPause->onStop->onDest ...

  6. Service 的生命周期;两种启动方法和区别

    1:startService  Service的生命周期:onCreate() --> onStart() -> onDestroy() 停止服务:service.stopService( ...

  7. Android的服务Service

    Android学了太久了,都忘了.复习下四大组件之一的Service. 介绍 Android的Service是一种在后台执行长时间运行操作的组件,它可以在没有用户界面的情况下执行任务,并且可以与应用程 ...

  8. (一)Service的生命周期和两种启动方式

    Service 一.概念 Service,也是Android四大组件之一.对照Activity的概念,Service属于后台运行的进程,并不需要界面,可以在后台长期运行,适合做比如播放音乐,下载等任务 ...

  9. Service的生命周期及handleMessage

    看android原生蓝牙,发现在开启蓝牙的时候,GattService.java的onStartCommand()中发送了一个message,但是到了onStart()执行结束后才执行这个消息. 先看 ...

  10. 神策数据张涛:企业服务客户全生命周期运营三步曲:执行反馈

    本文根据神策数据副总裁张涛关于企业服务客户全生命周期系列的直播内容整理,共 3 篇,本篇主要内容如下: 解决方案的落地与执行 解决方案执行效果反馈与分析 反向检验关键问题和解决方案的有效性 全生命周期 ...

最新文章

  1. 第3周实践项目7 删除链表元素最大值
  2. 4个最难的 Elastic Search 面试题
  3. 2020潮流海报设计PNG免抠素材
  4. 【C/C++】sizeof(结构体)的计算
  5. 【Interfacenavigation】隐藏导航栏(52)
  6. mysql打开数据库的sql语句_数据库MySQL——SQL语句(命令)
  7. nodejs中字符串和json转换
  8. Android Studio欢迎界面和登陆界面的设计(小白)
  9. 详解二叉树的递归遍历与非递归遍历——(二)
  10. 1-2 实验2 点对点通信
  11. CCF考试——201312-5I’m stuck!
  12. 三器六垢_本初行者劉暢友居士浅谈如何学佛(三)
  13. 计算机启动 滴的一声,电脑开机后滴的一声是什么意思?
  14. 基于PANDA做DTI分析
  15. 5410 ACM 杭电 01+完全背包
  16. 在blender使用MMD模型凹造型的简单流程
  17. 两台电脑用网线直连传文件
  18. 【笔记】理解黑天鹅,应对不可预知的未来
  19. [转帖]三星F488E的JAVA安装方法
  20. Xcode使用OpenCV访问Mac摄像头权限问题

热门文章

  1. 神奇的滚动动画,30个视差滚动网站设计
  2. CSU 1337 搞笑版费马大定理(2013湖南省程序设计竞赛J题)
  3. 优化应用不可不知道的知识
  4. Python学习笔记:web开发2
  5. 时频分析:短时傅里叶变换实现(1)
  6. QCustomplot基础应用
  7. Makefile文件生成
  8. Linux下autoconf和automake使用
  9. 二十万字C/C++、嵌入式软开面试题全集宝典九
  10. 通信工程专业的一些小知识点