Android开发艺术探索——第九章:四大组件的工作过程(中)

在上一篇我们一起学习了Activity的工作过程,这才是我们的的第一个组件,我们接着来看我们的后三个组件

一.Service的工作过程

本文中,我们将连接Service的启动过程和绑定过程,在分析Service的工作过程之前,我们先来了解一下如何使用Service,我们都知道,Service有两种状态,一种是启动状态,一种是绑定状态,前者是处理后台逻辑后者是处理与其他组件的交互,需要注意的是,这两种状态是可以共存的

  • 启动
    Intent intent = new Intent(this, TestService.class);
    startService(intent);
  • 绑定
    Intent intent = new Intent(this, TestService.class);
    bindService(intent,mServiceConnection,BIND_AUTO_CREATE);

1.Service的启动过程

Service的启动过程从ContextWrapper的startService开始

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

上面的代码中,mBase是ContextImpl类型,我们都知道在Activity被创建的时候会通过attach方法将一个ContextImpl对象关联起来,这个ContextImpl对象就是上述代码的mBase,从ContextWrapper的实现可以看出,他的大部分操作都在mBase里实现,在设计模式中这是一种典型的桥接模式,下面我们继续来看ContextImpl的startService实现:

    @Override
    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, mUser);
    }

    private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess();
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
            if (cn != null) {
                if (cn.getPackageName().equals("!")) {
                    throw new SecurityException(
                            "Not allowed to start service " + service
                            + " without permission " + cn.getClassName());
                } else if (cn.getPackageName().equals("!!")) {
                    throw new SecurityException(
                            "Unable to start service " + service
                            + ": " + cn.getClassName());
                }
            }
            return cn;
        } catch (RemoteException e) {
            return null;
        }
    }

在ContextImpl中,startService方法会调用startServiceCommon方法,而startServiceCommon方法又是通过ActivityManagerNative.getDefault().startService的对象来启动一个服务的,对于ActivityManagerNative.getDefault()这个对象,我们在Activity的工作过程中已经介绍了,通过AMS来启动一个服务的源码如下:

    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, int userId) {
        enforceNotIsolatedCaller("startService");
        // Refuse possible leaked file descriptors
        if (service != null && service.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }

        if (DEBUG_SERVICE)
            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }

在这段代码中,我们会调用mServices的startServiceLocked方法来启动,mServices对象的是ActiveServices,ActiveServices是一个辅助AMS进行Service管理的类,包含Service的启动,停止,绑定,等,在ActiveServices的startServiceLocked中,他在结尾会调用startServiceInnerLocked,startServiceInnerLocked的实现如下:

    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
            ServiceRecord r, boolean callerFg, boolean addToStarting) {
        ProcessStats.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);
        if (error != null) {
            return new ComponentName("!!", error);
        }

        if (r.startRequested && addToStarting) {
            boolean first = smap.mStartingBackground.size() == 0;
            smap.mStartingBackground.add(r);
            r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
            if (DEBUG_DELAYED_SERVICE) {
                RuntimeException here = new RuntimeException("here");
                here.fillInStackTrace();
                Slog.v(TAG, "Starting background (first=" + first + "): " + r, here);
            } else if (DEBUG_DELAYED_STARTS) {
                Slog.v(TAG, "Starting background (first=" + first + "): " + r);
            }
            if (first) {
                smap.rescheduleDelayedStarts();
            }
        } else if (callerFg) {
            smap.ensureNotStartingBackground(r);
        }

        return r.name;
    }

