闲话少说,接上一篇《Android 6.0 启动startService()源码分析(2)

10.9 ActiveServices.bumpServiceExecutingLocked

发送SERVICE_TIMEOUT_MSG用来判断是否ANR

  1.   private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
  2.       if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, ">>> EXECUTING "
  3.               + why + " of " + r + " in app " + r.app);
  4.       else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, ">>> EXECUTING "
  5.               + why + " of " + r.shortName);
  6.       long now = SystemClock.uptimeMillis();
  7.       executeNesting 记录前台次数,第一次为0fg是启动前台还是后台服务】
  8.       if (r.executeNesting == 0) {
  9.           r.executeFg = fg;
  10.           ProcessStats.ServiceState stracker = r.getTracker();
  11.           if (stracker != null) {
  12.               stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
  13.           }
  14.           if (r.app != null) {
  15.               r.app.executingServices.add(r);
  16.               r.app.execServicesFg |= fg;
  17.               if (r.app.executingServices.size() == 1) {
  18.                   scheduleServiceTimeoutLocked(r.app); 10.9.1 发送SERVICE_TIMEOUT_MSG
  19.               }
  20.           }
  21.       } else if (r.app != null && fg && !r.app.execServicesFg) {
  22.           r.app.execServicesFg = true;
  23.           scheduleServiceTimeoutLocked(r.app);
  24.       }
  25.       r.executeFg |= fg;
  26.       r.executeNesting++;
  27.       r.executingStart = now;
  28.   }
复制
10.9.1 发送SERVICE_TIMEOUT_MSG
  1.   void scheduleServiceTimeoutLocked(ProcessRecord proc) {
  2.       if (proc.executingServices.size() == 0 || proc.thread == null) {
  3.           return;
  4.       }
  5.       long now = SystemClock.uptimeMillis();
  6.       Message msg = mAm.mHandler.obtainMessage(
  7.               ActivityManagerService.SERVICE_TIMEOUT_MSG);
  8.       msg.obj = proc;
  9.       【发送SERVICE_TIMEOUT_MSG消息】
  10.       mAm.mHandler.sendMessageAtTime(msg,
  11.               proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
  12.   }
复制

前台服务 SERVICE_TIMEOUT是20s

后台服务 SERVICE_BACKGROUND_TIMEOUT是200s

如果超过上面时间,没有移除SERVICE_TIMEOUT_MSG消息,就会弹出ANR消息。

10.10 ActivityThread.scheduleCreateService
  1. app.thread.scheduleCreateService(r, r.serviceInfo,mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),app.repProcState);
复制

其实调用的方法是ApplicationThreadProxy中的scheduleCreateService(),代码写在ApplicationThreadNative.java中

  1.   public final void scheduleCreateService(IBinder token, ServiceInfo info,
  2.           CompatibilityInfo compatInfo, int processState) throws RemoteException {
  3.       Parcel data = Parcel.obtain();
  4.       data.writeInterfaceToken(IApplicationThread.descriptor);
  5.       data.writeStrongBinder(token);
  6.       info.writeToParcel(data, 0);
  7.       compatInfo.writeToParcel(data, 0);
  8.       data.writeInt(processState);
  9.       try {
  10.           【是不是很熟悉,,,binder....然后到了ApplicationThreadNativeonTransact()】
  11.           mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
  12.                   IBinder.FLAG_ONEWAY);
  13.       } catch (TransactionTooLargeException e) {
  14.           Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info);
  15.           throw e;
  16.       }
  17.       data.recycle();
  18.   }
复制

mRemote.transact()这是不是很熟悉啊,,参考前面《Android 6.0 启动startService()源码分析(1)》中ActivityManagerProxy、ActivityManagerNative和ActivityManagerService的关系,这里省略

最后运行到了ApplicationThread.scheduleCreateService()

10.11 ApplicationThread.scheduleCreateService()

ApplicationThread是在ActivityThread.java中

  1.     public final void scheduleCreateService(IBinder token,
  2.               ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
  3.           updateProcessState(processState, false);
  4.           CreateServiceData s = new CreateServiceData();
  5.           s.token = token;
  6.           s.info = info;
  7.           s.compatInfo = compatInfo;
  8.           【发送CREATE_SERVICE消息】
  9.           sendMessage(H.CREATE_SERVICE, s);
  10.     }
  11.   case CREATE_SERVICE:
  12.             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
  13.             handleCreateService
  14.             handleCreateService((CreateServiceData)msg.obj);
  15.             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  16.             break;
  17.   private void handleCreateService(CreateServiceData data) {
  18.       // If we are getting ready to gc after going to the background, well
  19.       // we are back active so skip it.
  20.       unscheduleGcIdler();
  21.       .....
  22.       try {
  23.           if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
  24.           ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
  25.           context.setOuterContext(service);
  26.           Application app = packageInfo.makeApplication(false, mInstrumentation);
  27.           service.attach(context, this, data.info.name, data.token, app,
  28.                   ActivityManagerNative.getDefault());
  29.           service.onCreate()创建】
  30.           service.onCreate();
  31.           mServices.put(data.token, service);
  32.           try {
  33.               10.12 这里调用的是ActivityManagerService.serviceDoneExecuting()此时出传入type=SERVICE_DONE_EXECUTING_ANON
  34.               ActivityManagerNative.getDefault().serviceDoneExecuting(
  35.                       data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
  36.           } catch (RemoteException e) {
  37.               // nothing to do.
  38.           }
  39.       } catch (Exception e) {
  40.           if (!mInstrumentation.onException(service, e)) {
  41.               throw new RuntimeException(
  42.                   "Unable to create service " + data.info.name
  43.                   + ": " + e.toString(), e);
  44.           }
  45.       }
  46.   }
复制
10.12 ActivityManagerService.serviceDoneExecuting()
  1.   public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
  2.       synchronized(this) {
  3.           if (!(token instanceof ServiceRecord)) {
  4.               Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
  5.               throw new IllegalArgumentException("Invalid service token");
  6.           }
  7.           10.13 serviceDoneExecutingLocked
  8.           mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
  9.       }
  10.   }
