Android源码之Service启动流程

版权声明:未经本人允许,严禁转载 https://blog.csdn.net/lmh_19941113/article/details/85403030

 Service在开发中使用得或许没有activity那么频繁,但它是Android四大组件之一,在Android中也是十分重要的,前面分析了activity的启动流程,这里也来分析一下Service是如何启动的。
 Service分为两种工作状态,一种是启动状态,主要用于执行后台计算;另外一种是绑定状态,主要用于其他组件与Service的交互。需要注意的是,Service的两种状态是可以共存的,即Service既可以处于启动状态也可以同时处于绑定状态。通过Context的startService即可启动Service。

        Intent intent = new Intent(this, MyService.class);
        startService(intent);

 通过Context的bindService方法即可以绑定的方式启动一个Service。

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

1、Service的启动过程

 startService方法存在于ContextWrapper中,具体实现如下

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

 这里调用了mBase的startService方法,那mBase是什么尼?其实mBase的类型是ContextImpl,在activity的attach方法中会将一个ContextImpl对象传给mBase。那就来ContextImpl中看startService的实现。

    public ComponentName startService(Intent service) {
        ...
        return startServiceCommon(service, false, mUser);
    }
    private ComponentName startServiceCommon(Intent service, boolean requireForeground,
            UserHandle user) {
        try {
            ...
            ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), requireForeground,
                            getOpPackageName(), user.getIdentifier());
            ...
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

 startService中调用了startServiceCommon这个方法,在startServiceCommon里则通过Binder机制调用AMS中的startService方法。

    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage, int userId)
            throws TransactionTooLargeException {
        ...
        //分段锁
        synchronized(this) {
            ...
            try {
                res = mServices.startServiceLocked(caller, service,
                        resolvedType, callingPid, callingUid,
                        requireForeground, callingPackage, userId);
            } finally {
                ...
            }
            return res;
        }
    }

 startService这个方法很简单,直接调用了ActiveServices的startServiceLocked方法。

   ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
           int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
           throws TransactionTooLargeException {
       ...
       ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
       return cmp;
   }
   ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
           boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
       ...
       String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
       ...
       return r.name;
   }

 startServiceLocked最后会调用startServiceInnerLocked这个方法,这个也比较简单,直接调用了bringUpServiceLocked,这个方法就比较重要了,Service的创建就在这里面实现的。

    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
        ...
        //如果该Service已经启动则直接调用Service的onStartCommand方法
        if (r.app != null && r.app.thread != null) {
            //这个很重要,具体就是调用Service的onStartCommand方法
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }
        ...
        if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
            ...
            if (app != null && app.thread != null) {
                try {
                    ...
                    //创建Service
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } catch (TransactionTooLargeException e) {
                    ...
                } catch (RemoteException e) {
                    ...
                }
            }
        } else {
            ...
        }

        //如果需要开启进程,就先开启进程
        if (app == null && !permissionsReviewRequired) {
            //开启新的进程
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingType, r.name, false, isolated, false)) == null) {
                ....
                //进程创建失败做的清除操作,如解绑Service、停止Service
                bringDownServiceLocked(r);
                return msg;
            }
            ...
        }
        ...
        return null;
    }

 bringUpServiceLocked中有四个方法非常重要,理解了这四个方法的实现就基本上理解了Service的启动流程。

  • sendServiceArgsLocked:会调用Service的onStartCommand方法,当Service已经存在时则直接调用onStartCommand,不再重新创建Service
  • realStartServiceLocked:创建一个Service
  • startProcessLocked:开启一个新的进程。
  • bringDownServiceLocked:主要是做解绑Service、停止Service的操作

 先来看sendServiceArgsLocked的实现。

    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {
        //当bindService时,N==0,所以bindService就不会调用onStartCommand
        ////直接采用绑定方式创建服务时这个是没有的,start流程中才有添加过程
        final int N = r.pendingStarts.size();
        if (N == 0) {
            return;
        }
        ...
        try {
            r.app.thread.scheduleServiceArgs(r, slice);
        } catch (TransactionTooLargeException e) {
            ...
        } catch (RemoteException e) {
            ...
        } catch (Exception e) {
            ...
        }
        ...
    }

 该方法还是比较简单的,直接调用了ApplicationThread的scheduleServiceArgs方法,然后通过系统Handler来调用ActivityThread的handleServiceArgs方法。

    private void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                ...
                int res;
                if (!data.taskRemoved) {
                    //调用了Service的onStartCommand的方法
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
                    ...
                }
                ...
            } catch (Exception e) {
                ...
            }
        }
    }

 在handleServiceArgs方法中就会调用Service的onStartCommand方法,onStartCommand方法想必都很熟悉吧。再回到ActiveServices的bringUpServiceLocked方法中,现在再来看realStartServiceLocked这个方法。

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        ...
        try {
            ...
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
            ...
        } finally {
            //如果Service未创建成功,则清除
            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);
                }
            }
        }
        ...
        //调用Service的onBind方法,后面梳理绑定Service时在详细讲解
        requestServiceBindingsLocked(r, execInFg);
        ...
        //这个方法前面就讲解了,主要是调用Service的onStartCommand方法
        sendServiceArgsLocked(r, execInFg, true);
        ...
    }

 realStartServiceLocked中首先调用了ApplicationThread的scheduleCreateService方法,scheduleCreateService中通过系统Handler来调用ActivityThread的handleCreateService方法。

    private void handleCreateService(CreateServiceData data) {
        ...
        try {
            //拿到ClassLoader
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            //通过反射创建Service
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            ...
        }

        try {
            ...
            //创建一个Service对应的ContextImpl 
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            //调用Service的attach方法,主要是初始化一些参数
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            //调用Service的onCreate方法,这个想必都很熟悉了
            service.onCreate();
            ...
        } catch (Exception e) {
            ...
        }
    }

 handleCreateService方法还是比较简单的,该方法通过反射创建了Service并调用Service的onCreate方法。再回到ActiveServices的bringUpServiceLocked中,现在再来看startProcessLocked这个方法。这个方法在Android源码分析之Activity启动流程这篇文章中有解介绍,这里就不在详细介绍了,只要知道它会创建一个新的进程,然后调用ActivityThread的main方法即可。接着调用attach方法,并最终调用AMS中的attachApplicationLocked方法。

    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

        ...
        // Find any services that should be running in this process...
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
                ...
            } catch (Exception e) {
                ...
            }
        }
        ...
        return true;
    }

 在该方法中调用了AMS的attachApplicationLocked方法,这个方法比较简单。

    boolean attachApplicationLocked(ProcessRecord proc, String processName)
            throws RemoteException {
        boolean didSomething = false;
        // Collect any services that are waiting for this process to come up.
        if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
            try {
                for (int i=0; i<mPendingServices.size(); i++) {
                    sr = mPendingServices.get(i);
                    ...
                    //创建Service
                    realStartServiceLocked(sr, proc, sr.createdFromFg);
                    didSomething = true;
                    if (!isServiceNeededLocked(sr, false, false)) {
                        // We were waiting for this service to start, but it is actually no
                        // longer needed.  This could happen because bringDownServiceIfNeeded
                        // won't bring down a service that is pending...  so now the pending
                        // is done, so let's drop it.
                        bringDownServiceLocked(sr);
                    }
                }
            } catch (RemoteException e) {
                ...
            }
        }
        ...
        return didSomething;
    }

 上面的realStartServiceLocked方法是不是很熟悉啊,前面刚介绍完毕,这里就不再继续介绍。再回到ActiveServices的bringUpServiceLocked中,现在再来看bringDownServiceLocked这个方法。

    private final void bringDownServiceLocked(ServiceRecord r) {
        
        // Report to all of the connections that the service is no longer
        // available.
        for (int conni=r.connections.size()-1; conni>=0; conni--) {
            ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
            for (int i=0; i<c.size(); i++) {
                ConnectionRecord cr = c.get(i);
                //仍然存在与正在关闭的服务的连接。 把它标记为已死。
                cr.serviceDead = true;
                try {
                    cr.conn.connected(r.name, null, true);
                } catch (Exception e) {
                    ...
                }
            }
        }

        //与Service解除绑定
        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 (ibr.hasBound) {
                    try {
                        ...
                        //调用Service的onUnbind方法
                        r.app.thread.scheduleUnbindService(r,
                                ibr.intent.getIntent());
                    } catch (Exception e) {
                        serviceProcessGoneLocked(r);
                    }
                }
            }
        }

        //检查Service是否在前台运行
        if (r.fgRequired) {
            ...
            r.fgRequired = false;
            r.fgWaiting = false;
            mAm.mHandler.removeMessages(
                    ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
            if (r.app != null) {
                Message msg = mAm.mHandler.obtainMessage(
                        ActivityManagerService.SERVICE_FOREGROUND_CRASH_MSG);
                msg.obj = r.app;
                mAm.mHandler.sendMessage(msg);
            }
        }
        ...
        //请注意,当通过bringUpServiceLocked()调用此方法时,则表示找不到该服务
        if (found != null && found != r) {
            // This is not actually the service we think is running...  this should not happen,
            // but if it does, fail hard.
            smap.mServicesByName.put(r.name, found);
            throw new IllegalStateException("Bringing down " + r + " but actually running "
                    + found);
        }
       
        ...
        //开始清除Service的相关信息
        cancelForegroundNotificationLocked(r);
        if (r.isForeground) {
            decActiveForegroundAppLocked(smap, r);
        }
        r.isForeground = false;
        r.foregroundId = 0;
        r.foregroundNoti = null;
        r.clearDeliveredStartsLocked();
        r.pendingStarts.clear();

        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);
                    //销毁Service并调用Service的onDestory方法
                    r.app.thread.scheduleStopService(r);
                } catch (Exception e) {
                    ...
                    serviceProcessGoneLocked(r);
                }
            } else {
                ...
            }
        } else {
            ...
        }
        //后面就是将一些信息置为null,方便回收
        if (r.bindings.size() > 0) {
            r.bindings.clear();
        }

        if (r.restarter instanceof ServiceRestarter) {
           ((ServiceRestarter)r.restarter).setService(null);
        }

        int memFactor = mAm.mProcessStats.getMemFactorLocked();
        long now = SystemClock.uptimeMillis();
        if (r.tracker != null) {
            r.tracker.setStarted(false, memFactor, now);
            r.tracker.setBound(false, memFactor, now);
            if (r.executeNesting == 0) {
                r.tracker.clearCurrentOwner(r, false);
                r.tracker = null;
            }
        }

        smap.ensureNotStartingBackgroundLocked(r);
    }

 从上面看出bringDownServiceLocked主要就是销毁、解绑Service。关于启动Service的启动流程就梳理完毕了。

