title: Android Service源码分析
tag: Android源码
category: Android


文章目录

  • Service源码分析
    • Service的启动过程
    • Service的绑定过程
    • Service的取消绑定
    • Service的停止

Service源码分析

Service脑图

Service的启动过程

我们通过startService(Intent service);方法来启动一个Service,跟进源码。调用的是ContextWrapper.startService()

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

这里并没有做什么事情,ContextWrapper是这里用到的一种桥接模式,所有相关函数(Activity相关、Service等)的调用都会先到这个类,但实际还是Context来实现的。调用mBase的startService方法,mBase是一个Context对象,而ContextImpl才是Context的具体实现类,是在Activity创建的时候通过attach关联起来的。

接下来看看ContextImpl的startService方法

@Overridepublic ComponentName startService(Intent service) {    //如果系统进程直接调用该方法,就会抛出警告    warnIfCallingFromSystemProcess();    //false,不需要前台进程;mUser是一个UserHandle    return startServiceCommon(service, false, mUser);}private ComponentName startServiceCommon(Intent service, boolean requireForeground,        UserHandle user) {    try {        //Service的验证        validateServiceIntent(service);        //离开进程准备        service.prepareToLeaveProcess(this);        //重点,通过AMS来startService,返回需要的ComPonentName        //mMainThread.getApplicationThread()主线程的ApplicationThread        ComponentName cn = ActivityManager.getService().startService(            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(                        getContentResolver()), requireForeground,                        getOpPackageName(), user.getIdentifier());        ...        return cn;    } catch (RemoteException e) {        throw e.rethrowFromSystemServer();    }}

ContextImpl的startService方法调用后,会接着调用内部的startServiceCommon方法,在startServiceCommon中先进行了一些少数的准备,接着调用ActivityManager.getService().startService()方法,ActivityManager.getService()是IActivityManager,其实例就是ActivityManagerService对象

接着看AMS(ActivityManagerService)的startService方法

@Overridepublic ComponentName startService(IApplicationThread caller, Intent service,        String resolvedType, boolean requireForeground, String callingPackage, int userId)        throws TransactionTooLargeException {    //一些检验    ...    synchronized(this) {        //进程id        final int callingPid = Binder.getCallingPid();        final int callingUid = Binder.getCallingUid();        final long origId = Binder.clearCallingIdentity();        ComponentName res;        try {            //mServices是一个ActivityServices对象            res = mServices.startServiceLocked(caller, service,                    resolvedType, callingPid, callingUid,                    requireForeground, callingPackage, userId);        } finally {            Binder.restoreCallingIdentity(origId);        }        return res;    }}

在AMS的startService方法中,在一个synchronized代码块中,获取了需要用到的进程id、Binder标识等,然后通过mServices这个ActivityServices对象,调用了其startServiceLocked()方法,ActivityServices跟ActivityStarter的作用是类似的,用来辅助AMS管理Service的类,例如缓存、启动、绑定、停止等

接着看ActivityServices的startServiceLocked方法

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,        int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)        throws TransactionTooLargeException {    ...    //检索Service    ServiceLookupResult res =        retrieveServiceLocked(service, resolvedType, callingPackage,                callingPid, callingUid, userId, true, callerFg, false);    ...    //获取ServiceRecord,一个Service的记录,一直贯穿整个启动过程    ServiceRecord r = res.record;    ...    //权限检查    if (mAm.mPermissionReviewRequired) {        if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage,                callingUid, service, callerFg, userId)) {            return null;        }    }    ...    final ServiceMap smap = getServiceMapLocked(r.userId);    ...    //接着调用内部的startServiceInnerLocked方法    ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);    return cmp;}

startServiceLocked方法前面基本都是一些检查、检索,到最后又调用了内部的startServiceInnerLocked方法

接着看ActivityServices的startServiceInnerLocked方法

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,        boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {    ServiceState stracker = r.getTracker();    if (stracker != null) {        stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);    }    r.callStart = false;    synchronized (r.stats.getBatteryStats()) {        r.stats.startRunningLocked();    }    //后续的工作完成    String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);    if (error != null) {        return new ComponentName("!!", error);    }    //需要为前台Service的处理    if (r.startRequested && addToStarting) {        ...    } else if (callerFg || r.fgRequired) {        smap.ensureNotStartingBackgroundLocked(r);    }    return r.name;}

这里面并没有做太多的工作,具体的启动过程也没有

所以要接着看ActivityServices的bringUpServiceLocked方法

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,        boolean whileRestarting, boolean permissionsReviewRequired)        throws TransactionTooLargeException {    //检验,其他情况的处理    ...    // Service is now being launched, its package can't be stopped.    ...    final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;    final String procName = r.processName;    String hostingType = "service";    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.versionCode, mAm.mProcessStats);                //真正启动的地方                realStartServiceLocked(r, app, execInFg);                return null;            } catch (TransactionTooLargeException e) {                throw e;            } catch (RemoteException e) {                Slog.w(TAG, "Exception when starting service " + r.shortName, e);            }            // If a dead object exception was thrown -- fall through to            // restart the application.        }    } else {        ...    }    // Not running -- get it started, and enqueue this service record    // to be executed when the app comes up.    ...    return null;}

bringUpServiceLocked方法中做了一些其他情况的处理,但真正启动Service却是在realStartServiceLocked方法中

接着看ActivityServices.realStartServiceLocked方法

private final void realStartServiceLocked(ServiceRecord r,        ProcessRecord app, boolean execInFg) throws RemoteException {    ...    final boolean newService = app.services.add(r);    bumpServiceExecutingLocked(r, execInFg, "create");    mAm.updateLruProcessLocked(app, false, null);    updateServiceForegroundLocked(r.app, /* oomAdj= */ false);    mAm.updateOomAdjLocked();    boolean created = false;    try {        if (LOG_SERVICE_START_STOP) {            String nameTerm;            int lastPeriod = r.shortName.lastIndexOf('.');            nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;            EventLogTags.writeAmCreateService(                    r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);        }        synchronized (r.stats.getBatteryStats()) {            r.stats.startLaunchedLocked();        }        mAm.notifyPackageUse(r.serviceInfo.packageName,                             PackageManager.NOTIFY_PACKAGE_USE_SERVICE);        app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);        //通过ApplicationThread来创建一个Service        app.thread.scheduleCreateService(r, r.serviceInfo,                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),                app.repProcState);        r.postNotification();        created = true;    } catch (DeadObjectException e) {        Slog.w(TAG, "Application dead when creating service " + r);        mAm.appDiedLocked(app);        throw e;    } finally {        if (!created) {            // Keep the executeNesting count accurate.            final boolean inDestroying = mDestroyingServices.contains(r);            //出错时停止Service的一些操作            serviceDoneExecutingLocked(r, inDestroying, inDestroying);            // Cleanup.            if (newService) {                app.services.remove(r);                r.app = null;            }            // Retry.            if (!inDestroying) {                scheduleServiceRestartLocked(r, false);            }        }    }    if (r.whitelistManager) {        app.whitelistManager = true;    }    //这里就是后面要分析的绑定过程    requestServiceBindingsLocked(r, execInFg);    updateServiceClientActivitiesLocked(app, null, true);    // If the service is in the started state, and there are no    // pending arguments, then fake up one so its onStartCommand() will    // be called.    ...    //通过该方法来调用Service其他的方法,如onStartCommand()    sendServiceArgsLocked(r, execInFg, true);    ...}

realStartServiceLocked包括了Service的很多操作,先是通过ApplicationThread.scheduleCreateService来创建了Service,接着通过requestServiceBindingsLocked方法进行绑定,再通过sendServiceArgsLocked方法进行其他方法的调用,如onStartCommand()。在sendServiceArgsLocked方法中,又会调用ActivityServices.sendServiceArgsLocked()方法,接着通过ApplicationThread.scheduleServiceArgs()方法,最后调用了Service的onStartCommand方法。

由于分析的是启动过程,所以这里主要看app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState);这行代码,app.thread是IApplicationThread,它的实现类是ApplicationThread,这个类是ActivityThread的内部类

接着在ActivityThread中看ApplicationThread的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;        //发送CREATE_SERVICE的消息创建Service        sendMessage(H.CREATE_SERVICE, s);    }

scheduleCreateService方法代码很少也很简单,创建了一个CreateServiceData的对象,这个对象就是创建Service时需要的信息,然后调用sendMessage方法

接着看ActivityThread的sendMessage方法

private void sendMessage(int what, Object obj) {    sendMessage(what, obj, 0, 0, false);}private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {    if (DEBUG_MESSAGES) Slog.v(        TAG, "SCHEDULE " + what + " " + mH.codeToString(what)        + ": " + arg1 + " / " + obj);    Message msg = Message.obtain();    msg.what = what;    msg.obj = obj;    msg.arg1 = arg1;    msg.arg2 = arg2;    if (async) {        msg.setAsynchronous(true);    }    mH.sendMessage(msg);}

第一个sendMessage方法没啥,后面又重载了一个,所以重点在第二个sendMessage方法,基本上四大组件最后都会在ActivityThread中通过这个函数发送消息。这里,就是重新打包了一下Message,然后通过mH来发送。mH是一个Handler,是ActivityThread内部的一个类,继承自Hanlder。发送完消息后,自然要在H中的来处理消息。

接着看H.handleMessage方法

public void handleMessage(Message msg) {        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));        switch (msg.what) {           ...           //这里主要留着关于Service的,包括create、bind、unbind、stop等            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;            case BIND_SERVICE:                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");                handleBindService((BindServiceData)msg.obj);                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                break;            case UNBIND_SERVICE:                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");                handleUnbindService((BindServiceData)msg.obj);                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                break;            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;            case STOP_SERVICE:                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");                handleStopService((IBinder)msg.obj);                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                break;            ...        }        ...    }}

前面我们发送的消息是CREATE_SERVICE,所以就会调用handleCreateService((CreateServiceData)msg.obj);
在这里可以看见,处理了很多消息,关于Activity、Window等各种的,所以这个H很重要。

接着看ActivityThread的handleCreateService()方法

private void handleCreateService(CreateServiceData data) {    // If we are getting ready to gc after going to the background, well    // we are back active so skip it.    unscheduleGcIdler();    LoadedApk packageInfo = getPackageInfoNoCheck(            data.info.applicationInfo, data.compatInfo);    Service service = null;    try {        java.lang.ClassLoader cl = packageInfo.getClassLoader();        //这里就创建了Service对象,通过类加载器        service = (Service) cl.loadClass(data.info.name).newInstance();    } catch (Exception e) {        if (!mInstrumentation.onException(service, e)) {            throw new RuntimeException(                "Unable to instantiate service " + data.info.name                + ": " + e.toString(), e);        }    }    try {        if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);        //创建了ContextImpl对象        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);        context.setOuterContext(service);        Application app = packageInfo.makeApplication(false, mInstrumentation);        //和Application等关联        service.attach(context, this, data.info.name, data.token, app,                ActivityManager.getService());        //create        service.onCreate();        //放入Service的列表缓存        mServices.put(data.token, service);        try {            //通过AMS来通知创建完成            ActivityManager.getService().serviceDoneExecuting(                    data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);        } catch (RemoteException e) {            throw e.rethrowFromSystemServer();        }    } catch (Exception e) {        if (!mInstrumentation.onException(service, e)) {            throw new RuntimeException(                "Unable to create service " + data.info.name                + ": " + e.toString(), e);        }    }}

到这里,终于看见了Service的创建了,这里的代码很简单。拿到类加载器器,接着通过类加载器创建了Serivce,然后创建ContextImpl对象通过Service的attach关联,最后调用Service的onCreate。

Service的绑定过程

首先bindService(Intent service, ServiceConnection conn, int flags);,接着就是ContentWrapper中bindService方法

@Overridepublic boolean bindService(Intent service, ServiceConnection conn,        int flags) {    return mBase.bindService(service, conn, flags);}

没啥看的,跟Service创建讲的一样,最终还是在ContextImpl中

接着看ContentImpl中的bindService方法

@Overridepublic boolean bindService(Intent service, ServiceConnection conn,        int flags) {    warnIfCallingFromSystemProcess();    return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),            Process.myUserHandle());}

然而这里面并没有什么太多的东西,需要注意的一点就是mMainThread.getHandler(),mMainThread是一个ActivityThread对象,getHandler返回的是ActivityThread中的H,返回了bindServiceCommon()

接着看ContextImpl.bindServiceCommon方法

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler        handler, UserHandle user) {    // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.    IServiceConnection sd;    if (conn == null) {        throw new IllegalArgumentException("connection is null");    }    if (mPackageInfo != null) {        //在这里将ServiceConnection转换为了ServiceDispatcher.InnerConnection对象,且初始化了ServiceDispatcher对象        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来绑定        int res = ActivityManager.getService().bindService(            mMainThread.getApplicationThread(), getActivityToken(), service,            service.resolveTypeIfNeeded(getContentResolver()),            sd, flags, 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();    }}

在这里,首先是将客户端的ServiceConnection对象转换为ServiceDispatcher.InnerConnection对象,之所以不能直接使用ServiceConnection对象是因为服务的绑定有可能是跨进程的,跨进程必须借助Binder,而ServiceDispatcher.InnerConnection刚好充当了Binder的角色。ServiceDispatcher起着链接ServiceConnection和InnerConnection的作用(在取消绑定的时候ServiceDispatcher也会用到)这个过程是由LoadedApk的getServiceDispatcher方法完成。

public final IServiceConnection getServiceDispatcher(ServiceConnection c,        Context context, Handler handler, int flags) {    synchronized (mServices) {        LoadedApk.ServiceDispatcher sd = null;        //ServiceConnection和ServiceDispatcher是一一对应的        ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);        if (map != null) {            if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);            sd = map.get(c);        }        if (sd == null) {            //如果这个ServiceConnection对应的ServiceDispathcer没有就创建一个            sd = new ServiceDispatcher(c, context, handler, flags);            if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);            if (map == null) {                map = new ArrayMap<>();                mServices.put(context, map);            }            map.put(c, sd);        } else {            sd.validate(context, handler);        }        return sd.getIServiceConnection();    }}

系统会首先查找是否存在相同的ServiceConnection,不存在就重新创建一个ServiceDispathcer对象并存储在mServices(private final ArrayMap> mServices = new ArrayMap<>();)中,在SerivceDispatcher的内部又保存了ServiceConnection和InnerConnection。当Service和客户端建立连接后,会通过InnerConnection来调用ServiceConnection中的onServiceConnected方法,又可能跨进程

言归正传,最后还是得通过AMS来进行绑定

接着看AMS的bindService方法

public int bindService(IApplicationThread caller, IBinder token, Intent service,        String resolvedType, IServiceConnection connection, int flags, String callingPackage,        int userId) throws TransactionTooLargeException {    enforceNotIsolatedCaller("bindService");    ...    synchronized(this) {        return mServices.bindServiceLocked(caller, token, service,                resolvedType, connection, flags, callingPackage, userId);    }}

这里AMS并没有做什么实际的事,交给了mServices,mServices是一个ActivityServices对象,调用了其bindServiceLocked方法

接着看ActivityServices的bindServiceLocked方法

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,        String resolvedType, final IServiceConnection connection, int flags,        String callingPackage, final int userId) throws TransactionTooLargeException {    ...    final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);    ...    ActivityRecord activity = null;    if (token != null) {        activity = ActivityRecord.isInStackLocked(token);        if (activity == null) {            Slog.w(TAG, "Binding with unknown activity: " + token);            return 0;        }    }    ...    //检索Service,获取其状态    ServiceLookupResult res =        retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),                Binder.getCallingUid(), userId, true, callerFg, isBindExternal);    ...    ServiceRecord s = res.record;    boolean permissionsReviewRequired = false;    // If permissions need a review before any of the app components can run,    // we schedule binding to the service but do not start its process, then    // we launch a review activity to which is passed a callback to invoke    // when done to start the bound service's process to completing the binding.    if (mAm.mPermissionReviewRequired) {        if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(                s.packageName, s.userId)) {            permissionsReviewRequired = true;            // Show a permission review UI only for binding from a foreground app            if (!callerFg) {                Slog.w(TAG, "u" + s.userId + " Binding to a service in package"                        + s.packageName + " requires a permissions review");                return 0;            }            final ServiceRecord serviceRecord = s;            final Intent serviceIntent = service;            RemoteCallback callback = new RemoteCallback(                    new RemoteCallback.OnResultListener() {                @Override                public void onResult(Bundle result) {                    synchronized(mAm) {                        final long identity = Binder.clearCallingIdentity();                        try {                            if (!mPendingServices.contains(serviceRecord)) {                                return;                            }                            // If there is still a pending record, then the service                            // binding request is still valid, so hook them up. We                            // proceed only if the caller cleared the review requirement                            // otherwise we unbind because the user didn't approve.                            if (!mAm.getPackageManagerInternalLocked()                                    .isPermissionsReviewRequired(                                            serviceRecord.packageName,                                            serviceRecord.userId)) {                                try {                                    //接着调用该方法进行绑定                                    bringUpServiceLocked(serviceRecord,                                            serviceIntent.getFlags(),                                            callerFg, false, false);                                } catch (RemoteException e) {                                    /* ignore - local call */                                }                            } else {                                //取消绑定                                unbindServiceLocked(connection);                            }                        } finally {                            Binder.restoreCallingIdentity(identity);                        }                    }                }            });            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, s.packageName);            intent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback);            if (DEBUG_PERMISSIONS_REVIEW) {                Slog.i(TAG, "u" + s.userId + " Launching permission review for package "                        + s.packageName);            }            mAm.mHandler.post(new Runnable() {                @Override                public void run() {                    mAm.mContext.startActivityAsUser(intent, new UserHandle(userId));                }            });        }    }    final long origId = Binder.clearCallingIdentity();    try {        if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "BIND SERVICE WHILE RESTART PENDING: "                    + s);        }        if ((flags&Context.BIND_AUTO_CREATE) != 0) {            s.lastActivity = SystemClock.uptimeMillis();            if (!s.hasAutoCreateConnections()) {                // This is the first binding, let the tracker know.                ServiceState stracker = s.getTracker();                if (stracker != null) {                    stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),                            s.lastActivity);                }            }        }        mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.curProcState,                s.appInfo.uid, s.name, s.processName);        // Once the apps have become associated, if one of them is caller is ephemeral        // the target app should now be able to see the calling app        mAm.grantEphemeralAccessLocked(callerApp.userId, service,                s.appInfo.uid, UserHandle.getAppId(callerApp.uid));        AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);        ConnectionRecord c = new ConnectionRecord(b, activity,                connection, flags, clientLabel, clientIntent);        IBinder binder = connection.asBinder();        ArrayList<ConnectionRecord> clist = s.connections.get(binder);        if (clist == null) {            clist = new ArrayList<ConnectionRecord>();            s.connections.put(binder, clist);        }        clist.add(c);        b.connections.add(c);        if (activity != null) {            if (activity.connections == null) {                activity.connections = new HashSet<ConnectionRecord>();            }            activity.connections.add(c);        }        b.client.connections.add(c);        if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {            b.client.hasAboveClient = true;        }        if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {            s.whitelistManager = true;        }        if (s.app != null) {            updateServiceClientActivitiesLocked(s.app, c, true);        }        clist = mServiceConnections.get(binder);        if (clist == null) {            clist = new ArrayList<ConnectionRecord>();            mServiceConnections.put(binder, clist);        }        clist.add(c);        if ((flags&Context.BIND_AUTO_CREATE) != 0) {            s.lastActivity = SystemClock.uptimeMillis();            if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,                    permissionsReviewRequired) != null) {                return 0;            }        }        if (s.app != null) {            if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {                s.app.treatLikeActivity = true;            }            if (s.whitelistManager) {                s.app.whitelistManager = true;            }            // This could have made the service more important.            mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities                    || s.app.treatLikeActivity, b.client);            mAm.updateOomAdjLocked(s.app, true);        }        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b                + ": received=" + b.intent.received                + " apps=" + b.intent.apps.size()                + " doRebind=" + b.intent.doRebind);        if (s.app != null && b.intent.received) {            // Service is already running, so we can immediately            // publish the connection.            try {                c.conn.connected(s.name, b.intent.binder, false);            } catch (Exception e) {                Slog.w(TAG, "Failure sending service " + s.shortName                        + " to connection " + c.conn.asBinder()                        + " (in " + c.binding.client.processName + ")", e);            }            // If this is the first app connected back to this binding,            // and the service had previously asked to be told when            // rebound, then do so.            if (b.intent.apps.size() == 1 && b.intent.doRebind) {                requestServiceBindingLocked(s, b.intent, callerFg, true);            }        } else if (!b.intent.requested) {            requestServiceBindingLocked(s, b.intent, callerFg, false);        }        getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);    } finally {        Binder.restoreCallingIdentity(origId);    }    return 1;}

在这里又调用了bringUpServiceLocked方法,这个方法是不是很眼熟?在前面启动Service的时候,也会调用到这个方法,所以后面的就跟Service的启动一样了。但是我们前面讲创建的时候留了一个东西,就是Service创建成功后,绑定的方法我们并没有讲。那么就这前面的讲。

调用了ActivityServices的bringUpServiceLocked方法后,又会接着调用ActivityServices.realStartServiceLocked(),这个方法前面启动Service时也讲到过

我们再看看这个方法

private final void realStartServiceLocked(ServiceRecord r,        ProcessRecord app, boolean execInFg) throws RemoteException {    ...    r.app = app;    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();    final boolean newService = app.services.add(r);    bumpServiceExecutingLocked(r, execInFg, "create");    mAm.updateLruProcessLocked(app, false, null);    updateServiceForegroundLocked(r.app, /* oomAdj= */ false);    mAm.updateOomAdjLocked();    boolean created = false;    try {        ...        //创建Service        app.thread.scheduleCreateService(r, r.serviceInfo,                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),                app.repProcState);        r.postNotification();        created = true;    } catch (DeadObjectException e) {        Slog.w(TAG, "Application dead when creating service " + r);        mAm.appDiedLocked(app);        throw e;    } finally {        ...    }    ...    //这里就是我们前面留着的绑定Service    requestServiceBindingsLocked(r, execInFg);    updateServiceClientActivitiesLocked(app, null, true);    ...    //通过该方法来调用Service其他的方法,如onStartCommand()    sendServiceArgsLocked(r, execInFg, true);    ...}

这个方法很熟悉了吧,但是接下来我们就不去看Service怎么创建的了。我们这里主要看Service怎样绑定的

接着ActivityServices的requestServiceBindingsLocked方法

private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)        throws TransactionTooLargeException {    for (int i=r.bindings.size()-1; i>=0; i--) {        IntentBindRecord ibr = r.bindings.valueAt(i);        if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {            break;        }    }}

这里面并没有做太多的事,遍历所有的IntentBindRecord,接着还是调用重载的requestServiceBindingsLocked方法

接着看这个重载的requestServiceBindingsLocked方法

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,        boolean execInFg, boolean rebind) throws TransactionTooLargeException {    if (r.app == null || r.app.thread == null) {        // If service is not currently running, can't yet bind.        return false;    }    if (DEBUG_SERVICE) Slog.d(TAG_SERVICE, "requestBind " + i + ": requested=" + i.requested            + " rebind=" + rebind);    if ((!i.requested || rebind) && i.apps.size() > 0) {        try {            bumpServiceExecutingLocked(r, execInFg, "bind");            r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);            //熟悉的app.thread又来了            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,                    r.app.repProcState);            if (!rebind) {                i.requested = true;            }            i.hasBound = true;            i.doRebind = false;        } catch (TransactionTooLargeException e) {            // Keep the executeNesting count accurate.            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);            final boolean inDestroying = mDestroyingServices.contains(r);            serviceDoneExecutingLocked(r, inDestroying, inDestroying);            throw e;        } catch (RemoteException e) {            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);            // Keep the executeNesting count accurate.            final boolean inDestroying = mDestroyingServices.contains(r);            serviceDoneExecutingLocked(r, inDestroying, inDestroying);            return false;        }    }    return true;}

在这个方法中,从ServiceRecord中拿到ApplicationThread,然后调用scheduleBindService方法

接着看ActivityThread.ApplicationThread.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;        if (DEBUG_SERVICE)            Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="                    + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());        sendMessage(H.BIND_SERVICE, s);    }

熟悉的一切,跟Service的创建是一样的。在这里会调用ActivityThread的sendMessage()方法,然后重载一次,通过mH这个Handler的sendMessage发送。然后在H中的handleMessage中处理消息,接着又调用ActivityThread.handleBindService()

接着看看ActivityThread.handleBindService()这个方法

private void handleBindService(BindServiceData data) {    //获取之前创建的Service    Service s = mServices.get(data.token);    if (DEBUG_SERVICE)        Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);    if (s != null) {        try {            data.intent.setExtrasClassLoader(s.getClassLoader());            data.intent.prepareToEnterProcess();            try {                if (!data.rebind) {                    //绑定                    IBinder binder = s.onBind(data.intent);                    //通知客户端绑定成功                    ActivityManager.getService().publishService(                            data.token, data.intent, binder);                } else {                    s.onRebind(data.intent);                    ActivityManager.getService().serviceDoneExecuting(                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);                }                ensureJitEnabled();            } 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方法,就绑定完成了。然后系统会通知客户端,接着看看如何通知客户端的

AMS.publishService方法

public void publishService(IBinder token, Intent intent, IBinder service) {    // Refuse possible leaked file descriptors    if (intent != null && intent.hasFileDescriptors() == true) {        throw new IllegalArgumentException("File descriptors passed in Intent");    }    synchronized(this) {        if (!(token instanceof ServiceRecord)) {            throw new IllegalArgumentException("Invalid service token");        }        mServices.publishServiceLocked((ServiceRecord)token, intent, service);    }}

从代码中可以看出,最终还是交到了ActivityServices中处理

接着看ActivityServices的publishServiceLocked方法

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {    final long origId = Binder.clearCallingIdentity();    try {        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r                + " " + intent + ": " + service);        if (r != null) {            Intent.FilterComparison filter                    = new Intent.FilterComparison(intent);            IntentBindRecord b = r.bindings.get(filter);            if (b != null && !b.received) {                b.binder = service;                b.requested = true;                b.received = true;                for (int conni=r.connections.size()-1; conni>=0; conni--) {                    ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);                    for (int i=0; i<clist.size(); i++) {                        ConnectionRecord c = clist.get(i);                        ...                        try {                            //这里才是重点                            c.conn.connected(r.name, service, false);                        } catch (Exception e) {                            Slog.w(TAG, "Failure sending service " + r.name +                                  " to connection " + c.conn.asBinder() +                                  " (in " + c.binding.client.processName + ")", e);                        }                    }                }            }            serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);        }    } finally {        Binder.restoreCallingIdentity(origId);    }}

c.conn是ServiceDispatcher.InnerConnection

所以接着看看LoadedApk.ServiceDispatcher.InnerConnection的connected方法

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

在这里可以看出,先是从mDispatcher中获取了ServiceDispatcher,然后调用了其connected方法。mDispatcher中存储着之前在ContextImpl.bindService()中将ServiceConnection转换为ServiceDispatcher.InnerConnection处创建的ServiceDispatcher

接着看LoadedApk.ServiceDispatcher的connected方法

public void connected(ComponentName name, IBinder service, boolean dead) {    if (mActivityThread != null) {        mActivityThread.post(new RunConnection(name, service, 0, dead));    } else {        doConnected(name, service, dead);    }}

通过mActivityThread post了一个RunConnection对象,mActivityThread就是一个Handler,是ActivityThread中的H(在ContextImpl的bindService中,调用bindServiceCommon时,通过mMainThread.getHandler获取,也就是在这里开始传入的),RunConnection就通过H发送到了主线程

简单看看RunConnection

private final class RunConnection implements Runnable {    RunConnection(ComponentName name, IBinder service, int command, boolean dead) {        mName = name;        mService = service;        mCommand = command;        mDead = dead;    }    public void run() {        if (mCommand == 0) {            doConnected(mName, mService, mDead);        } else if (mCommand == 1) {            doDeath(mName, mService);        }    }    final ComponentName mName;    final IBinder mService;    final int mCommand;    final boolean mDead;}

在这里会调用ServiceDispatcher的doConnected方法

接着看一些LoadedApk.ServiceDispatcher.doConnected

public void doConnected(ComponentName name, IBinder service, boolean dead) {    ServiceDispatcher.ConnectionInfo old;    ServiceDispatcher.ConnectionInfo info;    ...    // If there was an old service, it is now disconnected.    if (old != null) {        mConnection.onServiceDisconnected(name);    }    if (dead) {        mConnection.onBindingDied(name);    }    // If there is a new service, it is now connected.    if (service != null) {        mConnection.onServiceConnected(name, service);    }}

由于ServiceDispatcher保存右ServiceConnection,所以可以很方便的调用ServiceConnection的onServiceConnected方法

Service的取消绑定

unbindService(ServiceConnection conn);开始,先是ContextWrapper的unbindService方法

@Overridepublic void unbindService(ServiceConnection conn) {    mBase.unbindService(conn);}

然后接着还是ContextImpl中的unBindService方法

@Overridepublic void unbindService(ServiceConnection conn) {    if (conn == null) {        throw new IllegalArgumentException("connection is null");    }    if (mPackageInfo != null) {        //将ServiceConnection转换回IServiceConnection        IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(                getOuterContext(), conn);        try {            //AMS中的unbindService            ActivityManager.getService().unbindService(sd);        } catch (RemoteException e) {            throw e.rethrowFromSystemServer();        }    } else {        throw new RuntimeException("Not supported in system context");    }}

在这里先是通过LoadedApk.forgetServiceDispatcher方法将ServiceConnection转换回IServiceConnection,并对ServiceDispatcher做一些预处理,如remove掉这个ServiceConnection匹配的ServiceDispatcher,接着还是到了AMS中

接着看AMS的unbindService方法

public boolean unbindService(IServiceConnection connection) {    synchronized (this) {        return mServices.unbindServiceLocked(connection);    }}

然后又交给了ActivityServices

接着看ActivityServices.unbindServiceLocked方法

boolean unbindServiceLocked(IServiceConnection connection) {    IBinder binder = connection.asBinder();    if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "unbindService: conn=" + binder);    ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);    ...    final long origId = Binder.clearCallingIdentity();    try {        while (clist.size() > 0) {            ConnectionRecord r = clist.get(0);            //这么重要的remove            removeConnectionLocked(r, null, null);            ...            if (r.binding.service.app != null) {                if (r.binding.service.app.whitelistManager) {                    updateWhitelistManagerLocked(r.binding.service.app);                }                // This could have made the service less important.                if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {                    r.binding.service.app.treatLikeActivity = true;                    mAm.updateLruProcessLocked(r.binding.service.app,                            r.binding.service.app.hasClientActivities                            || r.binding.service.app.treatLikeActivity, null);                }                mAm.updateOomAdjLocked(r.binding.service.app, false);            }        }        mAm.updateOomAdjLocked();    } finally {        Binder.restoreCallingIdentity(origId);    }    return true;}

看重要的,就知道下面是removeConnectionLocked(r, null, null);这个方法

接着看ActivityServices的removeConnectionLocked方法

void removeConnectionLocked(    ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {    IBinder binder = c.conn.asBinder();    AppBindRecord b = c.binding;    ServiceRecord s = b.service;    ArrayList<ConnectionRecord> clist = s.connections.get(binder);    if (clist != null) {        clist.remove(c);        if (clist.size() == 0) {            s.connections.remove(binder);        }    }    b.connections.remove(c);    if (c.activity != null && c.activity != skipAct) {        if (c.activity.connections != null) {            c.activity.connections.remove(c);        }    }    if (b.client != skipApp) {        b.client.connections.remove(c);        if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {            b.client.updateHasAboveClientLocked();        }        // If this connection requested whitelist management, see if we should        // now clear that state.        if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {            s.updateWhitelistManager();            if (!s.whitelistManager && s.app != null) {                updateWhitelistManagerLocked(s.app);            }        }        if (s.app != null) {            updateServiceClientActivitiesLocked(s.app, c, true);        }    }    clist = mServiceConnections.get(binder);    if (clist != null) {        clist.remove(c);        if (clist.size() == 0) {            mServiceConnections.remove(binder);        }    }    mAm.stopAssociationLocked(b.client.uid, b.client.processName, s.appInfo.uid, s.name);    if (b.connections.size() == 0) {        b.intent.apps.remove(b.client);    }    if (!c.serviceDead) {        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Disconnecting binding " + b.intent                + ": shouldUnbind=" + b.intent.hasBound);        if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0                && b.intent.hasBound) {            try {                bumpServiceExecutingLocked(s, false, "unbind");                if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0                        && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {                    // If this service's process is not already in the cached list,                    // then update it in the LRU list here because this may be causing                    // it to go down there and we want it to start out near the top.                    mAm.updateLruProcessLocked(s.app, false, null);                }                mAm.updateOomAdjLocked(s.app, true);                b.intent.hasBound = false;                // Assume the client doesn't want to know about a rebind;                // we will deal with that later if it asks for one.                b.intent.doRebind = false;                //ApplicationThread,又是这个方式调用                s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());            } catch (Exception e) {                Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);                serviceProcessGoneLocked(s);            }        }        // If unbound while waiting to start, remove the pending service        mPendingServices.remove(s);        if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {            boolean hasAutoCreate = s.hasAutoCreateConnections();            if (!hasAutoCreate) {                if (s.tracker != null) {                    s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),                            SystemClock.uptimeMillis());                }            }            bringDownServiceIfNeededLocked(s, true, hasAutoCreate);        }    }}

这个方法里面有太多的remove了,感兴趣的可以自己去分析分析。我们看重点s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());,这里是多么熟悉,又是到ApplicationThread中

接着看ApplicationThread的scheduleUnbindService方法

public final void scheduleUnbindService(IBinder token, Intent intent) {    BindServiceData s = new BindServiceData();    s.token = token;    s.intent = intent;    sendMessage(H.UNBIND_SERVICE, s);}

后面的就都是一样的,在ActivityThread中辗转反则,最后通过ActivityThread的H发送,在H中处理消息,然后会调用ActivityThread的handleUnbindServicef方法

接着看这个方法

private void handleUnbindService(BindServiceData data) {    //获取Service    Service s = mServices.get(data.token);    if (s != null) {        try {            data.intent.setExtrasClassLoader(s.getClassLoader());            data.intent.prepareToEnterProcess();            //调用unBind            boolean doRebind = s.onUnbind(data.intent);            try {                if (doRebind) {                    //如果需要重新绑定                    ActivityManager.getService().unbindFinished(                            data.token, data.intent, doRebind);                } else {                    //已经取消绑定                    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 unbind to service " + s                        + " with " + data.intent + ": " + e.toString(), e);            }        }    }}

注释很清楚了,先获取Service,接着调用Service的onUnbind方法,接着看看AMS的serviceDoneExecuting方法吧

public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {    synchronized(this) {        if (!(token instanceof ServiceRecord)) {            Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);            throw new IllegalArgumentException("Invalid service token");        }        //又去了ActivityServices        mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);    }}

接着看ActivityServices的serviceDoneExecutingLocked方法

void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {    boolean inDestroying = mDestroyingServices.contains(r);    if (r != null) {        ...        final long origId = Binder.clearCallingIdentity();        //接着调用        serviceDoneExecutingLocked(r, inDestroying, inDestroying);        Binder.restoreCallingIdentity(origId);    } else {        Slog.w(TAG, "Done executing unknown service from pid "                + Binder.getCallingPid());    }}

接着看ActivityServices的serviceDoneExecutingLocked重载方法

private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,        boolean finishing) {    if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "<<< DONE EXECUTING " + r            + ": nesting=" + r.executeNesting            + ", inDestroying=" + inDestroying + ", app=" + r.app);    else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,            "<<< DONE EXECUTING " + r.shortName);    r.executeNesting--;    if (r.executeNesting <= 0) {        if (r.app != null) {            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,                    "Nesting at 0 of " + r.shortName);            r.app.execServicesFg = false;            r.app.executingServices.remove(r);            if (r.app.executingServices.size() == 0) {                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,                        "No more executingServices of " + r.shortName);                mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);            } else if (r.executeFg) {                // Need to re-evaluate whether the app still needs to be in the foreground.                for (int i=r.app.executingServices.size()-1; i>=0; i--) {                    if (r.app.executingServices.valueAt(i).executeFg) {                        r.app.execServicesFg = true;                        break;                    }                }            }            if (inDestroying) {                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,                        "doneExecuting remove destroying " + r);                mDestroyingServices.remove(r);                r.bindings.clear();            }            mAm.updateOomAdjLocked(r.app, true);        }        r.executeFg = false;        if (r.tracker != null) {            r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),                    SystemClock.uptimeMillis());            if (finishing) {                r.tracker.clearCurrentOwner(r, false);                r.tracker = null;            }        }        if (finishing) {            if (r.app != null && !r.app.persistent) {                r.app.services.remove(r);                if (r.whitelistManager) {                    updateWhitelistManagerLocked(r.app);                }            }            r.app = null;        }    }}

又是各种remove,remove的消息

Service的停止

stopService(Intent name);开始,然后是ContextWrapper中

@Overridepublic boolean stopService(Intent name) {    return mBase.stopService(name);}

然后具体的实现是在ContextImpl中

@Overridepublic boolean stopService(Intent service) {    warnIfCallingFromSystemProcess();    return stopServiceCommon(service, mUser);}

接着调用了ContextImpl内部的stopServiceCommon方法

private boolean stopServiceCommon(Intent service, UserHandle user) {    try {        //这都是一些准备        validateServiceIntent(service);        service.prepareToLeaveProcess(this);        //还是AMS        int res = ActivityManager.getService().stopService(            mMainThread.getApplicationThread(), service,            service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());        if (res < 0) {            throw new SecurityException(                    "Not allowed to stop service " + service);        }        return res != 0;    } catch (RemoteException e) {        throw e.rethrowFromSystemServer();    }}

做一些准备后,又到了AMS中的stopService

@Overridepublic int stopService(IApplicationThread caller, Intent service,        String resolvedType, int userId) {    enforceNotIsolatedCaller("stopService");    // Refuse possible leaked file descriptors    if (service != null && service.hasFileDescriptors() == true) {        throw new IllegalArgumentException("File descriptors passed in Intent");    }    synchronized(this) {        return mServices.stopServiceLocked(caller, service, resolvedType, userId);    }}

好吧,AMS还是交给了ActivityServices
接着看看ActivityServices的stopServiceLocked方法

int stopServiceLocked(IApplicationThread caller, Intent service,        String resolvedType, int userId) {    if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "stopService: " + service            + " type=" + resolvedType);    final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);    if (caller != null && callerApp == null) {        throw new SecurityException(                "Unable to find app for caller " + caller                + " (pid=" + Binder.getCallingPid()                + ") when stopping service " + service);    }    // If this service is active, make sure it is stopped.    //确保这个Service是要停止的检查    ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, null,            Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false, false);    if (r != null) {        if (r.record != null) {            final long origId = Binder.clearCallingIdentity();            try {                //内部方法调用                stopServiceLocked(r.record);            } finally {                Binder.restoreCallingIdentity(origId);            }            return 1;        }        return -1;    }    return 0;}

接着还是调用ActivityServices内部的stopServiceLocked方法

private void stopServiceLocked(ServiceRecord service) {    ...    //继续    bringDownServiceIfNeededLocked(service, false, false);}

接着还是调用ActivityServices的bringDownServiceIfNeededLocked方法

private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,        boolean hasConn) {    ...    bringDownServiceLocked(r);}

接着还是调用ActivityServices的bringDownServiceLocked方法

private final void bringDownServiceLocked(ServiceRecord r) {    ...    // Tell the service that it has been unbound.    if (r.app != null && r.app.thread != null) {        for (int i=r.bindings.size()-1; i>=0; i--) {            IntentBindRecord ibr = r.bindings.valueAt(i);            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down binding " + ibr                    + ": hasBound=" + ibr.hasBound);            if (ibr.hasBound) {                try {                    bumpServiceExecutingLocked(r, false, "bring down unbind");                    mAm.updateOomAdjLocked(r.app, true);                    ibr.hasBound = false;                    ibr.requested = false;                    //停止之前先取消绑定                    r.app.thread.scheduleUnbindService(r,                            ibr.intent.getIntent());                } catch (Exception e) {                    Slog.w(TAG, "Exception when unbinding service "                            + r.shortName, e);                    serviceProcessGoneLocked(r);                }            }        }    }    ...    if (r.app != null) {        synchronized (r.stats.getBatteryStats()) {            r.stats.stopLaunchedLocked();        }        r.app.services.remove(r);        if (r.whitelistManager) {            updateWhitelistManagerLocked(r.app);        }        if (r.app.thread != null) {            updateServiceForegroundLocked(r.app, false);            try {                bumpServiceExecutingLocked(r, false, "destroy");                mDestroyingServices.add(r);                r.destroying = true;                mAm.updateOomAdjLocked(r.app, true);                //停止                r.app.thread.scheduleStopService(r);            } catch (Exception e) {                Slog.w(TAG, "Exception when destroying service "                        + r.shortName, e);                serviceProcessGoneLocked(r);            }        } else {            if (DEBUG_SERVICE) Slog.v(                TAG_SERVICE, "Removed service that has no process: " + r);        }    } else {        if (DEBUG_SERVICE) Slog.v(            TAG_SERVICE, "Removed service that is not running: " + r);    }    ...}

这个方法中的代码有很多,但是关键还是.app.thread.scheduleStopService(r);这行代码

接着看ApplicationThread中的scheduleStopService方法

public final void scheduleStopService(IBinder token) {    sendMessage(H.STOP_SERVICE, token);}

好吧,熟悉的一切,跟前面的启动、绑定、取消绑定一样,最后调用H处理消息,然后调用ActivityThread的handleStopService方法

private void handleStopService(IBinder token) {    //从列表中移除Service    Service s = mServices.remove(token);    if (s != null) {        try {            if (localLOGV) Slog.v(TAG, "Destroying service " + s);            //销毁Service            s.onDestroy();            s.detachAndCleanUp();            Context context = s.getBaseContext();            if (context instanceof ContextImpl) {                final String who = s.getClassName();                ((ContextImpl) context).scheduleFinalCleanup(who, "Service");            }            QueuedWork.waitToFinish();            try {                //通知完成停止操作                ActivityManager.getService().serviceDoneExecuting(                        token, SERVICE_DONE_EXECUTING_STOP, 0, 0);            } catch (RemoteException e) {                throw e.rethrowFromSystemServer();            }        } catch (Exception e) {            if (!mInstrumentation.onException(s, e)) {                throw new RuntimeException(                        "Unable to stop service " + s                        + ": " + e.toString(), e);            }            Slog.i(TAG, "handleStopService: exception for " + token, e);        }    } else {        Slog.i(TAG, "handleStopService: token=" + token + " not found.");    }    //Slog.i(TAG, "Running services: " + mServices);}

先是从mServices中移除了要停止的Service,然后调用Service的onDestory销毁,最后通过AMS来发出通知(ActivityManager.getService().serviceDoneExecuting(token, SERVICE_DONE_EXECUTING_STOP, 0, 0);)后面的就跟取消绑定一样了

更多相关文章

  1. 【Android-tips】 Unable to execute dex: Multiple dex files d
  2. Android 访问Webservice接口,参数对象不能串行化问题解决(java.lan
  3. Android GridView的使用方法
  4. Activity之间传递对象
  5. ScrollView拉到尽头时出现阴影的解决方法
  6. php、java、android、ios通用的3des+base64加密方法
  7. android中webView JS调用Android的方法、webView的下拉刷新(Swipe
  8. 转:Android中几种图像特效处理方法小结

随机推荐

  1. 用PHP实现高并发服务器
  2. Tideways、xhprof 和 xhgui 打造 PHP 非
  3. 【笔试题】用PHP写一个微波炉
  4. 使用file_get_contents()函数读取文件内
  5. PHP后门的一些用法
  6. PHP并发性能调优实战(性能提升104%)
  7. 使用file_put_contents()创建及向文档内
  8. 面向对象的程序设计语言是一种什么语言
  9. Dockerfile构建PHP镜像
  10. phpcms模板怎么安装