Android Service 流程分析

九章 等级 771 0 0

启动Service过程


Android 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 流程分析

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 流程分析

Android Service解绑时序图.png

停止Service过程

Android Service 流程分析

Android Service停止时序图.png

本文转自 https://www.jianshu.com/p/752d51d487de,如有侵权,请联系删除。

收藏
评论区

相关推荐

IntentService使用以及源码分析
一 概述 我们知道,在Android开发中,遇到耗时的任务操作时,都是放到子线程去做,或者放到Service中去做,在Service中开一个子线程来执行耗时操作。 那么,在Service里面我们需要自己管理Service的生命周期,何时开启何时关闭,还是很麻烦的,还好Android给我们提供了一个这样的类,叫做IntentService 那么Intent
Android深入浅出之Binder机制
Android深入浅出之Binder机制 一 说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。所以搞明白Binder的话,在很大程度上就能理解程序运行的流程。 我们这里将以MediaService的例子来分析Binder的使用: ServiceMan
Android Service 流程分析
启动Service过程 Android Service启动时序图 (https://imghelloworld.osscnbeijing.aliyuncs.com/039313fdaaf1e7dea3bde222b3ec9934.png) Android Service启动时序图.png 上图就是Android
Android深入四大组件(二)Service的启动过程
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「刘望舒」 前言此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程。建议阅读此篇文章前,请先阅读和这两篇文章。<!more 1.ContextImpl到Activi
Android深入四大组件(三)Service的绑定过程
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「刘望舒」 前言我们可以通过调用Context的startService来启动Service,也可以通过Context的bindService来绑定Service,建议阅读此篇文章前请阅读这篇文章,知识点重叠的部分,本篇文章将不再赘述。<!more
16年工作日志
### 0331: 1.Random 随机数 2.DreamService 互动屏保 http://www.cnblogs.com/rustfisher/p/5232471.html 3.http://blog.csdn.net/andylao62/article/details/44060245 4.Android 服务类Service 的详细学习
Android Service详解
service作为四大组件值得我们的更多的关注 ======================= 在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务。例如,一个从service播放音乐的音乐播放器,应被设置为前台运行,因为用户会明确地注意它的运行.在状态栏中的通知可能会显示当前的歌曲并且允许用户启动一个act
AlarmManager研究
**AlarmManager研究** 侯 亮 1.概述 ====         在Android系统中,闹钟和唤醒功能都是由Alarm Manager Service控制并管理的。我们所熟悉的RTC闹钟以及定时器都和它有莫大的关系。为了便于称呼,我常常也把这个service简称为ALMS。         另外,ALMS还提供了一个AlarmMan
Android Service演义
Android Service演义 (本文以Android 5.1为准) 侯亮 1.概述 ======= 在Android平台上,那种持续性工作一般都是由service来执行的。不少初学者总是搞不清service和线程、进程之间的关系,这当然会影响到他们开展具体的开发工作。 其实,简单说起来,service和线程、进程是没什么关系的。我
Android Service的onStartCommand返回值用法
Android Service的onStartCommand返回值用法 ### 本文目的:使读者快速理解 1、START\_STICKY: 如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由 于服务状态为开始状态,所以创建服务后一定会调用onStartComma
Android service的使用
Services ======== 一个[Service](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fdeveloper.android.com%2Freference%2Fandroid%2Fapp%2FService.html)是一个应用组件,它可以在后台执行耗时长的操作,而不提供
Android后台保活实践总结:即时通讯应用无法根治的“顽疾”
**前言** ====== Android进程和Service的保活,是困扰Android开发人员的一大顽疾。因涉及到省电和内存管理策略,各厂商基于自家的理解,在自已ROOM发布于都对标准Android发行版作为或多或少的改动,使得应用层程序在处理进程和Service保活问题上变的异常复杂,且很难兼容,因为说不定哪款手机或者哪个版本的省电策略发生改变,那么
Android深入浅出之Binder机制
Android深入浅出之Binder机制 一 说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。所以搞明白Binder的话,在很大程度上就能理解程序运行的流程。 我们这里将以MediaService的例子来分析Binder的使用: l ServiceMana
Rxjava和EventBus对比
总的来说,EventBus是一款针对Android优化的发布/订阅事件总线,主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息。而Rxjava则是一种基于异步数据流的处理方案。如果一个订阅者需要注册多个事件的时候,Rxjava需要一个个单独的注册,而EventBus则可以实现一
Service Mesh对企业安全而言意味着什么?
你听说过Service Mesh(服务网格)吗? 我相信你听说过。Service Mesh正成为容器生态圈愈发重要的一部分。 本文将简要概述Service Mesh的作用,并深入探讨它们对于企业安全性的意义。 ![输入图片说明](https://static.oschina.net/uploads/img/201804/12175538_YJWW.jp