2、Service的绑定过程

 bindService方法也存在于ContextWrapper中,具体实现如下

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

 这里调用了mBase的bindService方法,前面说了mBase代表一个ContextImpl对象,那么就来ContextImpl中看bindService的实现。

    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        ...
        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 (mPackageInfo != null) {
            //将ServiceConnection 进行了转换,因为IServiceConnection 能够进程间通信
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
        } else {
            throw new RuntimeException("Not supported in system context");
        }
        validateServiceIntent(service);
        try {
            ...
            //调用AMS的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();
        }
    }

 在bindService中调用了bindServiceCommon这个方法,在该方法中首先将ServiceConnection对象转化为ServiceDispatcher.InnerConnection对象。之所以不能直接使用ServiceConnection对象,这是因为服务的绑定可能是跨进程的,因此ServiceConnection必须借助于Binder才能让远程服务端回调自己的方法,而ServiceDispatcher的内部类InnerConnection刚好充当起Binder这个角色。

    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<>();
                    mServices.put(context, map);
                }
                map.put(c, sd);
            } else {
                sd.validate(context, handler);
            }
            return sd.getIServiceConnection();
        }
    }

 转换成功后就调用AMS中的bindService方法。

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

 然后调用ActiveService的bindServiceLocked方法。

    int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String callingPackage, final int userId) throws TransactionTooLargeException {
        ...
        
        //判断是否进行权限检查
        if (mAm.mPermissionReviewRequired) {
            //进行权限检查
            if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                    s.packageName, s.userId)) {

                ...
                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 {
                                        //创建Service
                                        bringUpServiceLocked(serviceRecord,
                                                serviceIntent.getFlags(),
                                                callerFg, false, false);
                                    } catch (RemoteException e) {
                                        /* ignore - local call */
                                    }
                                } else {
                                    unbindServiceLocked(connection);
                                }
                            } finally {
                                Binder.restoreCallingIdentity(identity);
                            }
                        }
                    }
                });
                ...
            }
        }

        final long origId = Binder.clearCallingIdentity();

        try {
            ...
            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
                s.lastActivity = SystemClock.uptimeMillis();
                //创建Service
                if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                        permissionsReviewRequired) != null) {
                    return 0;
                }
            }

            if (s.app != null) {
                ...
            }
            if (s.app != null && b.intent.received) {
                //如果Service已经在运行,直接调用ServiceConnection中的onServiceConnected
                try {
                    c.conn.connected(s.name, b.intent.binder, false);
                } catch (Exception 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);
            }

            ...
        } finally {
            Binder.restoreCallingIdentity(origId);
        }

        return 1;
    }

 从上面看出bindServiceLocked里最终都是调用的bringUpServiceLocked方法。关于bringUpServiceLocked在前面已经讲解过,就不在叙述了。记得在realStartServiceLocked中的requestServiceBindingsLocked这个方法没有讲解,那是为什么尼?因为这个只有在Service绑定过程中才会用到。所以先来看看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;
            }
        }
    }
    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
        ...
        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                ...
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
                ...
            } catch (TransactionTooLargeException e) {
                ...
            } catch (RemoteException e) {
                ...
            }
        }
        return true;
    }

 requestServiceBindingsLocked比较简单,直接调用了requestServiceBindingLocked这个方法,在requestServiceBindingLocked中调用了ApplicationThread的scheduleBindService方法,再通过系统Handler调用ActivityThread的handleBindServic方法。

    private void handleBindService(BindServiceData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                ...
                try {
                    if (!data.rebind) {
                        IBinder binder = s.onBind(data.intent);
                        //调用ServiceConnection中的onServiceConnected                    
                        ActivityManager.getService().publishService(
                                data.token, data.intent, binder);
                    } else {
                        s.onRebind(data.intent);
                        ActivityManager.getService().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
                    ...
                } catch (RemoteException ex) {
                    ...
                }
            } catch (Exception e) {
                ...
                }
            }
        }
    }

 在上面代码就调用了Service的onBind方法,这个也是不是很熟悉啊。原则上来说,Service的onBind方法调用后,Service就处于绑定状态了,但是onBind方法还是Service的方法,这个时候客户端并不知道已经成功连接Service了,所以还必须调用客户端的ServiceConnection中的onServiceConnected,这个过程就是通过AMS中的publishService来完成的。

    public void publishService(IBinder token, Intent intent, IBinder service) {
        ...
        synchronized(this) {
            ...
            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
        }
    }

 publishService中调用了ActiveService的publishServiceLocked方法。

    void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
        final long origId = Binder.clearCallingIdentity();
        try {
            if (r != null) {
                ...
                if (b != null && !b.received) {
                    ...
                    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) {
                                ...
                            }
                        }
                    }
                }
                ...
            }
        } finally {
            ...
        }
    }

 其实publishServiceLocked的核心代码就是c.conn.connected(r.name, service, false);其中c的类型是ConnectionRecord,c.conn的类型是ServiceDispatcher.InnerConnection,这个类型是不是很熟悉啊,因为前面就是将ServiceConnection转换成ServiceDispatcher.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);
            }
        }
    }

 ServiceDispatcher.InnerConnection的connected方法很简单,就是调用了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);
        }
    }
    private final class RunConnection implements Runnable {
        ...
        public void run() {
            if (mCommand == 0) {
                doConnected(mName, mService, mDead);
            } else if (mCommand == 1) {
                doDeath(mName, mService);
            }
        }
        ...
    }

 其实在RunConnection中也是调用的doConnected方法,所以来看一下doConnected的实现。

    public void doConnected(ComponentName name, IBinder service, boolean dead) {
   
        // 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);
        }
    }

 上面的mConnection.onServiceDisconnected(name);mConnection.onBindingDied(name);mConnection.onServiceConnected(name, service);是不是很熟悉啊。到此,Service的绑定流程也就介绍完毕了。
 从总体上来说Service的启动流程及绑定流程是不是比Activity要简单很多啊,但也有不少东西尼,至于Service的停止及解绑过程就不在介绍了。跟启动流程类似的。

猜你喜欢

转载自blog.csdn.net/lmh_19941113/article/details/85403030