Service的启动过程

简介: Service的启动过程

1.应用层调用startService();

frameworks\base\core\java\android\content\ContextWrapper.java

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

进入 Context 类中 ,Context类为抽象类,具体实现类为ContextImpl ,frameworks\base\core\java\android\content\Context.java

@Nullable
    public abstract ComponentName startService(Intent service);

frameworks\base\core\java\android\app\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(), getAttributionTag(), 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());
                } else if (cn.getPackageName().equals("?")) {
                    throw ServiceStartNotAllowedException.newInstance(requireForeground,
                            "Not allowed to start service " + service + ": " + cn.getClassName());
                }
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

frameworks\base\core\java\android\app\ActivityManager.java

ActivityManager.getService()

  public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
 
    private static IActivityTaskManager getTaskService() {
        return ActivityTaskManager.getService();
    }
 
    @UnsupportedAppUsage
    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;
                }
            };

frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

 public ActivityManagerService getService() {
            return mService;
        }
    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage,
            String callingFeatureId, int userId)
            throws TransactionTooLargeException {
        enforceNotIsolatedCaller("startService");
        // Refuse possible leaked file descriptors
        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 + " fg=" + requireForeground);
        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, callingFeatureId, userId);
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
            return res;
        }
    }

 final ActiveServices mServices;

2.ActivityThread启动Service

frameworks\base\services\core\java\com\android\server\am\ActiveServices.java

 ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage,
            @Nullable String callingFeatureId, final int userId)
            throws TransactionTooLargeException {
        return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
                callingPackage, callingFeatureId, userId, false, null);
    }
 
    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired,
            String callingPackage, @Nullable String callingFeatureId, final int userId,
            boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
            throws TransactionTooLargeException {
 
 
        return startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg,
                allowBackgroundActivityStarts, backgroundActivityStartsToken);
    }
    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
        synchronized (mAm.mProcessStats.mLock) {
            final ServiceState stracker = r.getTracker();
            if (stracker != null) {
                stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
            }
        }
        r.callStart = false;
 
        final int uid = r.appInfo.uid;
        final String packageName = r.name.getPackageName();
        final String serviceName = r.name.getClassName();
        FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, uid, packageName,
                serviceName, FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__START);
        mAm.mBatteryStatsService.noteServiceStartRunning(uid, packageName, serviceName);
