Android Service 流程分析

本文详细分析了Android Service的启动和绑定流程,包括启动Service时序图、attach()和onCreate()方法回调、onStartCommand()参数处理,以及绑定Service时序图、onBind()或onRebind()回调过程,解释了为何仅仅绑定时不回调onStartCommand()。内容涵盖了Service生命周期的关键方法和系统内部处理细节。
摘要由CSDN通过智能技术生成

Android Service 代码地址

在前面已经对Service基本使用及aidl使用及源码进行的分析。在这篇文章中,我们来看一下Android Service的启动流程和绑定流程,以便于更好的理解Android Service的机制。

启动Service过程

Android Service启动时序图

Android Service启时序图
上图就是Android Service启动时序图,对照图查看代码。

我们在 Activity 中调用 startService() 方法时,直接调用了 调用 ContextWrapperstartService()

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

mBase 就是 ContextImpl,进入 ContextImpl 中查看

@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);
        // ActivityManager.getService() 就是获取到的 ActivityManagerService 对象
        ComponentName cn = ActivityManager.getService().startService(
            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                        getContentResolver()), requireForeground,
                        getOpPackageName(), user.getIdentifier());
        // ... 省略 对 cn 进行校验
        return cn;
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}

ActivityManager 中获取 ActivityManagerService 代码如下:

public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

// 通过 Singleton 创建IActivityManager.aidl接口对象,实现类为 `ActivityManagerService`
private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
        @Override
        protected IActivityManager create() {
            final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
            // 由一下代码可知,IActivityManager 是aidl,也就说明Service的启动过程是一个IPC的过程
            final IActivityManager am = IActivityManager.Stub.asInterface(b);
            return am;
        }
    };

进入 ActivityManagerService 中查看 startService() 方法

@Override
public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, boolean requireForeground, String callingPackage, int userId)
        throws TransactionTooLargeException {
    enforceNotIsolatedCaller("startService");
    // ... 省略 Refuse possible leaked file descriptors 对service文件描述和调用包进行判断

    synchronized(this) {
        final int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        ComponentName res;
        try {
        	// 调用 ActiveServices 的 startServiceLocked() 方法
            res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid,
                    requireForeground, callingPackage, userId);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
        return res;
    }
}

mServices 是 ActiveServices 类,该类是 AMS(ActivityManagerService) 的辅助类,是对 Service 进行管理的工具类,包含Service的启动、绑定、解绑、销毁等过程。查看 ActiveServicesstartServiceLocked() 方法,一下是ActiveServices中的方法调用过程:

// ActiveServices#startServiceLocked()
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
        int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
        throws TransactionTooLargeException {
    // 调用 startServiceLocked()
    return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
            callingPackage, userId, false);
}

// ActiveServices#startServiceLocked()
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
        int callingPid, int callingUid, boolean fgRequired, String callingPackage,
        final int userId, boolean allowBackgroundActivityStarts)
        throws TransactionTooLargeException {
  
    // ... 省略

    ServiceLookupResult res =
        retrieveServiceLocked(service, null, resolvedType, callingPackage,
                callingPid, callingUid, userId, true, callerFg, false, false);

    // 取出 ServiceRecord 对象,后面启动过程中都是使用的它
    ServiceRecord r = res.record;

    // ... 省略 判断和处理前台服务

    r.lastActivity = SystemClock.uptimeMillis();
    r.startRequested = true; // 启动服务标识置为 true
    r.delayedStop = false;
    r.fgRequired = fgRequired;
    r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
            service, neededGrants, callingUid));
    // 调用 startServiceInnerLocked() 方法
    ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    return cmp;
}

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

// ActiveServices#bringUpServiceLocked()
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
        boolean whileRestarting, boolean permissionsReview
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值