Service启动流程

2022-04-24  本文已影响0人  jxiang112

Activity并没有重写startService,其父类ContextThemeWrapper也没有重写,是在ContextWrapper中重写的

ContextWrapper

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

mBase是ContextImpl,在ActivityThread launchActivity的时候创建了context的实现类ContextImpl,并通过Activity.attach进行包装

ContextImpl

private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) {
        try {
            this.validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            ComponentName cn = ActivityManager.getService().startService(this.mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(this.getContentResolver()), requireForeground, this.getOpPackageName(), user.getIdentifier());
           //......

            return cn;
        } catch (RemoteException var5) {
            throw var5.rethrowFromSystemServer();
        }
    }

调用ActivityManager的getService获取AMS提供的Binder代理服务,调用Binder代理的startService通过进程间通信进入AMS

ActivityManager

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

ActivityManager.getService获取AMS提供的代理服务b。
获取到AMS的binder代理之后,调用AMS的startService方法,经过进程间通信进入AMS的startService方法

ActivityManagerService

@Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage, int userId)
            throws TransactionTooLargeException {
       //......
        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;
        }
       //......
    }

AMS的ActivityManagerService调用mServices.startServiceLocked方法继续完成startService流程,mServices是ActivityService的实例

ActivityService

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
            throws TransactionTooLargeException {
    //.....
  //校验是否允许启动前台服务/后台服务、生成启动serivice的记录等操作
  ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
        return cmp;
}

ActivityService的startServiceInnerLocked接着调用startServiceInnerLocked方法:

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
    //......
    String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
    //......
}

startServiceInnerLocked有继续调用startServiceInnerLocked方法:

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
    if (r.app != null && r.app.thread != null) {
            //service已经启动过,直接传到参数,即调用onStartCommand即可
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }
    //......
    if (app != null && app.thread != null) {
      //应用进程已启动
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
                    //调用realStartServiceLocked继续启动service
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } 
            }
    //......
  //进程未启动,则调用Am.startProcessLocked先启动进程,Am是AMS的实例
  if (app == null && !permissionsReviewRequired) {
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingType, r.name, false, isolated, false)) == null) {
                String msg = "Unable to launch app "
                        + r.appInfo.packageName + "/"
                        + r.appInfo.uid + " for service "
                        + r.intent.getIntent() + ": process is bad";
                Slog.w(TAG, msg);
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }
 //......
}

bringUpServiceLocked主要做:

private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
 //......
//倒计时startService流程onCreate是否超时,如果超时则抛出Anr
bumpServiceExecutingLocked(r, execInFg, "create");
//......
//调用ActivityThread内部类ApplicationThread的scheduleCreateService进行创建service并调用onCreate
app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
 //......
//向Service发送启动参数,其实就是调用onStartCommand
sendServiceArgsLocked(r, execInFg, true);
//......
}

realStartServiceLocked主要做:

我们先继续看sendServiceArgsLocked方法:

private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {
//......
//倒计时startService流程中onStartCommand是否超时,如果超时则抛出Anr。
bumpServiceExecutingLocked(r, execInFg, "start");
//......
//调用ActivityThread内部类ApplicationThread的scheduleServiceArgs进行调用onStartCommand
r.app.thread.scheduleServiceArgs(r, slice);
//......
}

sendServiceArgsLocked的核心就是调用onStartCommand并传递参数

ActivityThread

创建Service流程

根据上面的分析首先会进入ApplicationTrhead的scheduleCreateService方法:

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

ApplicationThread.scheduleCreateService方法中接着发出CREATE_SERVICE的消息,进入ActivityThread.H的消息CREATE_SERVICE流程:

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

接着进入ActivityThread的handleCreateService方法中:

private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        //获取apk包体信息
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            //根据service包名反射创建service实例对象
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = packageInfo.getAppFactory()
                    .instantiateService(cl, data.info.name, data.intent);
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
            //创建上下文实例
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
            //调用service的attach方法进行初始化
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            //调用onCreate生命周期方法
            service.onCreate();
            //缓存Service
            mServices.put(data.token, service);
            try {
                //移除createService流程超时引发Anr的监听
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } 
        //......
    }
onStartCommand流程

根据上面的分析,onStartCommand首先进入ApplicationThread的scheduleServiceArgs方法:

public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
            List<ServiceStartArgs> list = args.getList();

            for (int i = 0; i < list.size(); i++) {
                ServiceStartArgs ssa = list.get(i);
                ServiceArgsData s = new ServiceArgsData();
                s.token = token;
                s.taskRemoved = ssa.taskRemoved;
                s.startId = ssa.startId;
                s.flags = ssa.flags;
                s.args = ssa.args;

                sendMessage(H.SERVICE_ARGS, s);
            }
        }

scheduleServiceArgs方法组装参数并发出SERVICE_ARGS消息,进入ActivityThread.H的SERVICE_ARGS流程:

case SERVICE_ARGS:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
                    handleServiceArgs((ServiceArgsData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

SERVICE_ARGS分支调用handleServiceArgs方法继续处理:

private void handleServiceArgs(ServiceArgsData data) {
        //从缓存中取出Service
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess();
                }
                int res;
                if (!data.taskRemoved) {
                    //调用Service的onStartCommand
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }

                QueuedWork.waitToFinish();

                try {
                    //移除onStartCommand超时Anr消息
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
                ensureJitEnabled();
            } 
            //.......
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读