关键代码 
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg,
                false /* whileRestarting */,
                false /* permissionsReviewRequired */,
                false /* packageFrozen */,
                true /* enqueueOomAdj */);
        /* Will be a no-op if nothing pending */
        mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
        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() + mAm.mConstants.BG_START_TIMEOUT;
            if (DEBUG_DELAYED_SERVICE) {
                RuntimeException here = new RuntimeException("here");
                here.fillInStackTrace();
                Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
            } else if (DEBUG_DELAYED_STARTS) {
                Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
            }
            if (first) {
                smap.rescheduleDelayedStartsLocked();
            }
        } else if (callerFg || r.fgRequired) {
            smap.ensureNotStartingBackgroundLocked(r);
        }
 
        return r.name;
    }

 

 

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen,
            boolean enqueueOomAdj)
            throws TransactionTooLargeException {
得到ServiceRecord的processName的值赋值给procName ,其中processName用来描述Service想要在哪个进程运行,默认是当前进程,我们也可以在AndroidManifes配置文件中设置android:process属性来新开启一个进程运行Service
    final String procName = r.processName;
        HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
        ProcessRecord app;
 
        if (!isolated) {
将procName和Service的uid传入到AMS的getProcessRecordLocked方法中,来查询是否存在一个与Service对应的ProcessRecord类型的对象app,ProcessRecord主要用来记录运行的应用程序进程的信息
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid);
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
            if (app != null) {
                final IApplicationThread thread = app.getThread();
                final int pid = app.getPid();
                final UidRecord uidRecord = app.getUidRecord();
判断如果用来运行Service的应用程序进程存在,则调用realStartServiceLocked方法:
                if (thread != null) {
                    try {
                        app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode,
                                mAm.mProcessStats);
                        realStartServiceLocked(r, app, thread, pid, uidRecord, execInFg,
                                enqueueOomAdj);
                        return null;
                    } catch (TransactionTooLargeException e) {
                        throw e;
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
                    }
 
                    // If a dead object exception was thrown -- fall through to
                    // restart the application.
                }
            }
        }
 
}
    private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,
            IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg,
            boolean enqueueOomAdj) throws RemoteException {
        if (thread == null) {
            throw new RemoteException();
        }
        if (DEBUG_MU)
            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
                    + ", ProcessRecord.uid = " + app.uid);
        r.setProcess(app, thread, pid, uidRecord);
        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
 
        final ProcessServiceRecord psr = app.mServices;
        final boolean newService = psr.startService(r);
        bumpServiceExecutingLocked(r, execInFg, "create", null /* oomAdjReason */);
        mAm.updateLruProcessLocked(app, false, null);
        updateServiceForegroundLocked(psr, /* oomAdj= */ false);
        // Force an immediate oomAdjUpdate, so the client app could be in the correct process state
        // before doing any service related transactions
        mAm.enqueueOomAdjTargetLocked(app);
        mAm.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
 
        boolean created = false;
        try {
            if (LOG_SERVICE_START_STOP) {
                String nameTerm;
                int lastPeriod = r.shortInstanceName.lastIndexOf('.');
                nameTerm = lastPeriod >= 0 ? r.shortInstanceName.substring(lastPeriod)
                        : r.shortInstanceName;
                EventLogTags.writeAmCreateService(
                        r.userId, System.identityHashCode(r), nameTerm, r.app.uid, pid);
            }
 
            final int uid = r.appInfo.uid;
            final String packageName = r.name.getPackageName();
            final String serviceName = r.name.getClassName();
            FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_LAUNCH_REPORTED, uid, packageName,
                    serviceName);
            mAm.mBatteryStatsService.noteServiceStartLaunch(uid, packageName, serviceName);
            mAm.notifyPackageUse(r.serviceInfo.packageName,
                                 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
调用这里
            thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                    app.mState.getReportedProcState());
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
            Slog.w(TAG, "Application dead when creating service " + r);
            mAm.appDiedLocked(app, "Died when creating service");
            throw e;
        } finally {
            if (!created) {
                // Keep the executeNesting count accurate.
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying, false);
 
                // Cleanup.
                if (newService) {
                    psr.stopService(r);
                    r.setProcess(null, null, 0, null);
                }
 
                // Retry.
                if (!inDestroying) {
                    scheduleServiceRestartLocked(r, false);
                }
            }
        }
 
        if (r.allowlistManager) {
            psr.mAllowlistManager = true;
        }
 
        requestServiceBindingsLocked(r, execInFg);
 
        updateServiceClientActivitiesLocked(psr, null, true);
 
        if (newService && created) {
            psr.addBoundClientUidsOfNewService(r);
        }
 
        // If the service is in the started state, and there are no
        // pending arguments, then fake up one so its onStartCommand() will
        // be called.
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null, 0));
        }
 
        sendServiceArgsLocked(r, execInFg, true);
 
        if (r.delayed) {
            if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
            getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
            r.delayed = false;
        }
 
        if (r.delayedStop) {
            // Oh and hey we've already been asked to stop!
            r.delayedStop = false;
            if (r.startRequested) {
                if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
                        "Applying delayed stop (from start): " + r);
                stopServiceLocked(r, enqueueOomAdj);
            }
        }
    }

frameworks\base\core\java\android\app\ActivityThread.java

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

首先将要启动的信息封装成CreateServiceData 对象并传给sendMessage方法,sendMessage方法向H发送CREATE_SERVICE消息,H是ActivityThread的内部类并继承Handler。这个过程和应用程序的启动过程(根Activity启动过程)是类似的。

public void handleMessage(Message msg) {
case CREATE_SERVICE:
                    if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                                ("serviceCreate: " + String.valueOf(msg.obj)));
                    }
                    handleCreateService((CreateServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
}
    @UnsupportedAppUsage
    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();
 
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);获取要启动Service的应用程序的LoadedApk,LoadedApk是一个APK文件的描述类
        Service service = null;
        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
 
            Application app = packageInfo.makeApplication(false, mInstrumentation);
 
            final java.lang.ClassLoader cl;
            if (data.info.splitName != null) {
通过调用LoadedApk的getClassLoader方法来获取类加载器
                cl = packageInfo.getSplitClassLoader(data.info.splitName);
            } else {
                cl = packageInfo.getClassLoader();
            }
