美文网首页
组件之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