Android8.0.0-r4 ——Service的启动过程

Service组件在新进程中的启动过程主要过程如下所示:

1.Client组件向AMS发送一个启动Server组件的进程间通信请求

2.AMS发现用来运行Server组件的应用程序进程不存在,先将Server组件的信息保存下来,接着创建一个新的应用程序进程

3.新进程启动完成后向AMS发送一个启动完成的进程间通信请求,以便AMS可以继续启动Server组件的操作。

4.AMS将第二步保存下来的Server组件信息发送给第二步创建的应用程序进程,将Server组件启动起来。


 1.ContextWrapper.startService

代码路径:/frameworks/base/core/java/android/content/ContextWrapper.java
 (http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/content/ContextWrapper.java)

 
642    @Override
643    public ComponentName startService(Intent service) {
644        return mBase.startService(service);
645    }

要启动Service,会调用startService方法,它的实现在ContextWrapper中


 2.ContextImpl.startService

代码路径:/frameworks/base/core/java/android/app/ContextImpl.java
 (http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ContextImpl.java)

1458    @Override
1459    public ComponentName startService(Intent service) {
1460        warnIfCallingFromSystemProcess();
1461        return startServiceCommon(service, false, mUser);
1462    }

startService方法中会return startServiceCommon方法


3.ContextImpl.startServiceCommon

代码路径:/frameworks/base/core/java/android/app/ContextImpl.java

 (http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ContextImpl.java)
 
1486    private ComponentName startServiceCommon(Intent service, boolean requireForeground,
1487            UserHandle user) {
1488        try {
1489            validateServiceIntent(service);
1490            service.prepareToLeaveProcess(this);
1491            ComponentName cn = ActivityManager.getService().startService(
1492                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
1493                            getContentResolver()), requireForeground,
1494                            getOpPackageName(), user.getIdentifier());
1495            if (cn != null) {
1496                if (cn.getPackageName().equals("!")) {
1497                    throw new SecurityException(
1498                            "Not allowed to start service " + service
1499                            + " without permission " + cn.getClassName());
1500                } else if (cn.getPackageName().equals("!!")) {
1501                    throw new SecurityException(
1502                            "Unable to start service " + service
1503                            + ": " + cn.getClassName());
1504                } else if (cn.getPackageName().equals("?")) {
1505                    throw new IllegalStateException(
1506                            "Not allowed to start service " + service + ": " + cn.getClassName());
1507                }
1508            }
1509            return cn;
1510        } catch (RemoteException e) {
1511            throw e.rethrowFromSystemServer();
1512        }
1513    }

在startServiceCommon方法中会在1491行调用ActivityManageService(AMS)的代理对象的startService方法,最终会调用AMS的startService方法

这里与Android 7.0代码的逻辑有些不同,Android 7.0是通过ActivityManagerNative的getDefault来获取AMS的代理对象,现在这个逻辑封装到了ActivityManager中而不是ActivityManagerNative中


4.ActivityManagerService.startService

代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)
18124    @Override
18125    public ComponentName startService(IApplicationThread caller, Intent service,
18126            String resolvedType, boolean requireForeground, String callingPackage, int userId)
18127            throws TransactionTooLargeException {
18128        enforceNotIsolatedCaller("startService");
18129        // Refuse possible leaked file descriptors
18130        if (service != null && service.hasFileDescriptors() == true) {
18131            throw new IllegalArgumentException("File descriptors passed in Intent");
18132        }
18133
18134        if (callingPackage == null) {
18135            throw new IllegalArgumentException("callingPackage cannot be null");
18136        }
18137
18138        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18139                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18140        synchronized(this) {
18141            final int callingPid = Binder.getCallingPid();
18142            final int callingUid = Binder.getCallingUid();
18143            final long origId = Binder.clearCallingIdentity();
18144            ComponentName res;
18145            try {
18146                res = mServices.startServiceLocked(caller, service,
18147                        resolvedType, callingPid, callingUid,
18148                        requireForeground, callingPackage, userId);
18149            } finally {
18150                Binder.restoreCallingIdentity(origId);
18151            }
18152            return res;
18153        }
18154    }

在18146行调用mServices的startServiceLocked方法,mServices的类型是ActiveServices(1023行定义的mServices)

5.ActiveServices.startServiceLocked

代码路径:/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

 (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java)
 
327    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
328            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
329            throws TransactionTooLargeException {
...................................................
477
478        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
479        return cmp;
480    }
 

        ............................................................................

