美文网首页
Android基础:Service启动流程

Android基础:Service启动流程

作者: 我在等你回复可你没回 | 来源:发表于2019-03-13 00:08 被阅读0次

service启动流程简单说一下

startServiceLocked

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
            throws TransactionTooLargeException {
        if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
                + " type=" + resolvedType + " args=" + service.getExtras());
        //调用者是否处于前台,设置callerFg 标志
        final boolean callerFg;
        if (caller != null) {
            final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
            if (callerApp == null) {
                throw new SecurityException(
                        "Unable to find app for caller " + caller
                        + " (pid=" + callingPid
                        + ") when starting service " + service);
            }
            callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
        } else {
            callerFg = true;
        }
       //查找service的组件,通过packagemanager
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false);
        if (res == null) {
            return null;
        }
        if (res.record == null) {
            return new ComponentName("!", res.permission != null
                    ? res.permission : "private to package");
        }

        //组件以ServiceRecord 表示
        ServiceRecord r = res.record;

        //检测userid是否合法
        if (!mAm.mUserController.exists(r.userId)) {
            Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId);
            return null;
        }
        //后台启动的一些限制
        // If this isn't a direct-to-foreground start, check our ability to kick off an
        // arbitrary service
        if (!r.startRequested && !fgRequired) {
            // Before going further -- if this app is not allowed to start services in the
            // background, then at this point we aren't going to let it period.
            final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
                    r.appInfo.targetSdkVersion, callingPid, false, false);
            if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
                Slog.w(TAG, "Background start not allowed: service "
                        + service + " to " + r.name.flattenToShortString()
                        + " from pid=" + callingPid + " uid=" + callingUid
                        + " pkg=" + callingPackage);
                if (allowed == ActivityManager.APP_START_MODE_DELAYED) {
                    // In this case we are silently disabling the app, to disrupt as
                    // little as possible existing apps.
                    return null;
                }
                // This app knows it is in the new model where this operation is not
                // allowed, so tell it what has happened.
                UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
                return new ComponentName("?", "app is in background uid " + uidRec);
            }
        }

        r.lastActivity = SystemClock.uptimeMillis();
        r.startRequested = true;
        r.delayedStop = false;
        r.fgRequired = fgRequired;  //默认是false

        //进入startServiceInnerLocked
        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
        return cmp;
    }

进入startServiceInnerLocked

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

进入bringUpServiceLocked

    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
                   ....
                    realStartServiceLocked(r, app, execInFg);
                  ....
    }

进入realStartServiceLocked,scheduleCreateService会调用service的oncreate方法,于是service就起来了。

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
            ...
            app.thread.scheduleCreateService(r, r.serviceInfo,
            ...

    }

如何绑定本地服务和另一个apk的服务?

本地服务直接bind就行,另一个apk的服务还得依赖aidl。
参考:https://blog.csdn.net/u011386173/article/details/83575069

相关文章

网友评论

      本文标题:Android基础:Service启动流程

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