四大組件之Service(一)-Service啟動(dòng)過(guò)程

Service啟動(dòng)過(guò)程與Activity類(lèi)似,了解了Activity啟動(dòng)之后來(lái)看Service就容易了,那么還是來(lái)簡(jiǎn)單過(guò)一下流程,先看一張整體流程圖:

應(yīng)用層startService 最終通過(guò)Binder IPC 到AMS:

Context關(guān)系以后再講,這里其實(shí)我們都知道Context是個(gè)抽象類(lèi),真正干活的是ContextImpl. 由它執(zhí)行真正的startService操作:

@Override
public ComponentName startService(Intent service) {
    warnIfCallingFromSystemProcess();
    return startServiceCommon(service, false, mUser);
}

private ComponentName startServiceCommon(Intent service, boolean requireForeground,
        UserHandle user) {
    try {
        ...
        ComponentName cn = ActivityManager.getService().startService(
            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                        getContentResolver()), requireForeground,
                        getOpPackageName(), user.getIdentifier());
        ...
}

這是典型的binder ipc過(guò)程了,話不多說(shuō)。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override
public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, boolean requireForeground, String callingPackage, int userId)
        throws TransactionTooLargeException {
        ...
            res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid,
                    requireForeground, callingPackage, userId);
        ...
        return res;
    }
}

執(zhí)行startServiceLocked:

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
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;
   }

startServiceLocked 和startServiceInnerLocked 對(duì)應(yīng)于Activity中的startActivityMayWait和startActivity的過(guò)程,無(wú)非也就是一些檢驗(yàn)和初始化的工作。而startServiceInnerLocked方法中又調(diào)用了bringUpServiceLocked方法.

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
...
  final String procName = r.processName;
  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.versionCode,
                    mAm.mProcessStats);
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } 
         ...
if (app == null && !permissionsReviewRequired) {
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {
              ...
            }
          ...
        }
...     

}

該方法可以對(duì)比于Activity啟動(dòng)的startSpecificActivityLocked,也是一個(gè)分叉路,如果進(jìn)程存在則調(diào)用realStartServiceLocked去schedule Service應(yīng)用層的啟動(dòng),如果不存在,則socket通知Zygote去fork進(jìn)程,然后再回來(lái)schedule Service。Zygote去fork進(jìn)程部分與Activity啟動(dòng)部分并無(wú)太大差別,那么直接來(lái)看startSpecificActivityLocked:

private final void realStartServiceLocked(ServiceRecord r,
       ProcessRecord app, boolean execInFg) throws RemoteException {
  ...
   try {
      ...
       app.thread.scheduleCreateService(r, r.serviceInfo,
               mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
               app.repProcState);
       r.postNotification();
       created = true;
   } catch (DeadObjectException e) {
     ...
   }
   ...
}

app.thread是IApplicationThread類(lèi)型的,它的實(shí)現(xiàn)是ActivityThread的內(nèi)部類(lèi)ApplicationThread。

frameworks/base/core/java/android/app/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;
    sendMessage(H.CREATE_SERVICE, s);
}

到了ActivityThread的地界,那就是靠消息驅(qū)動(dòng)運(yùn)轉(zhuǎn)的世界了,由H發(fā)送CREATE_SERVICE的消息,然后在handleMessage對(duì)應(yīng)的case中執(zhí)行的是handleCreateService

private void handleCreateService(CreateServiceData data) {
      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) {
         ...
          }
      }
      try {
          if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
          ContextImpl context = ContextImpl.createAppContext(this, packageInfo);//4
          context.setOuterContext(service);
          Application app = packageInfo.makeApplication(false, mInstrumentation);
          service.attach(context, this, data.info.name, data.token, app,
                  ActivityManagerNative.getDefault());//5
          service.onCreate();//6
          mServices.put(data.token, service);//7
       ...
      } catch (Exception e) {
          ...
      }
  }

這里主要干兩件事:

  • 將service load到內(nèi)存

  • 通過(guò)Service的attach方法來(lái)初始化Service,然后走Service的onCreate方法,這樣Service就啟動(dòng)了。

好了今天就簡(jiǎn)單地總結(jié)了下Service的啟動(dòng)過(guò)程,下篇接著看看Service的綁定過(guò)程。

參考:
http://gityuan.com/2016/03/06/start-service/
http://liuwangshu.cn/framework/component/2-service-start.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容