Android Service 流程分析

Android Service 代码地址

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

启动Service过程

Android Service启动时序图

Android Service启动时序图.png

上图就是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 permissionsReviewRequired)
        throws TransactionTooLargeException {
    // 已经启动,重复启动时,直接发送参数调动 onStartCommand() 方法
    if (r.app != null && r.app.thread != null) {
        sendServiceArgsLocked(r, execInFg, false);
        return null;
    }

    final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
    final String procName = r.processName;
    HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
    ProcessRecord app;

    if (!isolated) {
        app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
        if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                    + " app=" + app);
        if (app != null && app.thread != null) {
            try {
                app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
                // 调用 realStartServiceLocked() 方法
                realStartServiceLocked(r, app, execInFg);
                return null;
            } catch (TransactionTooLargeException e) {
                throw e;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
            }
        }
    } else {
         // ... 省略
    }
     // ... 省略
    return null;
}

// ActiveServices#realStartServiceLocked()
private final void realStartServiceLocked(ServiceRecord r,
        ProcessRecord app, boolean execInFg) throws RemoteException {
   
    boolean created = false;
    try {
        // 调用 ActivityThread 的 scheduleCreateService() 方法
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                app.getReportedProcState());
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
        throw e;
    } finally {
        // ... 省略
    }
    // ... 省略


    // 如果是启动,并且需要调用 onStartCommand() 方法,给 pendingStarts 集合增加数据,
    // 因为 onStartCommand() 方法是否会调动是根据 pendingStarts 集合是否有数据来决定是否调用的。
    // 在后面说参数调用的时候就会知道,如果仅仅是绑定服务,就不会添加,这也就是为什么我们绑定服务时不会回调 onStartCommand() 方法的原因
    if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                null, null, 0));
    }
    // 调用方法,处理参数,从而调用 onStartCommand() 方法
    sendServiceArgsLocked(r, execInFg, true);
}

从这里开始分为两步,先通过 ActivityThread 中的方法来启动 Service,然后在通过 ActiveServices 自身的 sendServiceArgsLocked() 方法来处理参数(Intent数据),调用生命周期的 onStartCommand() 方法。注意注释部分,说明了我们仅仅是绑定服务时为什么不会回调 onStartCommand() 方法的原因,后面说绑定Service不会在重复了。

启动过程(attach() 和 onCreate() 方法回调过程)

先看 ActivityThread 中的方法

// ActivityThread#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;
    // 给 Handler 类 H 发送 CREATE_SERVICE
    // H 是 ActivityThread 的内部类,继承 Handler
    sendMessage(H.CREATE_SERVICE, s);
}

Handler 类 H handleMessage() 方法针对 what 为 CREATE_SERVICE 的处理,调用 handleCreateService() 方法

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

调用 handleCreateService() 方法,内部通过类加载器创建Service东西,然后调用Service的 attach()onCreate() 方法

// ActivityThread#handleCreateService()
private void handleCreateService(CreateServiceData data) {
   
    LoadedApk packageInfo = getPackageInfoNoCheck(
            data.info.applicationInfo, data.compatInfo);
    Service service = null;
    try {
        // 使用类加载器通过反射的形势创建Service对象
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = packageInfo.getAppFactory()
                .instantiateService(cl, data.info.name, data.intent);
    } catch (Exception e) {
    }

    try {
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);
        Application app = packageInfo.makeApplication(false, mInstrumentation);
        // Serivce 的 attach() 回调,并建立 Service 和 ContextImpl 之间的联系
        service.attach(context, this, data.info.name, data.token, app,
                ActivityManager.getService());
        service.onCreate(); // Serivce 的 onCreate() 回调
        // 将Service保存到集合中  final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
        mServices.put(data.token, service);
    } catch (Exception e) {
        
    }
}

通过类加载器创建Service的过程如下:

通过类 LoadedApk#getAppFactory() 方法可以知道获取到的是 AppComponentFactory 对象,

public AppComponentFactory getAppFactory() {
    return mAppComponentFactory;
}