在上述代码中,ServiceRecord描述的是一个Service记录,ServiceRecord一直贯穿着整个Service的启动过程,startServiceInnerLocked方法并完成具体的启动工作,而是把后续的工作交给了bringUpServiceLocked方法来处理,而在bringUpServiceLocked中又调用了一个realStartServiceLocked方法,从名字含义,我们可以知道这是真正的启动一个Service:

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        if (app.thread == null) {
            throw new RemoteException();
        }
        if (DEBUG_MU)
            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
                    + ", ProcessRecord.uid = " + app.uid);
        r.app = app;
        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();

        app.services.add(r);
        bumpServiceExecutingLocked(r, execInFg, "create");
        mAm.updateLruProcessLocked(app, false, null);
        mAm.updateOomAdjLocked();

        boolean created = false;
        try {
            String nameTerm;
            int lastPeriod = r.shortName.lastIndexOf('.');
            nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
            if (LOG_SERVICE_START_STOP) {
                EventLogTags.writeAmCreateService(
                        r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
            }
            synchronized (r.stats.getBatteryStats()) {
                r.stats.startLaunchedLocked();
            }
            mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_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);
        } finally {
            if (!created) {
                app.services.remove(r);
                r.app = null;
                scheduleServiceRestartLocked(r, false);
                return;
            }
        }

        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.
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null));
        }

        sendServiceArgsLocked(r, execInFg, true);

        if (r.delayed) {
            if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (new proc): " + r);
            getServiceMap(r.userId).mDelayedStartList.remove(r);
            r.delayed = false;
        }

        if (r.delayedStop) {
            // Oh and hey we've already been asked to stop!
            r.delayedStop = false;
            if (r.startRequested) {
                if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (from start): " + r);
                stopServiceLocked(r);
            }
        }
    }

在这个方法中,我们首先需要看下app.thread.scheduleCreateService方法来创建Service并且调用onCreate,接着通过sendServiceArgsLocked方法来调用其他方法,比如onstartCommon,这两个过程都是进程间通讯,app.thread对象是IApplicationThread类型,他实际上是一个Binder,他的具体实现是在ApplicationThread和ApplicationThreadNative,所以我们只需要看ApplicationThread对Service的处理就好了,所以我们来看下scheduleCreateService这个方法,事实上,现在的源码,应该在ActivityThread中

        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;

            sendMessage(H.CREATE_SERVICE, s);
        }

可以发现,他还是通过Handler去处理,这个与我们的Activity类似,他最终是发送一个CREATE_SERVICE的what,我们来看下

    case CREATE_SERVICE:
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
         handleCreateService((CreateServiceData)msg.obj);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    break;

所以我们终究代码还是在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) 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 context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
            service.onCreate();
            mServices.put(data.token, service);
            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, 0, 0, 0);
            } catch (RemoteException e) {
                // nothing to do.
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }

handleCreateService中主要完成了下面的几件事

  • 通过类加载器创建了Service对象
  • 然后创建Application对象并调用onCreate,只会创建一次
  • 接着创建ContextImpl并且通过Service的attach方法建立两者的关系,这个过程我们在Activity中看也类似,毕竟都是一个Context
  • 最后调用Service的onCreate并且将Service独享存储到ActivityThread中的一个列表中
final ArrayMap<IBinder, Service> mServices = new ArrayMap<IBinder, Service>();

由于Service的onCreate方法被执行,这也意味着服务被启动了,紧接着会调用onstartCommon方法,这是通过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) {
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }

                QueuedWork.waitToFinish();

                try {
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, 1, data.startId, res);
                } catch (RemoteException e) {
                    // nothing to do.
                }
                ensureJitEnabled();
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to start service " + s
                            + " with " + data.args + ": " + e.toString(), e);
                }
            }
        }
    }

到这里,Service就算是启动了,但是这只是一种启动情况,我们不要忘记了,服务还可以被绑定的

二.Service的绑定过程

绑定的代码

    Intent intent = new Intent(this, TestService.class);
    bindService(intent,mServiceConnection,BIND_AUTO_CREATE);

我们观看源码可以发现

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

同样的是从ContextWrapper开始的,最终会调用ConyexyImpl的bindServiceCommon

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

那我们来看下bindServiceCommon是怎么处理的

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
            UserHandle user) {
        IServiceConnection sd;
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (mPackageInfo != null) {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
                    mMainThread.getHandler(), 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();
            int res = ActivityManagerNative.getDefault().bindService(
                mMainThread.getApplicationThread(), getActivityToken(),
                service, service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, user.getIdentifier());
            if (res < 0) {
                throw new SecurityException(
                        "Not allowed to bind to service " + service);
            }
            return res != 0;
        } catch (RemoteException e) {
            return false;
        }
    }

