美文网首页
Service启动流程

Service启动流程

作者: 北疆小兵 | 来源:发表于2019-10-26 18:25 被阅读0次

    Android Service启动流程

    概述

    Service是android系统非常重要的四大组件之一,Service通常被用来在后台做一些耗时任务。本文从源码角度讲述启动Service流程

    启动流程

    1 startService

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

    2 [-> ContextImpl.java]

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

    3 [-> ContextImpl.java]

    private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            //检验service,当service为空则throw异常
            validateServiceIntent(service);
            service.prepareToLeaveProcess();
            // 调用ActivityManagerNative类 【见流程3.1以及流程4】
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), getOpPackageName(), user.getIdentifier());
            if (cn != null) {
                if (cn.getPackageName().equals("!")) {
                    throw new SecurityException("Not allowed to start service " +
                        service + " without permission " + cn.getClassName());
                } else if (cn.getPackageName().equals("!!")) {
                    throw new SecurityException("Unable to start service " +
                        service  ": " + cn.getClassName());
                }
            }
            return cn;
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
    }
    
    ``
    这里通过ActivityManager.getService().startService() 是通过binder机制发起了服务请求,这里假设startService的发起进程为A,ActivityManagerService为进程B,那么进程A通过Binder机制(采用IActivityManager接口)向进程B发起请求服务,进程B则通过Binder机制(采用IApplicationThread接口)向进程A发起请求服务。也就是说进程A和进程B通过binder机制可以互相主动发起请求来进行进程间通信 
    

    4.ActivityManager

    @Override
    public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, String callingPackage, int userId) throws TransactionTooLargeException {
        //当调用者是孤立进程,则抛出异常。
        enforceNotIsolatedCaller("startService");
    
        if (service != null && service.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        if (callingPackage == null) {
            throw new IllegalArgumentException("callingPackage cannot be null");
        }
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                "startService: " + service + " type=" + resolvedType);
    
        synchronized(this) {
            final int callingPid = Binder.getCallingPid(); //调用者pid
            final int callingUid = Binder.getCallingUid(); //调用者uid
            final long origId = Binder.clearCallingIdentity();
            //此次的mServices为ActiveServices对象 【见流程5】
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, callingPackage, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }
    
    

    这里mServices.startServiceLocked() 中的mServices是ActiveServices的实例

    5 ActiveServices.startServiceLocked

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, String callingPackage, int userId) throws TransactionTooLargeException {
    
        final boolean callerFg;
        if (caller != null) {
            final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
            if (callerApp == null)
                throw new SecurityException(""); //抛出异常,此处省略异常字符串
            callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
        } else {
            callerFg = true;
        }
        //检索服务信息
        ServiceLookupResult res =  retrieveServiceLocked(service, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg);
        if (res == null) {
            return null;
        }
        if (res.record == null) {
            return new ComponentName("!", res.permission != null
                    ? res.permission : "private to package");
        }
        ServiceRecord r = res.record;
        if (!mAm.getUserManagerLocked().exists(r.userId)) { //检查是否存在启动服务的user
            return null;
        }
        NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
                callingUid, r.packageName, service, service.getFlags(), null, r.userId);
    
        r.lastActivity = SystemClock.uptimeMillis();
        r.startRequested = true;
        r.delayedStop = false;
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                service, neededGrants));
        final ServiceMap smap = getServiceMap(r.userId);
        boolean addToStarting = false;
        //对于非前台进程的调度
        if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
            ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
            if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
                if (r.delayed) {  //已计划延迟启动
                    return r.name;
                }
                if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
                    //当超出 同一时间允许后续启动的最大服务数,则将该服务加入延迟启动的队列。
                    smap.mDelayedStartList.add(r);
                    r.delayed = true;
                    return r.name;
                }
                addToStarting = true;
            } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
                //将新的服务加入到后台启动队列,该队列也包含当前正在运行其他services或者receivers的进程
                addToStarting = true;
            }
        }
        //【见流程6】
        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    }
    
    

    这个方法最后调用的是startServiceInnerLocked

    6.ActiveServices.startServiceLocked

    
     ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
                boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
           ProcessStats.ServiceState stracker = r.getTracker();
        if (stracker != null) {
            stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
        }
        r.callStart = false;
        synchronized (r.stats.getBatteryStats()) {
            r.stats.startRunningLocked(); //用于耗电统计,开启运行的状态
        }
        //【见流程7】
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
        if (error != null) {
            return new ComponentName("!!", error);
        }
        if (r.startRequested && addToStarting) {
            boolean first = smap.mStartingBackground.size() == 0;
            smap.mStartingBackground.add(r);
            r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
            if (first) {
                smap.rescheduleDelayedStarts();
            }
        } else if (callerFg) {
            smap.ensureNotStartingBackground(r);
        }
        return r.name;
    

    7.ActiveServices.bringUpServiceLocked

    private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) throws TransactionTooLargeException {
        if (r.app != null && r.app.thread != null) {
            //调用service.onStartCommand()过程
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }
        if (!whileRestarting && r.restartDelay > 0) {
            return null; //等待延迟重启的过程,则直接返回
        }
    
        // 启动service前,把service从重启服务队列中移除
        if (mRestartingServices.remove(r)) {
            r.resetRestartCounter();
            clearRestartingIfNeededLocked(r);
        }
        //service正在启动,将delayed设置为false
        if (r.delayed) {
            getServiceMap(r.userId).mDelayedStartList.remove(r);
            r.delayed = false;
        }
    
        //确保拥有该服务的user已经启动,否则停止;
        if (mAm.mStartedUsers.get(r.userId) == null) {
            String msg = "";
            bringDownServiceLocked(r);
            return msg;
        }
        //服务正在启动,设置package停止状态为false
        AppGlobals.getPackageManager().setPackageStoppedState(
                r.packageName, false, r.userId);
    
        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
        final String procName = r.processName;
        ProcessRecord app;
        if (!isolated) {
            //根据进程名和uid,查询ProcessRecord
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                    // 启动服务 【见流程8】
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } catch (TransactionTooLargeException e) {
                    throw e;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
                }
            }
        } else {
            app = r.isolatedProc;
        }
    
        //对于进程没有启动的情况
        if (app == null) {
            //启动service所要运行的进程(7.1)
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {
                String msg = ""
                bringDownServiceLocked(r); // 进程启动失败
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }
        if (!mPendingServices.contains(r)) {
            mPendingServices.add(r);
        }
        if (r.delayedStop) {
            r.delayedStop = false;
            if (r.startRequested) {
                stopServiceLocked(r); //停止服务
            }
        }
        return null;
    }
    
    

    这里判断app != null && app.thread != null 如果不为空,说明进程已经启动起来了,直接调用realStartServiceLocked启动服务,如果进程没有启动,则调用AMS.startProcessLocked启动进程

    7.AMS.startProcessLocked

     startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
                    null /* entryPoint */, null /* entryPointArgs */);
    
    

    AMS.startProcessLocked方法最后会调用到ActivityService.attachApplicationLocked

    8.1 ActivityService.attachApplicationLocked

    
    boolean didSomething = false;
        //启动mPendingServices队列中,等待在该进程启动的服务
        if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
            try {
                for (int i=0; i<mPendingServices.size(); i++) {
                    sr = mPendingServices.get(i);
                    if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                            || !processName.equals(sr.processName))) {
                        continue;
                    }
                    mPendingServices.remove(i);
                    I--;
                    // 将当前服务的包信息加入到proc
                    proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
                            mAm.mProcessStats);
                    // 启动服务,即将进入服务的生命周期 【见流程9】
                    realStartServiceLocked(sr, proc, sr.createdFromFg);
                    didSomething = true;
                }
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception in new application when starting service "
                        + sr.shortName, e);
                throw e;
            }
        }
        // 对于正在等待重启并需要运行在该进程的服务,现在是启动它们的大好时机
        if (mRestartingServices.size() > 0) {
            ServiceRecord sr = null;
            for (int i=0; i<mRestartingServices.size(); i++) {
                sr = mRestartingServices.get(i);
                if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                        || !processName.equals(sr.processName))) {
                    continue;
                }
                mAm.mHandler.removeCallbacks(sr.restarter);
                mAm.mHandler.post(sr.restarter);
            }
        }
        return didSomething;
    
    

    9. ActivityService.AS.realStartServiceLocked

    private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException {
        ...
    
        r.app = app;
        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
        final boolean newService = app.services.add(r);
    
        //发送delay消息【见流程9.1】
        bumpServiceExecutingLocked(r, execInFg, "create");
        mAm.updateLruProcessLocked(app, false, null);
        mAm.updateOomAdjLocked();
        boolean created = false;
        try {
            synchronized (r.stats.getBatteryStats()) {
                r.stats.startLaunchedLocked();
            }
            mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            //服务进入 onCreate() 【见流程10】
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
            mAm.appDiedLocked(app); //应用死亡处理
            throw e;
        } finally {
            if (!created) {
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
                if (newService) {
                    app.services.remove(r);
                    r.app = null;
                }
                //尝试重新启动服务
                if (!inDestroying) {
                    scheduleServiceRestartLocked(r, false);
                }
            }
        }
        requestServiceBindingsLocked(r, execInFg);
        updateServiceClientActivitiesLocked(app, null, true);
    
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null));
        }
        //服务 进入onStartCommand() 【见流程17】
        sendServiceArgsLocked(r, execInFg, true);
        if (r.delayed) {
            getServiceMap(r.userId).mDelayedStartList.remove(r);
            r.delayed = false;
        }
        if (r.delayedStop) {
            r.delayedStop = false;
            if (r.startRequested) {
                stopServiceLocked(r); //停止服务
            }
        }
    }
    
    
    

    这个方法里面调用了app.thread.scheduleCreateService的scheduleCreateService, 这里的app.thread其实是IApplicationThread接口,也就是说在AS这个服务器进程中通过binder机制 (采用IApplicationThread接口)调用app进程的scheduleCreateService

    10. ApplicationThread.scheduleCreateService

    private class ApplicationThread extends IApplicationThread.Stub {
         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的内部类ApplicationThread中通过Handler发送CREATE_SERVICE消息

    11 ActivityThread.handleMessage

    public void handleMessage(Message msg) {
        switch (msg.what) {
            ...
            case CREATE_SERVICE:
                handleCreateService((CreateServiceData)msg.obj); //【见流程15】
                break;
            case BIND_SERVICE:
                handleBindService((BindServiceData)msg.obj);
                break;
            case UNBIND_SERVICE:
                handleUnbindService((BindServiceData)msg.obj);
                break;
            case SERVICE_ARGS:
                handleServiceArgs((ServiceArgsData)msg.obj);  // serviceStart
                break;
            case STOP_SERVICE:
                handleStopService((IBinder)msg.obj);
                maybeSnapshot();
                break;
            ...
        }
    }
    
    

    12 ActivityThread.handleCreateService

    //当应用处于后台即将进行GC,而此时被调回到活动状态,则跳过本次gc。
        unscheduleGcIdler();
        LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
    
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        //通过反射创建目标服务对象
        Service service = (Service) cl.loadClass(data.info.name).newInstance();
        ...
    
        try {
            //创建ContextImpl对象
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
            //创建Application对象,如果已创建,则不会再创建
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
            //调用服务onCreate()方法 【见流程13.1】
            service.onCreate();
            mServices.put(data.token, service);
            //调用服务创建完成
            ActivityManagerNative.getDefault().serviceDoneExecuting(
                    data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
        } catch (Exception e) {
            ...
        }
    
    
    

    13 Service.onCreate

    public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
        public void onCreate(){    }
    }
    
    

    至此Service的生命周期方法onCreate就开始执行了

    总结

    根据以上源代码流程分析可以得出,service启动流程

    从关键代码流程来看:

    1.ContextImpl.startService()
    2.ActivityManagerProxy.startService() (ActivityManagerProxy和ActivityManangerService都实现了IActivityManager接口)
    3.ActivityManagerNative.transact() => 通过Binder方式(采用IActivityManager接口调用ActivityManangerService)
    4.ActivityManangerService.startService()
    5.ApplicationThreadProxy.scheduleCreateService()
    6.ApplicationThreadNative.onTransact
    7.ApplicationThreadNative. scheduleCreateService
    8.ApplicationThread. scheduleCreateService=>通过Binder方式(采用IApplicaitonThread接口)
    9.ActivityThread.mH.sendMessage()
    10.ActivityThread.handleCreateService();
    11.创建application(只会创建一次)
    12.反射创建Service,调用其onCreate方法

    从进程方面来看

    在整个startService启动过程中,共涉及到以下几个进程

    • Process A进程,是指调用startService命令所在的进程,也就是启动服务所在的进程,例如点击桌面app图标,此处Process A便是Launch所在进程
    • system_server进程:系统进程,例如ApplicationThreadProxy,ActivityManagerService都运行在system_server进程的不同线程中
    • Zygote进程:由init进程孵化而来
    • Remote Service进程: 远程服务所在进程,由system_server进程孵化而来,主线程负责Activity/Service/BroadcastReceiver 以及ui操作等的生命周期调用,另外每个app进程至少会有两个binder线程ApplicationThread(简称AT)和ActivityManagerProxy(简称AMP)
    2222.jpeg

    参考资料

    GitYuan博客:startService启动过程分析

    相关文章

      网友评论

          本文标题:Service启动流程

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