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