根据CreateServiceData对象中存储的Service信息,将Service加载到内存中
            service = packageInfo.getAppFactory()
                    .instantiateService(cl, data.info.name, data.intent);
创建Service的上下文环境ContextImpl对象
            ContextImpl context = ContextImpl.getImpl(service
                    .createServiceBaseContext(this, packageInfo));
            if (data.info.splitName != null) {
                context = (ContextImpl) context.createContextForSplit(data.info.splitName);
            }
            if (data.info.attributionTags != null && data.info.attributionTags.length > 0) {
                final String attributionTag = data.info.attributionTags[0];
                context = (ContextImpl) context.createAttributionContext(attributionTag);
            }
            // Service resources must be initialized with the same loaders as the application
            // context.
            context.getResources().addLoaders(
                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
 
            context.setOuterContext(service);
通过Service的attach方法来初始化Service
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
调用Service的onCreate方法,启动Service
            service.onCreate();
            mServicesData.put(data.token, data);
将启动的Service加入到ActivityThread的成员变量mServices中
            mServices.put(data.token, service);
            try {
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }


目录
相关文章
|
SQL 分布式计算 运维
如何对付一个耗时6h+的ODPS任务:慢节点优化实践
本文描述了大数据处理任务(特别是涉及大量JOIN操作的任务)中遇到的性能瓶颈问题及其优化过程。
|
Android开发 芯片 异构计算
Android图形显示系统——下层显示4:图层合成下(硬件合成器)
硬件合成器-HwComposer 使用3D合成,需要大面积的像素混合计算和大量的内存传输(GPU读写GraphicBuffer所需),对GPU和DDR来说是一个巨大的负担。在GPU/DDR重度使用的场景(比如玩游戏),会造成发热、卡顿等。 为了提升性能,减少功耗,可以将合成这个过程交由另一个芯片完成,减轻GPU负担。进一步,直接让这个芯片连LCD,在LCD需要显示某一行时
7297 0
|
11月前
|
存储 弹性计算 数据管理
阿里云对象存储oss怎么收费?存储费用+流量收费标准
阿里云对象存储OSS收费标准包含存储费、流量费及请求费等,支持按量付费与包年包月两种模式。标准型本地冗余存储按量付费价格为0.09元/GB/月,包年包月500GB预留空间优惠价118元/年。流量费仅收取公网出方向费用,忙时0.50元/GB,闲时0.25元/GB。更多详情可参考官方页面。
2154 91
|
Python
Jetson环境安装(二):ubuntu18.0卸载和安装python3
在Jetson Nano上如何卸载Python 3.7并重新安装Python 3.7.0版本的详细步骤,包括卸载命令、安装依赖库、下载和编译Python源码以及建立软链接等。
546 2
|
10月前
|
Kubernetes Cloud Native 区块链
Arista cEOS 4.30.10M - 针对云原生环境设计的容器化网络操作系统
Arista cEOS 4.30.10M - 针对云原生环境设计的容器化网络操作系统
324 0
|
人工智能 Android开发 数据安全/隐私保护
移动应用与系统:探索移动应用开发及操作系统的未来趋势####
本文深入探讨了移动应用开发和移动操作系统的现状、挑战与未来发展趋势。通过分析当前主流的移动操作系统(如Android和iOS)以及移动应用开发的最新技术,旨在为开发者提供有价值的参考,帮助他们更好地应对未来的挑战。 ####
|
缓存 Java Python
python垃圾回收&缓存机制
python垃圾回收&缓存机制
|
移动开发 开发框架 小程序
UniApp与微信小程序介绍及区别
UniApp与微信小程序介绍及区别
1543 0
|
开发者 UED Python
深入浅出:Python中的异步编程
在当今快速发展的软件行业,异步编程已成为提高应用性能和用户体验的关键技术。本文将通过清晰的解释和实例,深入探讨Python中的异步编程机制。我们不仅会介绍异步编程的基本概念和它与同步编程的区别,还会通过实际代码示例展示如何在Python中使用asyncio库来实现异步编程。此外,我们还将探讨异步编程的一些常见问题及其解决方案,旨在为读者提供一个全面而深入的理解,帮助开发者有效地在自己的项目中应用异步编程,优化应用性能。
|
安全 关系型数据库 MySQL
关于 linux 文件权限控制-SELinux
关于 linux 文件权限控制-SELinux
446 0
关于 linux 文件权限控制-SELinux