Android Service 流程分析

九章 等级 390 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
js动态生成二维码
需求:项目需要根据链接实时生成二维码,当检测终端是PC时,将当前项目链接生成二维码供用户手机端使用 判断终端是否为mobile function isMobile () { let flag navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile
参考阿里规范,优秀的 Java 项目代码该如何分层?
1.背景 说起应用分层,大部分人都会认为这个不是很简单嘛 就controller,service, mapper三层。看起来简单,很多人其实并没有把他们职责划分开,在很多代码中,controller做的逻辑比service还多,service往往当成透传了,这其实是很多人开发代码都没有注意到的地方,反正功能也能用,至于放哪无所谓呗。这样往往造成后
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开发 常见异常和解决办法(一)
Android Studio是Android开发的理想工具,但是由于版本的更新和配置的差异,会出现很多问题,下面是以《第一行代码 第二版》为基础进行开发学习可能遇见的一些问题及其解决办法。 1.Android Studio 3.0及以上版本找不到Android Device Monitor: 解决办法: (1)在Android Studio中打开终端,如下
Kubernetes Ingress — NGINX
在 Kubernetes 中,Service 是一种抽象的概念,它定义了每一组 Pod 的逻辑集合和访问方式,并提供一个统一的入口,将请求进行负载分发到后端的各个 Pod 上。Service 默认类型是 ClusterIP,集群内部的应用服务可以相互访问,但集群外部的应用服务无法访问。为此 Kubernetes 提供了 NodePorts,LoadBalan
Android动态更新APP图标
但凡一款用户量有一定的规模之后,运营都会在逢年过节的时候做一些活动来提高日活,促销商品等。所以为了配合活动,我们开发也需要在App启动图标上做出活动的效果,换一个活动图标,而且还在不额外发布版本的情况下。 效果演示图: 实现步骤 1.首先在AndroidManifest中创建一个activity的别名,用于替换启动页的ac
GO开发 - etcd用法
etcd是什么? A highlyavailable key value store for shared configuration and service discovery.是一个键值存储仓库,用于配置共享和服务发现 概念:高可用的分布式ke
Django+Vue开发生鲜电商平台之4.Restful API和Vue介绍
也许今天你是最好的,但未必明天还最好;今天也许你是最差的,但社会给了你很多的机会,只要你把握,只要努力,总会有机会。 ——马云Github和Gitee代码同步更新:;。后端架构搭建好之后,需要搭建前端架构。 一、Restful API介绍 1.前后端分离优缺点近年来,随着多种平台类型(PC端、Android端、Mac端、iPhone端、P
uni-app开发 常见异常和解决办法
前言uniapp 是一个基于 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。在开发过程中可能会遇到一些异常,这些异常及其解决办法总结如下。 1.调用微信开发者工具报错IDE service port dis
Android深入理解Context(二)Activity和Service的Context创建过程
Android框架层 Android深入理解Contextcategories: Android框架层本文首发于微信公众号「刘望舒」 前言上一篇文章我们学习了Context关联类和Application Context的创建过程,这一篇我们接着来学习Activity和Service的Context创建过程。需要注意的是,本篇的知识点会和深入理解四大组件系列的
SSM项目中遇到Could not autowire. No beans of ‘XXX‘ type found.错误
写代码时候遇到了这个问题Could not autowire. No beans of HeadLineService' type found.提示这个错误,是因为在Service的实现类HeadLineServiceImpl中忘记在类的头部加注解@Service解决如下图。
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