复制
10.13 ActiveServices.serviceDoneExecutingLocked()

在onCreate时候传入的type是SERVICE_DONE_EXECUTING_ANON,上面可以看到。

  1.   void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
  2.       boolean inDestroying = mDestroyingServices.contains(r);
  3.       if (r != null) {
  4.           if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
  5.             .....
  6.           } else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
  7.             ......
  8.           }
  9.           final long origId = Binder.clearCallingIdentity();
  10.           // 10.14 type 都不符合上面条件,因此直接走这里serviceDoneExecutingLocked
  11.           serviceDoneExecutingLocked(r, inDestroying, inDestroying);
  12.           Binder.restoreCallingIdentity(origId);
  13.       } else {
  14.           Slog.w(TAG, "Done executing unknown service from pid "
  15.                   + Binder.getCallingPid());
  16.       }
  17.   }
复制
10.14 serviceDoneExecutingLocked
  1.   private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
  2.           boolean finishing) {
  3.       r.executeNesting--;
  4.       if (r.executeNesting <= 0) {
  5.           if (r.app != null) {
  6.               if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
  7.                       "Nesting at 0 of " + r.shortName);
  8.               r.app.execServicesFg = false;
  9.               r.app.executingServices.remove(r);
  10.               if (r.app.executingServices.size() == 0) {
  11.                   if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
  12.                           "No more executingServices of " + r.shortName);
  13.                   【移除超时SERVICE_TIMEOUT_MSG消息,否则就会ANR
  14.                   mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
  15.               } else if (r.executeFg) {
  16.                   // Need to re-evaluate whether the app still needs to be in the foreground.
  17.                   for (int i=r.app.executingServices.size()-1; i>=0; i--) {
  18.                       if (r.app.executingServices.valueAt(i).executeFg) {
  19.                           r.app.execServicesFg = true;
  20.                           break;
  21.                       }
  22.                   }
  23.               }
  24.       ......
  25.       }
  26.   }
复制

如果没有移除超时消息SERVICE_TIMEOUT_MSG,就会ANR。

onCreate()执行完后,接着是前面提到的sendServiceArgsLocked(),我们继续

11. 0 sendServiceArgsLocked

服务进入onStartCommand()

  1. private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
  2. boolean oomAdjusted) throws TransactionTooLargeException {
  3. final int N = r.pendingStarts.size();
  4. if (N == 0) {
  5. return;
  6. }
  7.  
  8. while (r.pendingStarts.size() > 0) {
  9. Exception caughtException = null;
  10. ServiceRecord.StartItem si;
  11. try {
  12. si = r.pendingStarts.remove(0);
  13. if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: "
  14. + r + " " + r.intent + " args=" + si.intent);
  15. if (si.intent == null && N > 1) {
  16. // If somehow we got a dummy null intent in the middle,
  17. // then skip it. DO NOT skip a null intent when it is
  18. // the only one in the list -- this is to support the
  19. // onStartCommand(null) case.
  20. continue;
  21. }
  22. si.deliveredTime = SystemClock.uptimeMillis();
  23. r.deliveredStarts.add(si);
  24. si.deliveryCount++;
  25. if (si.neededGrants != null) {
  26. mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
  27. si.getUriPermissionsLocked());
  28. }
  29. 【和 10.9 ActiveServices.bumpServiceExecutingLocked 发送SERVICE_TIMEOUT_MSG用来判断是否ANR,一样】
  30. bumpServiceExecutingLocked(r, execInFg, "start");
  31. if (!oomAdjusted) {
  32. oomAdjusted = true;
  33. mAm.updateOomAdjLocked(r.app);
  34. }
  35. int flags = 0;
  36. if (si.deliveryCount > 1) {
  37. flags |= Service.START_FLAG_RETRY;
  38. }
  39. if (si.doneExecutingCount > 0) {
  40. flags |= Service.START_FLAG_REDELIVERY;
  41. }
  42. 【启动onStartCommand,这个和启动onCreate()的路径都一样,这里都不在重复】
  43. r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
  44. } catch (TransactionTooLargeException e) {
  45. if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large: intent="
  46. + si.intent);
  47. caughtException = e;
  48. } catch (RemoteException e) {
  49. // Remote process gone... we'll let the normal cleanup take care of this.
  50. if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);
  51. caughtException = e;
  52. } catch (Exception e) {
  53. Slog.w(TAG, "Unexpected exception", e);
  54. caughtException = e;
  55. }
  56.  
  57. if (caughtException != null) {
  58. // Keep nesting count correct
  59. final boolean inDestroying = mDestroyingServices.contains(r);
  60. serviceDoneExecutingLocked(r, inDestroying, inDestroying);
  61. if (caughtException instanceof TransactionTooLargeException) {
  62. throw (TransactionTooLargeException)caughtException;
  63. }
  64. break;
  65. }
  66. }
  67. }
复制

启动onStartCommand()和onCreate()流程差不多,这个就不再重复。流程很长,细节部分都丢了。

总结

1、在流程中,我们看到了在ActivityThread.java中初始化了Looper.prepareMainLooper()和开启了Looper.loop()

2、前台服务20m没有执行完就会ANR,后台服务200s没有启动就ANR

相关文章

1 条评论

  • Yu
    Yu管理员

    太久了,略过吧

    回复