美文网首页
startService流程梳理

startService流程梳理

作者: 付凯强 | 来源:发表于2023-04-26 22:07 被阅读0次

    app

    MainActivity.java:

    startService(new Intent(this,TestService.class));
    

    ContextWrapper.java

        @Override
        public @Nullable ComponentName startService(Intent service) {
            return mBase.startService(service);
        }
    

    这里的mBase是代理模式,其对象是ContextImpl对象。

    ContextImpl.java

        @Override
        public ComponentName startService(Intent service) {
            warnIfCallingFromSystemProcess();
            return startServiceCommon(service, false, mUser);
        }
    
    private ComponentName startServiceCommon(Intent service, boolean requireForeground,
                UserHandle user) {
                ...
                ComponentName cn = ActivityManager.getService().startService(
                    mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                                getContentResolver()), requireForeground,
                                getOpPackageName(), user.getIdentifier());
                ...
        }
    

    ActivityManager.getService().startService 通过binder通信,会调用ActivityManagerService中的startService。

    system_server

    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);
            ...
        }
    

    mServices是类型为ActiveServices。

    ActiveServices.java

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
                int callingPid, int callingUid, boolean fgRequired, String callingPackage,
                final int userId, boolean allowBackgroundActivityStarts)
                throws TransactionTooLargeException {
        ...
            ComponentName cmp = 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;
        }
    

    它的返回值是ComponentName,与startService相同,在执行完bringUpServiceLocked之后就返回了,所以重点看下bringUpServiceLocked方法。

    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
                boolean whileRestarting, boolean permissionsReviewRequired)
                throws TransactionTooLargeException {
            // 第一种情况: 当进程存在,service存在
            if (r.app != null && r.app.thread != null) {
                sendServiceArgsLocked(r, execInFg, false);
                return null;
            }
            // 第二种情况:当进程存在,service不存在
            if (!isolated) {
                if (app != null && app.thread != null) {
                        realStartServiceLocked(r, app, execInFg);
                }
            }
            // 第三种情况:当进程不存在,service自然也不存在
            if (app == null && !permissionsReviewRequired) {
                if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                        hostingRecord, false, isolated, false)) == null) {
                }
            }
    }
    

    以上三种情形分别会调用不同的方法进行处理,现在就分别看下这三个方法的实现。

    1. sendServiceArgsLocked方法
    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
                boolean oomAdjusted) throws TransactionTooLargeException {
                bumpServiceExecutingLocked(r, execInFg, "start");
                r.app.thread.scheduleServiceArgs(r, slice);
    }
    

    scheduleServiceArgs是发送应用的binder调用,对应应用中的onStartCommand方法。

    1. realStartServiceLocked方法
        private final void realStartServiceLocked(ServiceRecord r,
                ProcessRecord app, boolean execInFg) throws RemoteException {
            bumpServiceExecutingLocked(r, execInFg, "create");
            ...
                app.thread.scheduleCreateService(r, r.serviceInfo,
                        mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                        app.getReportedProcState());
            ...
            requestServiceBindingsLocked(r, execInFg);
            ...
            sendServiceArgsLocked(r, execInFg, true);
            ...
        }
    
        private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
                throws TransactionTooLargeException {
        ...
                if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
        ...
        }
    
    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
                boolean execInFg, boolean rebind) throws TransactionTooLargeException {
    ...
                    bumpServiceExecutingLocked(r, execInFg, "bind");
    ...
                    r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                            r.app.getReportedProcState());
                    ...
        }
    

    realStartServiceLocked方法会执行三个主逻辑,并分别对应三个binder调用,分别是scheduleCreateService、scheduleBindService、scheduleServiceArgs,并分别对应binder对端,即app service组件的onCreate、onBind、onStartCommand方法。

    1. startProcessLocked方法

    这里不再详述,但能想到它会做两件事情,第一件事情是创建进程,第二件事情就是执行realStartServiceLocked,因为realStartServiceLocked对应了“当进程存在,service不存在”这种场景。

    app

    ActivityThread.java

    1. scheduleCreateService
            public final void scheduleCreateService(IBinder token,
                    ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
                ...
                sendMessage(H.CREATE_SERVICE, s);
            }
    
    1. scheduleBindService
            public final void scheduleBindService(IBinder token, Intent intent,
                    boolean rebind, int processState) {
                ...
                sendMessage(H.BIND_SERVICE, s);
            }
    
    1. scheduleServiceArgs
            public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
                    ...
                    sendMessage(H.SERVICE_ARGS, s);
                }
            }
    

    scheduleCreateService、scheduleBindService、scheduleServiceArgs三个方法其实运行在binder线程,这个时候需要通过消息机制的sendMessage让主线程去执行相应的操作。分别对应下面的三个case:

    1. CREATE_SERVICE
                    case CREATE_SERVICE:
                        handleCreateService((CreateServiceData)msg.obj);
                        break;
    
    1. BIND_SERVICE
                    case BIND_SERVICE:
                        handleBindService((BindServiceData)msg.obj);
                        break;
    
    1. SERVICE_ARGS
                    case SERVICE_ARGS:
                        handleServiceArgs((ServiceArgsData)msg.obj);
                        break;
    

    三个case分别执行下面的三个方法

        @UnsupportedAppUsage
        private void handleCreateService(CreateServiceData data) {
            ...
                service.onCreate();
                ...
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            ...
        }
    
        private void handleBindService(BindServiceData data) {
            Service s = mServices.get(data.token);
                 ...
                            IBinder binder = s.onBind(data.intent);
                 ...
                            ActivityManager.getService().serviceDoneExecuting(
                                    data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                 ...
        }
    
    private void handleServiceArgs(ServiceArgsData data) {
            Service s = mServices.get(data.token);
                 ...
                        res = s.onStartCommand(data.args, data.flags, data.startId);
                 ...
                        ActivityManager.getService().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                        ...
    }
    

    可见handleCreateService、handleBindService、handleServiceArgs分别调用了Service组件的onCreate、onBind、onStartCommand,并且执行完成后通过调用binder方法serviceDoneExecuting告诉system_server操作已完成。

    加油吧,少年!

    相关文章

      网友评论

          本文标题:startService流程梳理

          本文链接:https://www.haomeiwen.com/subject/wqnvjdtx.html