AndroidService是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AndroidService是啥?相关的知识,希望对你有一定的参考价值。

Service,看名字就知道跟正常理解的“服务”差不多,后台运行,可交互这样的一个东西。它跟Activity的级别差不多,但是他不能自己运行,需要通过某一个Activity或者其他Context对象来调用, Context.startService() 和 Context.bindService()。
两种启动Service的方式有所不同。这里要说明一下的是如果你在Service的onCreate或者onStart做一些很耗时间的事情,最好在Service里启动一个线程来完成,因为Service是跑在主线程中,会影响到你的UI操作或者阻塞主线程中的其他事情。
什么时候需要Service呢?比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。
参考技术A Service就是一个应用程序组件,用来执行一些长时间的操作,然而不与用户交互或者为其他应用程序提供一些功能。每一个Service类都必须定义在androidManifest.xml中,以<service>tag开头。

Android Service 流程分析

Android Service 代码地址

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

启动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 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启动时序图,绑定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过程

停止Service过程

以上是关于AndroidService是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Android Service 流程分析

Android Service更多知识

Android Service回调和配置

Android中服务service

Android 开机自启动service实践

Android Service aidl分析