// 给 mAppComponentFactory 赋值
private AppComponentFactory createAppFactory(ApplicationInfo appInfo, ClassLoader cl) {
    if (appInfo.appComponentFactory != null && cl != null) {
        try {
            return (AppComponentFactory)  cl.loadClass(appInfo.appComponentFactory).newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            Slog.e(TAG, "Unable to instantiate appComponentFactory", e);
        }
    }
    return AppComponentFactory.DEFAULT;
}

然后调用 AppComponentFactory#instantiateService() 方法,创建Service类,方法实现如下:

public @NonNull Service instantiateService(@NonNull ClassLoader cl,
        @NonNull String className, @Nullable Intent intent)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    // 通过反射创建Service
    return (Service) cl.loadClass(className).newInstance();
}

上面说了,分为两步。先是启动 Service;然后在处理参数。通过以上步骤,我们知道 Service 已经启动了,它的 attach()onCreate() 都已经调用了,下面我们来看看它的生命周期方法
onStartCommand() 在什么时候调用,在上面已经说过是通过 ActiveServices 自身的 sendServiceArgsLocked() 方法来处理的

参数处理(onStartCommand() 方法回调过程)

// ActiveServices#sendServiceArgsLocked() 方法
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
        boolean oomAdjusted) throws TransactionTooLargeException {
    final int N = r.pendingStarts.size();
    // 集合中没有数据,直接返回。
    // 如果仅仅是绑定服务,大小为0,这也就是为什么我们绑定服务时不会回调 onStartCommand() 方法的原因
    // 上面 ActiveServices#realStartServiceLocked() 注释
    if (N == 0) {
        return;
    }

    ArrayList<ServiceStartArgs> args = new ArrayList<>();
    // ... 省略 r.pendingStarts 参数处理部分
    ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
    slice.setInlineCountLimit(4);
    Exception caughtException = null;
    try {
        // 调用 ActivityThread 的 scheduleServiceArgs() 方法
        r.app.thread.scheduleServiceArgs(r, slice);
    } catch (TransactionTooLargeException e) {
    }
}

上面当 r.pendingStarts.size() 为0时,不会继续执行,也就是当仅仅是绑定Service时,不会执行后面的步骤了。接着看 ActivityThread 中的 scheduleServiceArgs() 方法

// ActivityThread#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;
        // 给 Handler 类 H 发送 SERVICE_ARGS
        sendMessage(H.SERVICE_ARGS, s);
    }
}

Handler 类 H handleMessage() 方法针对 what 为 SERVICE_ARGS 的处理,调用 handleServiceArgs() 方法

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;

调用 handleServiceArgs() 方法,在方法内部调用 Serivce 的 onStartCommand() 回调

// ActivityThread#handleServiceArgs()
private void handleServiceArgs(ServiceArgsData data) {
    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) {
                // Serivce 的 onStartCommand() 回调
                res = s.onStartCommand(data.args, data.flags, data.startId);
            } else {
                s.onTaskRemoved(data.args);
                res = Service.START_TASK_REMOVED_COMPLETE;
            }

            QueuedWork.waitToFinish();

            try {
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
        }
    }
}

以上就是Android中的Service启动流程,就是通过AMS(ActivityManagerService)借助 ActiveServices 来完成,由AMS的定义ActivityManagerService extends IActivityManager.Stub 可知这也是一个IPC过程,最后则都是通过 ActivityThread 来内部类H来处理(H是主线程的Handler),主线程的Loop由 ActivityThread 的 main() 方法开启

// ActivityThread#main()
public static void main(String[] args) {
    Looper.prepareMainLooper();
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    Looper.loop();
}

绑定Service过程

Android Service绑定时序图

Android Service绑定时序图.png

上图就是Android Service启动时序图,绑定Service我们也需要启动Service,也就是需要调用Service 的 attach()onCreate() 方法,由图可知,在调用这两个方法的过程中,ActiveServicesActivityThread 中间的过程是一样的。

我们具体的来看一下

我们在 Activity 中调用 bindService() 方法时,直接调用了 调用 ContextWrapperbindService(),接着调用 ContextImplbindService(),查看 ContextImpl 中的代码

