目录
- 10.9 ActiveServices.bumpServiceExecutingLocked
- 10.9.1 发送SERVICE_TIMEOUT_MSG
- 10.10 ActivityThread.scheduleCreateService
- 10.11 ApplicationThread.scheduleCreateService()
- 10.12 ActivityManagerService.serviceDoneExecuting()
- 10.13 ActiveServices.serviceDoneExecutingLocked()
- 10.14 serviceDoneExecutingLocked
- 11. 0 sendServiceArgsLocked
》
10.9 ActiveServices.bumpServiceExecutingLocked
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, ">>> EXECUTING " + why + " of " + r + " in app " + r.app); else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, ">>> EXECUTING " + why + " of " + r.shortName); long now = SystemClock.uptimeMillis(); 【executeNesting 记录前台次数,第一次为0,fg是启动前台还是后台服务】 if (r.executeNesting == 0) { r.executeFg = fg; ProcessStats.ServiceState stracker = r.getTracker(); if (stracker != null) { stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now); } if (r.app != null) { r.app.executingServices.add(r); r.app.execServicesFg |= fg; if (r.app.executingServices.size() == 1) { scheduleServiceTimeoutLocked(r.app); 【10.9.1 发送SERVICE_TIMEOUT_MSG】 } } } else if (r.app != null && fg && !r.app.execServicesFg) { r.app.execServicesFg = true; scheduleServiceTimeoutLocked(r.app); } r.executeFg |= fg; r.executeNesting++; r.executingStart = now; }
10.9.1 发送SERVICE_TIMEOUT_MSG
void scheduleServiceTimeoutLocked(ProcessRecord proc) { if (proc.executingServices.size() == 0 || proc.thread == null) { return; } long now = SystemClock.uptimeMillis(); Message msg = mAm.mHandler.obtainMessage( ActivityManagerService.SERVICE_TIMEOUT_MSG); msg.obj = proc; 【发送SERVICE_TIMEOUT_MSG消息】 mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT)); }
前台服务 SERVICE_TIMEOUT是20s
后台服务 SERVICE_BACKGROUND_TIMEOUT是200s
如果超过上面时间,没有移除SERVICE_TIMEOUT_MSG消息,就会弹出ANR消息。
10.10 ActivityThread.scheduleCreateService
app.thread.scheduleCreateService(r, r.serviceInfo,mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),app.repProcState);
其实调用的方法是ApplicationThreadProxy中的scheduleCreateService(),代码写在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); try { 【是不是很熟悉,,,binder....然后到了ApplicationThreadNative的onTransact()】 mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); } catch (TransactionTooLargeException e) { Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info); throw e; } data.recycle(); }
mRemote.transact()这是不是很熟悉啊,,参考前面《》中ActivityManagerProxy、ActivityManagerNative和ActivityManagerService的关系,这里省略
最后运行到了ApplicationThread.scheduleCreateService()
10.11 ApplicationThread.scheduleCreateService()
ApplicationThread是在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; 【发送CREATE_SERVICE消息】 sendMessage(H.CREATE_SERVICE, s); } case CREATE_SERVICE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate"); 【handleCreateService】 handleCreateService((CreateServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; 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(); ..... 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()创建】 service.onCreate(); mServices.put(data.token, service); try { 【10.12 这里调用的是ActivityManagerService.serviceDoneExecuting()此时出传入type=SERVICE_DONE_EXECUTING_ANON 】 ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } catch (RemoteException e) { // nothing to do. } } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to create service " + data.info.name + ": " + e.toString(), e); } } }
10.12 ActivityManagerService.serviceDoneExecuting()
public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { synchronized(this) { if (!(token instanceof ServiceRecord)) { Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); throw new IllegalArgumentException("Invalid service token"); } 【10.13 serviceDoneExecutingLocked】 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); } }
10.13 ActiveServices.serviceDoneExecutingLocked()
在onCreate时候传入的type是SERVICE_DONE_EXECUTING_ANON,上面可以看到。
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) { boolean inDestroying = mDestroyingServices.contains(r); if (r != null) { if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) { ..... } else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) { ...... } final long origId = Binder.clearCallingIdentity(); // 10.14 type 都不符合上面条件,因此直接走这里serviceDoneExecutingLocked serviceDoneExecutingLocked(r, inDestroying, inDestroying); Binder.restoreCallingIdentity(origId); } else { Slog.w(TAG, "Done executing unknown service from pid " + Binder.getCallingPid()); } }
10.14 serviceDoneExecutingLocked
private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying, boolean finishing) { r.executeNesting--; if (r.executeNesting <= 0) { if (r.app != null) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Nesting at 0 of " + r.shortName); r.app.execServicesFg = false; r.app.executingServices.remove(r); if (r.app.executingServices.size() == 0) { if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, "No more executingServices of " + r.shortName); 【移除超时SERVICE_TIMEOUT_MSG消息,否则就会ANR】 mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app); } else if (r.executeFg) { // Need to re-evaluate whether the app still needs to be in the foreground. for (int i=r.app.executingServices.size()-1; i>=0; i--) { if (r.app.executingServices.valueAt(i).executeFg) { r.app.execServicesFg = true; break; } } } ...... } }
如果没有移除超时消息SERVICE_TIMEOUT_MSG,就会ANR。
onCreate()执行完后,接着是前面提到的sendServiceArgsLocked(),我们继续
11. 0 sendServiceArgsLocked
服务进入onStartCommand()
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg, boolean oomAdjusted) throws TransactionTooLargeException { final int N = r.pendingStarts.size(); if (N == 0) { return; } while (r.pendingStarts.size() > 0) { Exception caughtException = null; ServiceRecord.StartItem si; try { si = r.pendingStarts.remove(0); if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: " + r + " " + r.intent + " args=" + si.intent); if (si.intent == null && N > 1) { // If somehow we got a dummy null intent in the middle, // then skip it. DO NOT skip a null intent when it is // the only one in the list -- this is to support the // onStartCommand(null) case. continue; } si.deliveredTime = SystemClock.uptimeMillis(); r.deliveredStarts.add(si); si.deliveryCount++; if (si.neededGrants != null) { mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants, si.getUriPermissionsLocked()); } 【和 10.9 ActiveServices.bumpServiceExecutingLocked 发送SERVICE_TIMEOUT_MSG用来判断是否ANR,一样】 bumpServiceExecutingLocked(r, execInFg, "start"); if (!oomAdjusted) { oomAdjusted = true; mAm.updateOomAdjLocked(r.app); } int flags = 0; if (si.deliveryCount > 1) { flags |= Service.START_FLAG_RETRY; } if (si.doneExecutingCount > 0) { flags |= Service.START_FLAG_REDELIVERY; } 【启动onStartCommand,这个和启动onCreate()的路径都一样,这里都不在重复】 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); } catch (TransactionTooLargeException e) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large: intent=" + si.intent); caughtException = e; } catch (RemoteException e) { // Remote process gone... we'll let the normal cleanup take care of this. if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r); caughtException = e; } catch (Exception e) { Slog.w(TAG, "Unexpected exception", e); caughtException = e; } if (caughtException != null) { // Keep nesting count correct final boolean inDestroying = mDestroyingServices.contains(r); serviceDoneExecutingLocked(r, inDestroying, inDestroying); if (caughtException instanceof TransactionTooLargeException) { throw (TransactionTooLargeException)caughtException; } break; } } }
启动onStartCommand()和onCreate()流程差不多,这个就不再重复。流程很长,细节部分都丢了。
总结
1、在流程中,我们看到了在ActivityThread.java中初始化了Looper.prepareMainLooper()和开启了Looper.loop()
历史上的今天
随机推荐
刘大白:秋江的晚上
归巢的鸟儿, 尽管是倦了, 还驮着斜阳回去。 双翅一翻, 把斜阳掉在江上; 头白的芦苇, 也妆成一瞬的红颜了。
[代码片段]MediaCode 播放Video中的视频帧[无声]
前言 这就只做使用MediaCodec+SurfaceView播放视频 PS 这里不涉及音频播放,只显示视频帧出来。 正文 这里只简单记录一下,推荐看我参考的文章,我用的就是...
白岩松:幸福在哪里
一 走在人群中,我习惯看一看周围人的手腕,那里似乎藏着一个属于当代中国人的内心秘密,从不言说,却日益增多。 越来越多的人,不分男女,会戴上一个手串,...
里柯克:吃饼冠军乔.布朗
我们当中的一位伟大人物。 吃饼冠军乔.布朗给人的第一个印象是不嚣张,没架子,身材并不怎么出众,举止坦率随便,一点儿也不让人感到拘束。 “请坐吧,”他朝...
StorageManagerService的启动
前言 最近在看磁盘的挂载相关内容,涉及StorageManagerService,因此记录一下其的启动等相关内容,方便后续查阅和回顾。 个人流水文章,也就是只是方便自己而...
乔叶:曾经这样爱过你
曾经这样爱过一个人:爱的人知道,被爱的人不知道,这是暗恋吗? 爱着的时候,就整天鬼迷心窍地琢磨着你。 你偶然有句话,就想着你为什么要这样说?你在说给...
太久了,略过吧