这里主要做了几件事,首先将ServiceCommon对象转换为ServiceDispatcher.InnerConnection对象,之所以不能直接使用ServiceCommon对象,这是因为服务的绑定有可能跨进程,所以必须借助Binder才能让远程回调自己的方法,而ServiceDispatcher.InnerConnection刚好充当了Binder的角色,那么ServiceDispatcher的作用是什么呢?,其实ServiceDispatcher起来连接ServiceConnon和InnerConnection的作用,这个过程由LoadedApk的getServiceDispatcher方法来完成:

    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
        synchronized (mServices) {
            LoadedApk.ServiceDispatcher sd = null;
            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
            if (map != null) {
                sd = map.get(c);
            }
            if (sd == null) {
                sd = new ServiceDispatcher(c, context, handler, flags);
                if (map == null) {
                    map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
                    mServices.put(context, map);
                }
                map.put(c, sd);
            } else {
                sd.validate(context, handler);
            }
            return sd.getIServiceConnection();
        }
    }

在这段代码中,mService是一个ArrayMap,他主要是存储了一个应用当前的活动的ServiceConnon和ServiceDispatcher的映射关系,如下:

    private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
        = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();

系统首先会查找是否相同的ServiceConnection,如果不存在就重新创建一个ServiceDispatcher对象并将其保存在mService中,其中映射关系的key是ServiceConnection,value是ServiceDispatcher,在ServiceDispatcher内部又保存了ServiceConnection和InnerConnection对象,当Service和客户端建立连接后,系统会通过 InnerConnection 来调用ServiceConnection中的pnServiceConnection方法,这个过程有可能是跨进程的,当ServiceDispatcher创建好以后,getServiceDispatcher会返回其保存的InnerConnection对象,

接着bindServiceCOMMON方法会通过AMS来完成Service的具体绑定过程,这对应AMS的bindService

    public int bindService(IApplicationThread caller, IBinder token,
            Intent service, String resolvedType,
            IServiceConnection connection, int flags, int userId) {
        enforceNotIsolatedCaller("bindService");

        // Refuse possible leaked file descriptors
        if (service != null && service.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }

        synchronized(this) {
            return mServices.bindServiceLocked(caller, token, service, resolvedType,
                    connection, flags, userId);
        }
    }

可以看到,AMS会调用ActiveServices的bindServiceLocked方法,然后在这内部又会继续调用bringUpServiceLocked,bringUpServiceLocked内部继续调用realStartServiceLocked方法,然后realStartServiceLocked里面执行的逻辑就和刚才启动Service的与有点类似了,通过ActivityThread来完成onCreate的创建,和启动Service不同的是,Service的绑定过程会调用app.thread的scheduleBindService方法,这个过程的实现在ActivityService的requestServiceBindingLocked方法中,我们来看下:

    private final boolean requestServiceBindingLocked(ServiceRecord r,
            IntentBindRecord i, boolean execInFg, boolean rebind) {
        if (r.app == null || r.app.thread == null) {
            // If service is not currently running, can't yet bind.
            return false;
        }
        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind");
                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
                if (!rebind) {
                    i.requested = true;
                }
                i.hasBound = true;
                i.doRebind = false;
            } catch (RemoteException e) {
                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
                return false;
            }
        }
        return true;
    }

在这段代码中,我们可以看到,他的最终实现还是在r.app.thread.scheduleBindService中,到这里你应该很清楚,肯定又用到H这个Handler类

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

果然没错,我们跟踪这个BIND_SERVICE的what可以看到他最终调用的是handleUnbindService

    private void handleUnbindService(BindServiceData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess();
                boolean doRebind = s.onUnbind(data.intent);
                try {
                    if (doRebind) {
                        ActivityManagerNative.getDefault().unbindFinished(
                                data.token, data.intent, doRebind);
                    } else {
                        ActivityManagerNative.getDefault().serviceDoneExecuting(
                                data.token, 0, 0, 0);
                    }
                } catch (RemoteException ex) {
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to unbind to service " + s
                            + " with " + data.intent + ": " + e.toString(), e);
                }
            }
        }
    }