526    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
527            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
528        ServiceState stracker = r.getTracker();
529        if (stracker != null) {
530            stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
531        }
532        r.callStart = false;
533        synchronized (r.stats.getBatteryStats()) {
534            r.stats.startRunningLocked();
535        }
536        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
537        if (error != null) {
538            return new ComponentName("!!", error);
539        }
540
541        if (r.startRequested && addToStarting) {
542            boolean first = smap.mStartingBackground.size() == 0;
543            smap.mStartingBackground.add(r);
544            r.startingBgTimeout = SystemClock.uptimeMillis() + mAm.mConstants.BG_START_TIMEOUT;
545            if (DEBUG_DELAYED_SERVICE) {
546                RuntimeException here = new RuntimeException("here");
547                here.fillInStackTrace();
548                Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
549            } else if (DEBUG_DELAYED_STARTS) {
550                Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
551            }
552            if (first) {
553                smap.rescheduleDelayedStartsLocked();
554            }
555        } else if (callerFg || r.fgRequired) {
556            smap.ensureNotStartingBackgroundLocked(r);
557        }
558
559        return r.name;
560    }

startServiceLocked方法的末尾478行return了startServiceInnerLocked方法;

startServiceInnerLocked方法中在536行又调用了bringUpServiceLocked方法


6.ActiveServices.bringUpServiceLocked

代码路径:/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

 (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java)
2052    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
2053            boolean whileRestarting, boolean permissionsReviewRequired)
2054            throws TransactionTooLargeException {
             ...............................................
2107        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
2108        final String procName = r.processName;
2109        String hostingType = "service";
2110        ProcessRecord app;
2111
2112        if (!isolated) {
2113            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
2114            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
2115                        + " app=" + app);
2116            if (app != null && app.thread != null) {
2117                try {
2118                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
2119                    realStartServiceLocked(r, app, execInFg);
2120                    return null;
2121                } catch (TransactionTooLargeException e) {
2122                    throw e;
2123                } catch (RemoteException e) {
2124                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
2125                }
2126
2127                // If a dead object exception was thrown -- fall through to
2128                // restart the application.
2129            }
2130        } else {
2131            // If this service runs in an isolated process, then each time
2132            // we call startProcessLocked() we will get a new isolated
2133            // process, starting another process if we are currently waiting
2134            // for a previous process to come up.  To deal with this, we store
2135            // in the service any current isolated process it is running in or
2136            // waiting to have come up.
2137            app = r.isolatedProc;
2138            if (WebViewZygote.isMultiprocessEnabled()
2139                    && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
2140                hostingType = "webview_service";
2141            }
2142        }
2143
2144        // Not running -- get it started, and enqueue this service record
2145        // to be executed when the app comes up.
2146        if (app == null && !permissionsReviewRequired) {
2147            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
2148                    hostingType, r.name, false, isolated, false)) == null) {
2149                String msg = "Unable to launch app "
2150                        + r.appInfo.packageName + "/"
2151                        + r.appInfo.uid + " for service "
2152                        + r.intent.getIntent() + ": process is bad";
2153                Slog.w(TAG, msg);
2154                bringDownServiceLocked(r);
2155                return msg;
2156            }
2157            if (isolated) {
2158                r.isolatedProc = app;
2159            }
2160        }
2161
           .......................................
2175
2176        return null;
2177    }

在2108行得到ServiceRecord的processName的值赋值给procName ,其中ServiceRecord用来描述Service的android:process属性。

在2113行将procName和Service的uid传入到AMS的getProcessRecordLocked方法中,来查询是否存在一个与Service对应的ProcessRecord类型的对象app,ProcessRecord主要用来记录运行的应用程序进程的信息。

在2146行判断Service对应的app为null则说明用来运行Service的应用程序进程不存在,则调用在2146行的AMS的startProcessLocked方法来创建对应的应用程序进程。

在2116行判断如果用来运行Service的应用程序进程存在,则调用2119行的realStartServiceLocked方法。

7.ActiveServices.realStartServiceLocked

代码路径:/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

 (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java)