@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
    warnIfCallingFromSystemProcess();
    return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, getUser());
}

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
        String instanceName, Handler handler, Executor executor, UserHandle user) {
    IServiceConnection sd;
    // mPackageInfo 为 LoadedApk
    if (mPackageInfo != null) {
        if (executor != null) {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
        } else {
            // handler不为null,将 ServiceConnection 封装成 IServiceConnection
            // IServiceConnection 就是 LoadedApk.ServiceDispatcher.InnerConnection 类
            // 将 conn 保持到InnerConnection中,handler 为主线程Handler,也就是 ActivityThread的内部类 H 对象
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
        }
    } else {
        throw new RuntimeException("Not supported in system context");
    }
    validateServiceIntent(service);
    try {
        IBinder token = getActivityToken();
        if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
                && mPackageInfo.getApplicationInfo().targetSdkVersion
                < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            flags |= BIND_WAIVE_PRIORITY;
        }
        service.prepareToLeaveProcess(this);
        // 调用 AMS 的 bindIsolatedService() 方法
        int res = ActivityManager.getService().bindIsolatedService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
        if (res < 0) {
            throw new SecurityException(
                    "Not allowed to bind to service " + service);
        }
        return res != 0;
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}

注意:在这里需要注意以上注释的地方,因为绑定Service最终客户端要回调 ServiceConnection 对象的 onServiceConnected() 方法,mPackageInfo.getServiceDispatcher() 就是将我们调用 bindService() 方法传递的 ServiceConnection 对象 封装成 IServiceConnection(实现为 LoadedApk#ServiceDispatcher#InnerConnection 类,定义为 InnerConnection extends IServiceConnection.Stub )这是一个aidl接口,这是因为Service启动和绑定时跨进程的,普通的 ServiceConnection 是不能款进程传输的,所以需要进行封装与转换成aidl类型。

先看绑定Service的启动过程

调用 AMS 的 bindIsolatedService() 方法

// ActivityManagerService#bindIsolatedService()
public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
        String resolvedType, IServiceConnection connection, int flags, String instanceName,
        String callingPackage, int userId) throws TransactionTooLargeException {

    synchronized(this) {
        // 调用 ActiveServices 的 bindServiceLocked() 方法
        return mServices.bindServiceLocked(caller, token, service,
                resolvedType, connection, flags, instanceName, callingPackage, userId);
    }
}

由AMS调用 ActiveServices 中的 bindServiceLocked() 方法

// ActiveServices#bindServiceLocked()
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
        String resolvedType, final IServiceConnection connection, int flags,
        String instanceName, String callingPackage, final int userId)
        throws TransactionTooLargeException {
    // ... 省略 

    // 绑定服务时,调用 ServiceRecord 的 retrieveAppBindingLocked() 方法,
    // 在该方法中给 ServiceRecord的bindings 添加绑定记录
    AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
    ConnectionRecord c = new ConnectionRecord(b, activity,
            connection, flags, clientLabel, clientIntent,
            callerApp.uid, callerApp.processName, callingPackage);
    IBinder binder = connection.asBinder();
    // 保存到 ServiceRecord 的 connections 集合中
    s.addConnection(binder, c);
    b.connections.add(c);

    // ... 省略 
    if ((flags&Context.BIND_AUTO_CREATE) != 0) {
        s.lastActivity = SystemClock.uptimeMillis();
        // 调用 bringUpServiceLocked() 方法,后面的启动过程和启动Service一样
        if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                permissionsReviewRequired) != null) {
            return 0;
        }
    }

    // ... 省略 
    return 1;
}

注意,上面注释部分,绑定服务时,我们将连接对象保存到了 ServiceRecord 中。

绑定服务到这里,后面调用 attach() 和 onCreate() 方法就和启动服务时一样的了,在 bringUpServiceLocked() 中 调用
realStartServiceLocked() 方法,接着继续往下调用。

和启动Service不一样的是,在 realStartServiceLocked() 方法中会调用 requestServiceBindingsLocked() 方法,处理绑定服务的过程