这个方法中,会根据服务的token取出服务的对象,然后调用onBind方法,我们都知道,onBInd会返回一个Binder对象给我们,原则上说,onBind调用之后,服务处于绑定状态,但是onBInd是Service的方法,这个时候客户端并不知道已经成功连接上了,所以还需要调用客户端的ServiceCommon中的onServiceConnection,这个过程有 ActivityManagerNative.getDefault().unbindFinished来完成。

Service有一个特性,当多次绑定同一个Service的时候,Service只会执行一次,除非Service被终止,当Service的onBInder执行之后,系统需要告知客户端已经成功连接了Service,我们来看下unbindFinished实现

    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
        // Refuse possible leaked file descriptors
        if (intent != null && intent.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }

        synchronized(this) {
            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
        }
    }

这段代码说明,他最终还是给了ActiveServices的unbindFinishedLocked去处理:

    void unbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind) {
        final long origId = Binder.clearCallingIdentity();
        try {
            if (r != null) {
                Intent.FilterComparison filter
                        = new Intent.FilterComparison(intent);
                IntentBindRecord b = r.bindings.get(filter);
                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
                        + " at " + b + ": apps="
                        + (b != null ? b.apps.size() : 0));

                boolean inDestroying = mDestroyingServices.contains(r);
                if (b != null) {
                    if (b.apps.size() > 0 && !inDestroying) {
                        // Applications have already bound since the last
                        // unbind, so just rebind right here.
                        boolean inFg = false;
                        for (int i=b.apps.size()-1; i>=0; i--) {
                            ProcessRecord client = b.apps.valueAt(i).client;
                            if (client != null && client.setSchedGroup
                                    != Process.THREAD_GROUP_BG_NONINTERACTIVE) {
                                inFg = true;
                                break;
                            }
                        }
                        requestServiceBindingLocked(r, b, inFg, true);
                    } else {
                        // Note to tell the service the next time there is
                        // a new client.
                        b.doRebind = true;
                    }
                }

                serviceDoneExecutingLocked(r, inDestroying, false);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

这个类看起来挺复杂的,但是你真要理解就一句话,c.conn.connected(r.name, service);,其中c的类型是ConnectionRecord,c.conn的类型是IServiceConnection,service就是Service的onBind方法返回的Binder对象,为了分析具体的逻辑,我么来看下InnerConnection的定义:

        private static class InnerConnection extends IServiceConnection.Stub {
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

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

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

在连接的时候又调用了一次ServiceDispatcher的connected方法

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

对于Service的绑定过程来说,ServiceDisoatcher的mActivityThread是一个Handler,其实他就是ActivityThread中的H,从前面ServiceDispatcher的创建过来说,mActivityThread不会为null,这样一来,RunConnection就可以经过H的post方法而运行到主线程,所以,客户端ServiceConnection中的方法是在主线程被回调的,如下:

        private final class RunConnection implements Runnable {
            RunConnection(ComponentName name, IBinder service, int command) {
                mName = name;
                mService = service;
                mCommand = command;
            }

            public void run() {
                if (mCommand == 0) {
                    doConnected(mName, mService);
                } else if (mCommand == 1) {
                    doDeath(mName, mService);
                }
            }

            final ComponentName mName;
            final IBinder mService;
            final int mCommand;
        }

很显然这个run方法就是调用了doConnected,由于ServiceDispatcher内部保存了客户端的ServiceConnectionduixiang ,因此他可以很方便的调用ServiceConnection对象的onServiceConnected方法:

            // If there is a new service, it is now connected.
            if (service != null) {
                mConnection.onServiceConnected(name, service);
            }

到这里,这样的话,客户端的onServiceConnection方法执行后,Service的绑定过程也就到这里结束了,至于停止,解绑这类的操作。系统的执行很类似,大家可以自己先去看看。

来我的群玩玩吧

  • Android旅行的路途 484167109
  • Android进阶深度学习群 515171658(此群精品付费)

也可以关注我的微信公众号

猜你喜欢

转载自blog.csdn.net/qq_26787115/article/details/78956546
今日推荐