2189    private final void realStartServiceLocked(ServiceRecord r,
2190            ProcessRecord app, boolean execInFg) throws RemoteException {
       .................................
2207        try {
2208            if (LOG_SERVICE_START_STOP) {
2209                String nameTerm;
2210                int lastPeriod = r.shortName.lastIndexOf('.');
2211                nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
2212                EventLogTags.writeAmCreateService(
2213                        r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
2214            }
2215            synchronized (r.stats.getBatteryStats()) {
2216                r.stats.startLaunchedLocked();
2217            }
2218            mAm.notifyPackageUse(r.serviceInfo.packageName,
2219                                 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
2220            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
2221            app.thread.scheduleCreateService(r, r.serviceInfo,
2222                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
2223                    app.repProcState);
2224            r.postNotification();
2225            created = true;
2226        } catch (DeadObjectException e) {
2227            Slog.w(TAG, "Application dead when creating service " + r);
2228            mAm.appDiedLocked(app);
2229            throw e;
2230        } finally {
2231            if (!created) {
2232                // Keep the executeNesting count accurate.
2233                final boolean inDestroying = mDestroyingServices.contains(r);
2234                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
2235
2236                // Cleanup.
2237                if (newService) {
2238                    app.services.remove(r);
2239                    r.app = null;
2240                }
2241
2242                // Retry.
2243                if (!inDestroying) {
2244                    scheduleServiceRestartLocked(r, false);
2245                }
2246            }
2247        }
2248
     ............................................
2282    }

在realStartServiceLocked方法中调用了2221行的app.thread的scheduleCreateService方法。

其中app.thread是IApplicationThread类型的,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口。


8.ActivityThread.scheduleCreateService

代码路径:/frameworks/base/core/java/android/app/ActivityThread.java

 (http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)

首先将要启动的信息封装成CreateServiceData 对象并传给sendMessage方法,sendMessage方法向H发送CREATE_SERVICE消息,H是ActivityThread的内部类并继承Handler。这个过程和根Activity启动过程是类似的。我们接着查看H的handleMessage方法。 

9.ActivityThread.handleMessage

代码路径:/frameworks/base/core/java/android/app/ActivityThread.java

 (http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)
1584        public void handleMessage(Message msg) {
1585            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1586            switch (msg.what) {

      ................................................
1681                case CREATE_SERVICE:
1682                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
1683                    handleCreateService((CreateServiceData)msg.obj);
1684                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1685                    break;
      ................................................
1859            }
1860            Object obj = msg.obj;
1861            if (obj instanceof SomeArgs) {
1862                ((SomeArgs) obj).recycle();
1863            }
1864            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
1865        }

在1683行handleMessage方法根据消息类型,调用了handleCreateService方法


10.ActivityThread.handleCreateService

代码路径:/frameworks/base/core/java/android/app/ActivityThread.java

 (http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)
3376    private void handleCreateService(CreateServiceData data) {
3377        // If we are getting ready to gc after going to the background, well
3378        // we are back active so skip it.
3379        unscheduleGcIdler();
3380
3381        LoadedApk packageInfo = getPackageInfoNoCheck(
3382                data.info.applicationInfo, data.compatInfo);
3383        Service service = null;
3384        try {
3385            java.lang.ClassLoader cl = packageInfo.getClassLoader();
3386            service = (Service) cl.loadClass(data.info.name).newInstance();
3387        } catch (Exception e) {
3388            if (!mInstrumentation.onException(service, e)) {
3389                throw new RuntimeException(
3390                    "Unable to instantiate service " + data.info.name
3391                    + ": " + e.toString(), e);
3392            }
3393        }
3394
3395        try {
3396            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
3397
3398            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
3399            context.setOuterContext(service);
3400
3401            Application app = packageInfo.makeApplication(false, mInstrumentation);
3402            service.attach(context, this, data.info.name, data.token, app,
3403                    ActivityManager.getService());
3404            service.onCreate();
3405            mServices.put(data.token, service);
3406            try {
3407                ActivityManager.getService().serviceDoneExecuting(
3408                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3409            } catch (RemoteException e) {
3410                throw e.rethrowFromSystemServer();
3411            }
3412        } catch (Exception e) {
3413            if (!mInstrumentation.onException(service, e)) {
3414                throw new RuntimeException(
3415                    "Unable to create service " + data.info.name
3416                    + ": " + e.toString(), e);
3417            }
3418        }
3419    }

在3381行获取要启动Service的应用程序的LoadedApk,LoadedApk是一个APK文件的描述类。

在3385行通过调用LoadedApk的getClassLoader方法来获取类加载器。

在3386行根据CreateServiceData对象中存储的Service信息,将Service加载到内存中。

在3398行创建Service的上下文环境ContextImpl对象。

在3402行通过Service的attach方法来初始化Service。

在3404行调用Service的onCreate方法,这样Service就启动了。

在3405行将启动的Service加入到ActivityThread的成员变量mServices中,其中mServices是ArrayMap类型。

240    final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值