美文网首页
组件之Service源码解析

组件之Service源码解析

作者: kjy_112233 | 来源:发表于2018-10-08 11:20 被阅读0次

一、startService源码启动流程

(1)启动流程是从ContextWraper的startService方法开始的

  • ActivityManager.getService()是IActivityManager的代理对象,调用代理对象的startService方法,会向系统服务ActivityManagerService发起请求,基于Binder机制,调用ActivityManagerService的startService方法。
    @Override
    public ComponentName startService(Intent service) {
        return mBase.startService(service);
    }

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

    private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            //注释
            ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), requireForeground,
                            getOpPackageName(), user.getIdentifier());
            //code...
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

(2)查看ActivityManagerService.startService源码

  • mServices的类型是ActiveServices,管理Service类的启动、绑定和销毁等。调用ActiveServices.startServiceLocked()执行启动操作。
    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage, int userId)
            throws TransactionTooLargeException {
        enforceNotIsolatedCaller("startService");
        //code...
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res;
            try {
                //注释
                res = mServices.startServiceLocked(caller, service,
                        resolvedType, callingPid, callingUid,
                        requireForeground, callingPackage, userId);
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
            return res;
        }
    }
  • 查看ActiveServices.startServiceLocked源码
    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
            throws TransactionTooLargeException {
        //coed...
        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
        return cmp;
    }

    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
        //code...
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
        //code...
        return r.name;
    }
  • 查看bringUpServiceLocked源码
  • 如果service所在进程已经存在,则通过realStartServiceLocked方法启动Service。
  • 如果service所在进程未启动,则通过startProcessLocked创建。
    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
        //code...
        if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
                    //注释
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } catch (TransactionTooLargeException e) {
                    throw e;
                } catch (RemoteException e) {
                }

            }
        } else {
            app = r.isolatedProc;
            if (WebViewZygote.isMultiprocessEnabled()
                    && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
                hostingType = "webview_service";
            }
        }

        //注释
        if (app == null && !permissionsReviewRequired) {
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingType, r.name, false, isolated, false)) == null) {
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }
        //code...
        return null;
    }
  • 查看realStartServiceLocked源码
  • 通过aidl的调用调用ApplicationThread中scheduleCreateService创建service
  • 如果设置更新通知栏,进行通知栏的更新
    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        //code...
            //注释
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            //注释
            r.postNotification();
        //code..
    }

(3)查看ApplicationThread.scheduleCreateService源码

  • 发送消息到ActivityThread内部类H中
        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);
        }
  • 查看H中handleMessage方法
  • 在handleMessage中接收消息并调用handleCreateService方法启动服务
  • 启动Service回调attach和onCreate方法
        public void handleMessage(Message msg) {
            switch (msg.what) {
                //code...
                case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                    handleCreateService((CreateServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
            }
            Object obj = msg.obj;
            if (obj instanceof SomeArgs) {
                ((SomeArgs) obj).recycle();
            }
        }
    }

    private void handleCreateService(CreateServiceData data) {
        unscheduleGcIdler();
        //code...
        try {
            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,
                    ActivityManager.getService());
            service.onCreate();
            mServices.put(data.token, service);
            try {
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        //code...
    }

相关文章

网友评论

      本文标题:组件之Service源码解析

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