绑定过程(onBind() 或者 onRebind() 方法回调过程)

ActiveServices 中的requestServiceBindingsLocked() 方法

// ActiveServices#requestServiceBindingsLocked()
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
        throws TransactionTooLargeException {
    // 根据 ServiceRecord的bindings 是否有数据调用 requestServiceBindingLocked() 方法,在上一步给它添加了数据
    for (int i=r.bindings.size()-1; i>=0; i--) {
        IntentBindRecord ibr = r.bindings.valueAt(i);
        if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
            break;
        }
    }
}

根据是否有连接对象判断是否需要调用 ActiveServices 中的requestServiceBindingLocked() 方法,绑定Service在 ActiveServices 中的 bindServiceLocked() 方法中添加了,所以集合肯定不会为空

// ActiveServices#requestServiceBindingLocked()
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
        boolean execInFg, boolean rebind) throws TransactionTooLargeException {
    
    if ((!i.requested || rebind) && i.apps.size() > 0) {
        try {
            bumpServiceExecutingLocked(r, execInFg, "bind");
            r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            // 调用 ActivityThread 的 scheduleBindService() 方法
            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                    r.app.getReportedProcState());
            if (!rebind) {
                i.requested = true;
            }
            i.hasBound = true;
            i.doRebind = false;
        } catch (TransactionTooLargeException e) {
            return false;
        }
    }
    return true;
}

继续进入 ActivityThread 中调用 scheduleBindService() 方法

// ActivityThread#scheduleBindService
public final void scheduleBindService(IBinder token, Intent intent,
        boolean rebind, int processState) {
    updateProcessState(processState, false);
    BindServiceData s = new BindServiceData();
    s.token = token;
    s.intent = intent;
    s.rebind = rebind;

    // 给 Handler 类 H 发送 BIND_SERVICE
    sendMessage(H.BIND_SERVICE, s);
}

Handler 类 H handleMessage() 方法针对 what 为 BIND_SERVICE 的处理,调用 handleBindService() 方法

case BIND_SERVICE:
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
    handleBindService((BindServiceData)msg.obj);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;

ActivityThread 中调用 handleBindService() 方法

// ActivityThread#handleBindService
private void handleBindService(BindServiceData data) {
    Service s = mServices.get(data.token);
    if (s != null) {
        try {
            data.intent.setExtrasClassLoader(s.getClassLoader());
            data.intent.prepareToEnterProcess();
            try {
                if (!data.rebind) {
                    // 调用 Service 的 onBind() 方法
                    IBinder binder = s.onBind(data.intent);
                    // 这里调用 ActivityManagerService 的 publishService() 方法,
                    ActivityManager.getService().publishService(
                            data.token, data.intent, binder);
                } else {
                    // 如果是重新绑定,就调用 Service 的 onRebind() 方法
                    s.onRebind(data.intent);
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                }
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(s, e)) {
                throw new RuntimeException(
                        "Unable to bind to service " + s
                        + " with " + data.intent + ": " + e.toString(), e);
            }
        }
    }
}

在上面的方法中我们已经看到了 Service 的 onBind() 或者 onRebind() 方法已经被调用了,那么对于Service类来说已经执行完成了。但是我们绑定Service,客户端需要拿到IBinder对象,这个对象是在 ServiceConnection 对象的回调 onServiceConnected() 方法取到的,所以我们继续看看这个过程是怎样的。

调用 ServiceConnection 对象的回调 onServiceConnected() 方法过程

// 这里调用 ActivityManagerService 的 publishService() 方法,
ActivityManager.getService().publishService(data.token, data.intent, binder);

查看以上这句代码,调用 ActivityManagerServicepublishService()方法

// ActivityManagerService#publishService()
public void publishService(IBinder token, Intent intent, IBinder service) {
    synchronized(this) {
        if (!(token instanceof ServiceRecord)) {
            throw new IllegalArgumentException("Invalid service token");
        }
        // 调用 ActiveServices 的 publishServiceLocked() 方法
        mServices.publishServiceLocked((ServiceRecord)token, intent, service);
    }
}

