美文网首页
Android bindService源码解析

Android bindService源码解析

作者: Android_Jian | 来源:发表于2019-02-24 13:35 被阅读0次

    在上节课,我们从源码的角度分析了startService,今天我们继续分析下bindService,对startService这种启动方式还不熟悉的小伙伴可以先移至笔者的文章:https://www.jianshu.com/p/ad1776a4dc88

    这里先放上一张笔者绘制的流程图,大家可以先整体过一遍: bindService流程图.png

    好了,相信大家都知道,如果我们的Activity需要和Service进行通信的话,这个时候就需要采用bindService的方式,基本操作如下:

    public class MainActivity extends Activity {
    
        private ServiceConnection mConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
    
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Intent intent = new Intent(MainActivity.this, TestService.class);
            bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        }
    }
    

    我们跟进去bindService方法去看下:

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

    可以看到 ContextWrapper类的bindService方法直接调用到 mBase.bindService方法,mBase其实就是ContextImpl实例,所以我们跟进去ContextImpl的bindService方法:

        #ContextImpl
        @Override
        public boolean bindService(Intent service, ServiceConnection conn,
                int flags) {
            warnIfCallingFromSystemProcess();
            return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
                    Process.myUserHandle());
        }
    
        ---
    
       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) {
                //1.重点 将 ServiceConnection对象转换成ServiceDispatcher.InnerConnection对象
                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);
                //2.重点 IPC操作,最终调用到ActivityManagerService的bindService方法
                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();
            }
        }
    

    上述代码重点部分已经做了标注,我们首先看下 1处,1处调用到 mPackageInfo.getServiceDispatcher方法,将 ServiceConnection对象转换成ServiceDispatcher.InnerConnection对象,我们跟进去看下:

        #LoadedApk
        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) {
                    if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
                    sd = map.get(c);
                }
                if (sd == null) {
                    //1. 重点!
                    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);
                }
                //2. 获得 ServiceDispatcher.InnerConnection实例
                return sd.getIServiceConnection();
            }
        }
    

    上述方法中涉及到了 mServices,我们先来看下它的定义:

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

    mServices就是一个ArrayMap,它存储了一个应用当前活动的 ServiceConnection和 ServiceDispatcher之间的映射关系。

    可以看到在 1处创建了ServiceDispatcher对象,我们跟进去构造方法看下:

    static final class ServiceDispatcher {
    
           private final ServiceDispatcher.InnerConnection mIServiceConnection;
           private final ServiceConnection mConnection;
           private final Context mContext;
           private final Handler mActivityThread;
    
           ServiceDispatcher(ServiceConnection conn,
                    Context context, Handler activityThread, int flags) {
                mIServiceConnection = new InnerConnection(this);
                mConnection = conn;
                mContext = context;
                mActivityThread = activityThread;
                mLocation = new ServiceConnectionLeaked(null);
                mLocation.fillInStackTrace();
                mFlags = flags;
            }
    }
    

    在ServiceDispatcher的构造方法中,首先创建了InnerConnection对象,并赋值给它的成员变量mIServiceConnection,接着将ServiceConnection 对象conn赋值给成员变量mConnection ,将ActivityThread类中的Handler H mH赋值给mActivityThread 成员变量。

    我们接着跟进去 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, boolean dead)
                    throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service, dead);
                }
            }
        }
    

    InnerConnection为ServiceDispatcher中的静态内部类,继承自 IServiceConnection.Stub,很显然,它是一个binder对象。类似于ApplicationThread,InnerConnection中的方法是运行在客户端进程中的Binder线程池中的,它主要参与Service绑定后ServiceConnection 中onServiceConnected方法的回调过程。可以看到在InnerConnection的构造方法中只是对外部传入的ServiceDispatcher对象通过WeakReference做了一次封装,使得InnerConnection对象持有ServiceDispatcher对象的引用,方便后续操作。

    好了,我们回过头看下getServiceDispatcher方法的 2处,可以看到在 2处调用到ServiceDispatcher对象的getIServiceConnection()方法,我们跟进去看下:

        #ServiceDispatcher
        IServiceConnection getIServiceConnection() {
             return mIServiceConnection;
        }
    

    方法中直接将mIServiceConnection return掉,mIServiceConnection不就是我们之前在ServiceDispatcher构造方法中创建的InnerConnection 对象嘛(Binder实例),是的没错!

    我们回过头ContextImpl的bindServiceCommon方法,继续向下分析。2处为IPC操作,最终会调用到ActivityManagerService(AMS)的bindService方法,我们跟进去:

        #ActivityManagerService
        public int bindService(IApplicationThread caller, IBinder token, Intent service,
                String resolvedType, IServiceConnection connection, int flags, String callingPackage,
                int userId) throws TransactionTooLargeException {
            enforceNotIsolatedCaller("bindService");
    
            // Refuse possible leaked file descriptors
            if (service != null && service.hasFileDescriptors() == true) {
                throw new IllegalArgumentException("File descriptors passed in Intent");
            }
    
            if (callingPackage == null) {
                throw new IllegalArgumentException("callingPackage cannot be null");
            }
    
            synchronized(this) {
                //重点!
                return mServices.bindServiceLocked(caller, token, service,
                        resolvedType, connection, flags, callingPackage, userId);
            }
        }
    
        ---
    
        #ActiveServices
        int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
                String resolvedType, final IServiceConnection connection, int flags,
                String callingPackage, final int userId) throws TransactionTooLargeException {
    
            //通过applicationthread对象获得对应的ProcessRecord 
            final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
            if (callerApp == null) {
                throw new SecurityException(
                        "Unable to find app for caller " + caller
                        + " (pid=" + Binder.getCallingPid()
                        + ") when binding service " + service);
            }
    
            ...  
    
           //创建 ServiceRecord对象并关联到新创建的ServiceLookupResult对象
           ServiceLookupResult res =
                retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
                        Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
            if (res == null) {
                return 0;
            }
            if (res.record == null) {
                return -1;
            }
            //通过res.record获取到创建的ServiceRecord对象并赋值给 ServiceRecord s变量
            ServiceRecord s = res.record;
    
            ...
             
               //调用ServiceRecord 的retrieveAppBindingLocked方法,
               //内部对bindings进行put操作,标志当前为bindService
               AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
                //创建ConnectionRecord对象,将 IServiceConnection connection赋值给conn成员变量
                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();
                    //1.重点!
                    if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                            permissionsReviewRequired) != null) {
                        return 0;
                    }
                }
    

    我们跟进去ActiveServices 中的 bringUpServiceLocked方法去看下:

      private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
                boolean whileRestarting, boolean permissionsReviewRequired)
                throws TransactionTooLargeException {
    
          ...
    
          if (app != null && app.thread != null) {
                    try {
                        app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                        //1.重点
                        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.
                }
    
          ...
      }
    

    接着来到realStartServiceLocked方法:

    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();
    
            final boolean newService = app.services.add(r);
            bumpServiceExecutingLocked(r, execInFg, "create");
            mAm.updateLruProcessLocked(app, false, null);
            updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
            mAm.updateOomAdjLocked();
    
            //标记当前Service对象是否成功创建
            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);
                //1.重点 发起SystemServer进程到客户端进程的单向IPC操作,创建Service对象并调用其onCreate方法
                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);
                    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;
            }
     
            //2.若当前Service的启动方式为bindService,则执行Service的绑定操作
            requestServiceBindingsLocked(r, execInFg);
    
            updateServiceClientActivitiesLocked(app, null, true);
    
            //3.若当前Service的启动方式为startService,则新创建一个ServiceRecord.StartItem对象并添加到ServiceRecord对象 r的pendingStarts集合中
            if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
                r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                        null, null, 0));
            }
           
            //4.若当前Service的启动方式为startService,则回调当前Service对象的 onStartCommand方法
            sendServiceArgsLocked(r, execInFg, true);
    
            if (r.delayed) {
                if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
                getServiceMapLocked(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_SERVICE,
                            "Applying delayed stop (from start): " + r);
                    stopServiceLocked(r);
                }
            }
        }
    

    1处发起SystemServer进程到客户端进程的单向IPC操作,创建Service对象并调用其onCreate方法,上节课startService方式的时候我们已经分析过了,这里就不再赘述了。由于当前Service的启动方式为bindService,所以3处if条件不满足,导致ServiceRecord r的pendingStarts集合为empty,之后4处调用到sendServiceArgsLocked方法,在 sendServiceArgsLocked方法内部获取到pendingStarts.size()为0直接return掉了,至此当前Service对象的 onStartCommand方法并不会被回调。这也就解释了我们通过bindService的方式启动Service,onStartCommand方法并不会被回调的原因。好了,我们现在的重点放在 2处的 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;
                }
            }
        }
    

    这里我同样要解释一下,当我们通过bindService的方式启动Service时,会对ServiceRecord r.bindings集合进行put操作,put操作的位置我们上述代码中有提及到,不记得的小伙伴可以回过头看下。这样子就导致r.bindings.size()不为0,会调用到for循环中的 requestServiceBindingLocked方法,而当我们通过startService的方式启动Service时,r.bindings.size()为0,for循环条件不满足直接退出。这也就解释了我们通过StartService的方式启动Service时,Service的onBind方法不会回调的原因。
    好了,我们跟进去requestServiceBindingLocked方法:

    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);
    
                    //重点!该操作为SystemServer进程到客户端进程的单向IPC操作,
                    //最终会调用到ApplicationThread的scheduleBindService方法
                    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;
        }
    

    在ApplicationThread的scheduleBindService方法中发送了一条BIND_SERVICE的Message,最终会调用ActivityThread类的handleBindService方法,我们跟进去看下:

    private void handleBindService(BindServiceData data) {
            //1.获取到当前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) {
                            //2.回调当前Service对象的onBind方法
                            IBinder binder = s.onBind(data.intent);
                            //3.重点 IPC 操作,最终调用到AMS的publishService方法
                            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);
                    }
                }
            }
        }
    

    可以看到 2处回调了当前Service对象的onBind方法,接着看下3处,我们跟进去AMS的publishService方法:

        #ActivityManagerService
        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);
            }
        }
    
        ---
    
        #ActiveServices
        void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
                      try {
                              //重点!IPC操作,最终会调用到InnerConnection 对象的connected方法,该方法运行在客户端的binder线程池中
                              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);
                          }
        }
    

    我们看到在 ActiveServices的publishServiceLocked方法中发起了IPC操作,最终会调用到InnerConnection 对象的connected方法,该方法运行在客户端的binder线程池中,我们跟过去看下:

       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, boolean dead)
                    throws RemoteException {           
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    //重点 这里传过来的dead为false
                    sd.connected(name, service, dead);
                }
            }
        }
    

    可以看到在InnerConnection 对象的connected方法中调用到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);
              }
        }
    

    我们刚有讲过,在ServiceDispatcher的构造方法中,将ActivityThread类中的Handler H mH赋值给mActivityThread 成员变量,所以这里调用到mH的post方法切换到主线程,我们跟进去RunConnection对象的run方法:

          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() {
                    //这里传入的mCommand 为0,会调用doConnected方法
                    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;
            }
    

    我们接着跟进去doConnected方法看下:

          #ServiceDispatcher
          public void doConnected(ComponentName name, IBinder service, boolean dead) {
                ServiceDispatcher.ConnectionInfo old;
                ServiceDispatcher.ConnectionInfo info;
    
                synchronized (this) {
                    if (mForgotten) {
                        // We unbound before receiving the connection; ignore
                        // any connection received.
                        return;
                    }
                    old = mActiveConnections.get(name);
                    if (old != null && old.binder == service) {
                        // Huh, already have this one.  Oh well!
                        return;
                    }
    
                    if (service != null) {
                        // A new service is being connected... set it all up.
                        info = new ConnectionInfo();
                        info.binder = service;
                        info.deathMonitor = new DeathMonitor(name, service);
                        try {
                            service.linkToDeath(info.deathMonitor, 0);
                            mActiveConnections.put(name, info);
                        } catch (RemoteException e) {
                            // This service was dead before we got it...  just
                            // don't do anything with it.
                            mActiveConnections.remove(name);
                            return;
                        }
    
                    } else {
                        // The named service is being disconnected... clean up.
                        mActiveConnections.remove(name);
                    }
    
                    if (old != null) {
                        old.binder.unlinkToDeath(old.deathMonitor, 0);
                    }
                }
    
                // 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);
                }
            }
    

    可以看到在doConnected方法的最后调用到了ServiceConnection的onServiceConnected方法。

    至此,Service的启动方式之bindService方式的源码分析就结束了。

    相关文章

      网友评论

          本文标题:Android bindService源码解析

          本文链接:https://www.haomeiwen.com/subject/bqyvyqtx.html