然后调用 ActiveServicespublishServiceLocked() 方法

// ActiveServices#publishServiceLocked()
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    // 从 ServiceRecord 的 connections 集合中取出数据
    ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
    for (int conni = connections.size() - 1; conni >= 0; conni--) {
        ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
        for (int i=0; i<clist.size(); i++) {
            ConnectionRecord c = clist.get(i);
            try {
                // c.conn 为 IServiceConnection 对象
                // 实际就是 LoadedApk.ServiceDispatcher.InnerConnection 类
                c.conn.connected(r.name, service, false);
            } catch (Exception e) {
              
            }
        }
    }
}

这个地方我们先从 ServiceRecord 取出数据,取出来的数据就是包含了客户端 ServiceConnection 对象的aidl接口对象 IServiceConnection (实现类为 LoadedApk#ServiceDispatcher#InnerConnection),所以调用的就是 LoadedApk#ServiceDispatcher#InnerConnection 的 connected() 方法

// LoadedApk 内部类 InnerConnection 的 connected() 方法,也就是上面的 c.conn.connected() 方法
private static class InnerConnection extends IServiceConnection.Stub {
    @UnsupportedAppUsage
    final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

    InnerConnection(LoadedApk.ServiceDispatcher sd) {
        mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
    }

    public void connected(ComponentName name, IBinder service, boolean dead)
            throws RemoteException {
        LoadedApk.ServiceDispatcher sd = mDispatcher.get();
        if (sd != null) {
            // 调用 LoadedApk.ServiceDispatcher 的 connected() 方法
            sd.connected(name, service, dead);
        }
    }
}

调用 LoadedApk#ServiceDispatcher 的 connected() 方法

// LoadedApk.ServiceDispatcher#connected()
public void connected(ComponentName name, IBinder service, boolean dead) {
    if (mActivityExecutor != null) {
        mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
    } else if (mActivityThread != null) {
        // 由 ContextImpl#bindServiceCommon() 方法中可知,mActivityThread 就是 ActivityThread 的 H对象(主线程的Handler),不为null
        // RunConnection 的 run方法中调用 doConnected() 方法
        // 因为是通过主线程的Handler调用的方法,所以客户端的ServiceConnection#onServiceConnected()运行在主线程
        mActivityThread.post(new RunConnection(name, service, 0, dead));
    } else {
        doConnected(name, service, dead);
    }
}

由前面的代码可知,这里的 mActivityThread 不会为 null ,而且就是就是 ActivityThread 的 H对象(主线程的Handler),会调用mActivityThread.post运行任务。RunConnection 代码如下:

// RunConnection 类代码
private final class RunConnection implements Runnable {
    public void run() {
        if (mCommand == 0) {
            // 调用 doConnected() 方法
            doConnected(mName, mService, mDead);
        } else if (mCommand == 1) {
            doDeath(mName, mService);
        }
    }
}

在 RunConnection 中调用 LoadedApk 类的 doConnected() 方法

// LoadedApk#doConnected()
public void doConnected(ComponentName name, IBinder service, boolean dead) {
    // ... 省略

    // 由 ContextImpl#bindServiceCommon() 方法中可知,mConnection 就是客户端的 ServiceConnection 对象,回调它的 onServiceConnected() 方法,完成绑定过程
    if (service != null) {
        mConnection.onServiceConnected(name, service);
    } else {
        // The binding machinery worked, but the remote returned null from onBind().
        mConnection.onNullBinding(name);
    }
}

service不为null时,调用 mconnection 的 onServiceConnected() 方法,mconnection 就是客户端的 ServiceConnection 对象,在前面 ContextImplbindServiceCommon() 方法说明时有注释进行说明了。

以上就是绑定Service以及回调给客户端IBinder东西的完整过程,也就是我们在使用绑定Service时系统的调用过程。对于解绑和停止Service相关类也就是这些,这里就一一贴出代码了,一下提供解绑Service和停止Service的时序图。

解绑Service过程

Android Service解绑时序图.png

停止Service过程

Android Service停止时序图.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容