原创

Android10.0 Service绑定源码解析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://menxindiaolong.blog.csdn.net/article/details/103095545

本文出自门心叼龙的博客,属于原创类容,转载请注明出处。


我们知道Service有两种启动模式一种是startService,另一种是bindService,通过startService方式启动后,Activity和Service就没有任何关系了,当Activity销毁了,Service可以在后台依然存活,而通过bindService方式启动后,Activity和Service的生命周期就捆绑在了一起,当Activity销毁了Service也就销毁了,这两种用法各有自己的应用场景。

Service的基本使用

上一篇我们学习了Android10.0的Service的第一种启动模式即通过startService启动Service的流程,今天我们继续对Service的第二种启动模式bindService流程进行研究,下面我们简单的回顾一下bindService的使用方式,
首先我们创建一个服务接口IMyServcie,如下所示:

public interface IMyService {
    void test();
}

很简单,接口中就一个方法test,接下来我们定义一个服务TestService来实现这个接口,如下所示:

public class TestService extends Service implements IMyService{
    MyService binder;

    @Override
    public void onCreate() {
        Log.v("MYTAG", "onCreate start...");
        binder = new MyService();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.v("MYTAG", "onStartCommand start...");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.v("MYTAG", "onBind start...");
        return binder;
    }

    @Override
    public void test() {
        Log.v("MYTAG", "hello world...");
    }
	//注释1
    class MyService extends Binder implements IMyService {
        @Override
        public void test() {
            TestService.this.test();
        }
    }
}

在上面代码,首先TestService继承了Servcie并实现IMyService接口,接着在注释1处创建了一个内部类MyService,MyServcie继承了Binder并实现了接口IMyService,在onCreate方法中创建了一个MyService并把它赋值给binder,并在onBind方法中返回了该binder对象,接下来我们需要在AndroidManifest.xml中注册服务,如下所示:

<application>
    <service android:name=".service.TestService" />
</application>

这样服务端的工作就完成了,接下来我们看客户端怎么使用它,如下所示:

private IMyService mMyService;
private void bindService() {
        bindService(new Intent(TestServiceActivity.this, TestService.class), new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.v("MYTAG", "onServiceConnected start...");
                mMyService = (IMyService) service;
                mMyService.test();
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        }, Context.BIND_AUTO_CREATE);
    }

通过Activity的bindService方法我们绑定了一个服务,该方法共有三个参数,我们主要看他的第二个参数ServiceConnection这是一个匿名对象参数,服务绑定成功后会调用他的onServiceConnected方法,该方法的第二个参数service就是TestService的onBind方法所返回的那个binder,拿到了服务端的binder就可以调用服务端的方法了,首先我们看一下调用startService各个方法的回调过程,如下所示:
在这里插入图片描述
如果继续startService,那么onStartCommand方法会继续执行。接下来我们看bindService的时候,各个方法的回调情况,如下:
在这里插入图片描述
如果继续bindServcie绑定的是同一个ServiceConnection,onCreate,onBind,onServiceConnected都不会回调,这也不难理解,因为都绑定过了,如果再次bindServcie绑定的是一个新的ServiceConnection,onCreate,onBind这两个方法不会回调,onServiceConnected会回调,这时候就形成了多个ServiceConnection对应一个Servcie的多对一的情形。

以上就是我们在日常开发过程中,关于Servcie的一些最基本的用法,通过打log我们也看到了,bindService的时候服务端的Service的onCreate方法先调用,紧着调用onBind方法,最后调用了onServiceConnected方法,接下来我们通过查看源码来探索onCreate,onBind,onServiceConnected这三个方法都是在什么时候调用的,通过下面的学习这些疑问将逐一破解。

Service的绑定过程

绑定一个Service首先是从ContextWraper的bindService方法开始,如下所示:

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

这个方法很干净,只有一行代码调用了mBase的bindService方法,mBase就是ContextImpl,mBase是什么在上篇文章有过详细的介绍,在这里就不多说了,我们直接进入ContextImpl的bindServcie方法,如下所示:

@Override
    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
                getUser());
    }

在bindService方法内部又调用了ContextImple的bindServiceCommon方法,这个方法具体实现如下:

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
            String instanceName, Handler handler, Executor executor, UserHandle user) {
        // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
        IServiceConnection sd;
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (handler != null && executor != null) {
            throw new IllegalArgumentException("Handler and Executor both supplied");
        }
        if (mPackageInfo != null) {
            if (executor != null) {
                sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
            } else {
            	//注释1
                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
            int res = ActivityManager.getService().bindIsolatedService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
            if (res < 0) {
                throw new SecurityException(
                        "Not allowed to bind to service " + service);
            }
            return res != 0;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

在bindServiceCommon方法中,看注释1处把传递过来的ServiceConnection通过mPackageInfo的getServiceDispatcher进行处理返回了一个IServiceConnection类型的对象,最后把这个IServiceConnection交给了注释2处ActivityManager.getService()对象的bindIsolatedService方法。IServiceConnection到底是个什么鬼?mPackageInfo就是LoadedApk,我们看LoadedApk的getServiceDispatcher方法实现:

@UnsupportedAppUsage
    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
        return getServiceDispatcherCommon(c, context, handler, null, flags);
    }
    private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
            Context context, Handler handler, Executor executor, int flags) {
        synchronized (mServices) {
            LoadedApk.ServiceDispatcher sd = null;
            //注释1
            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) {
                if (executor != null) {
                    sd = new ServiceDispatcher(c, context, executor, flags);
                } else {
                	//注释2
                    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, executor);
            }
            return sd.getIServiceConnection();
        }
    }

从上面的代码我们可以看到getServiceDispatcher内部又会调用getServiceDispatcherCommon方法,首先看注释1处取出当前Service的所有的连接的集合,然后再找到每一个ServcieConnection所对应的ServiceDispatcher,最后返回它的IServiceConnection,如果没有就会执行注释2处实例化一个ServiceDispatcher,最后它缓存到map当中,然后返回ServiceDispatcher的IServiceConnection,现在我们看看注释2处ServiceDispatcher的构造方法的具体实现:

 ServiceDispatcher(ServiceConnection conn,
                Context context, Handler activityThread, int flags) {
            //注释1
            mIServiceConnection = new InnerConnection(this);
            mConnection = conn;
            mContext = context;
            mActivityThread = activityThread;
            mActivityExecutor = null;
            mLocation = new ServiceConnectionLeaked(null);
            mLocation.fillInStackTrace();
            mFlags = flags;
        }

在注释1处终于找到了IServiceConnection的实现,其实他就是一个InnerConnection,我们看他的具体实现:

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

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

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

通过继承关系我们发现IServiceConnection就是一个binder,而且他还持有了ServiceDispatcher,通过这几段代码其实就做了一件事将ServiceConnection转化了一个InnerConnection,ServiceDispatcher同时持有了InnerConnection和和ServiceConnection引用,InnerConnection反向还持有了ServiceDispatcher的引用。他们之前是一种相关持有的关系。

现在回过头我们看ContetImple的bindServiceCommon方法的注释2处的

int res = ActivityManager.getService().bindIsolatedService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, instanceName, getOpPackageName(), user.getIdentifier());

这段代码,ActivityManager.getService()已经在上篇文章讲过了,它就是ActivityManagerService,随后ActivityManagerService调用了bindIsolatedService方法,它有一个参数sd,sd就是我们上面花了很大力气找到的InnerConnection,它是一个binder,bindIsolatedService方法调用后,程序就由客户端切换到了服务端。

ActivityManagerService中的流程

接下来我们来看ActivityManagerService的bindIsolatedService方法的具体实现,如下所示:

public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags, String instanceName,
            String callingPackage, int userId) throws TransactionTooLargeException {
        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");
        }

        // Ensure that instanceName, which is caller provided, does not contain
        // unusual characters.
        if (instanceName != null) {
            for (int i = 0; i < instanceName.length(); ++i) {
                char c = instanceName.charAt(i);
                if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
                            || (c >= '0' && c <= '9') || c == '_' || c == '.')) {
                    throw new IllegalArgumentException("Illegal instanceName");
                }
            }
        }

        synchronized(this) {  
            //注释1
            return mServices.bindServiceLocked(caller, token, service,
                    resolvedType, connection, flags, instanceName, callingPackage, userId);
        }
    }

在bindIsolatedService方法的最后的注释1处把绑定的任务交给了ActiveServices的bindServiceLocked方法。

ActiveServices中的流程

ActiveServices的bindServiceLocked具体实现如下所示:

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String instanceName, String callingPackage, final int userId)
            throws TransactionTooLargeException {
			...           
            if ((flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
                s.setHasBindingWhitelistingBgActivityStarts(true);
            }
            if (s.app != null) {
                updateServiceClientActivitiesLocked(s.app, c, true);
            }
            ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
            if (clist == null) {
                clist = new ArrayList<>();
                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;
                }
            }

            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,
                        (callerApp.hasActivitiesOrRecentTasks() && s.app.hasClientActivities())
                                || (callerApp.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP
                                        && (flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0),
                        b.client);
                mAm.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE);
            }

            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.shortInstanceName
                            + " 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) {
            	//注释2
                requestServiceBindingLocked(s, b.intent, callerFg, false);
            }
            getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);

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

这个方法是比较长的,接下来会调用注释1处的bringUpServiceLocked,bringUpServiceLocked方法又会调用realStartServiceLocked,在realStartServiceLocked方法中又会调用app.thread.scheduleCreateService,紧接着Service就创建了,Service的onCreate方法就会被调用,这个流程是不是很熟悉,其实这这就是上一篇文章我们讲到的service启动流程,所以这块我们就不在贴代码分析了,接下来我们继续看注释2的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);
                //注释1
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.getReportedProcState());
                if (!rebind) {
                    i.requested = true;
                }
                i.hasBound = true;
                i.doRebind = false;
            } catch (TransactionTooLargeException e) {
                // 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;
    }

requestServiceBindingLocked方法的注释1处会调用r.app.thread对象的scheduleBindService方法,r.app.thread就是ActivityThraed的内部类对象ApplicationThread,至此流程就由服务端切换到客户端了。

ActivityThread中的流程

接下来ApplicationThread的scheduleBindService方法会发送一个BIND_SERVICE类型的消息,紧接着在ActivityThread的消息处理器的H会收到消息,此时就进入了handleBindService方法,该方法的实现如下:

private void handleBindService(BindServiceData data) {
        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) {
                    	//注释1
                        IBinder binder = s.onBind(data.intent);
                        //注释2
                        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) {
                    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);
                }
            }
        }
    }

handleBindService方法的注释1处Service的onBind方法调用了,注释2处调用了ActivityManagerService的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);
        }
    }

publishService方法的最后一行会调用ActiveServices的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;
                    ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
                    for (int conni = connections.size() - 1; conni >= 0; conni--) {
                        ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
                        for (int i=0; i<clist.size(); i++) {
                            ConnectionRecord c = clist.get(i);
                            if (!filter.equals(c.binding.intent.intent)) {
                                if (DEBUG_SERVICE) Slog.v(
                                        TAG_SERVICE, "Not publishing to: " + c);
                                if (DEBUG_SERVICE) Slog.v(
                                        TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
                                if (DEBUG_SERVICE) Slog.v(
                                        TAG_SERVICE, "Published intent: " + intent);
                                continue;
                            }
                            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
                            try {
                            	//注释1
                                c.conn.connected(r.name, service, false);
                            } catch (Exception e) {
                                Slog.w(TAG, "Failure sending service " + r.shortInstanceName
                                      + " to connection " + c.conn.asBinder()
                                      + " (in " + c.binding.client.processName + ")", e);
                            }
                        }
                    }
                }
                serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

我们直接看注释1处调用了c.conn对象的connected方法,c就是ConnectionRecord对象我们看他的构造方法:

ConnectionRecord(AppBindRecord _binding,
            ActivityServiceConnectionsHolder<ConnectionRecord> _activity,
            IServiceConnection _conn, int _flags,
            int _clientLabel, PendingIntent _clientIntent,
            int _clientUid, String _clientProcessName, String _clientPackageName) {
        binding = _binding;
        activity = _activity;
        //注释1
        conn = _conn;
        flags = _flags;
        clientLabel = _clientLabel;
        clientIntent = _clientIntent;
        clientUid = _clientUid;
        clientProcessName = _clientProcessName;
        clientPackageName = _clientPackageName;
    }

我们直接看注释1处的conn的赋值我们知道它就是IServiceConnection类型的,而c.conn它的具体实现就是在前面的ContextImpl.bindServiceCommon方法中我们花了大量时间所讲到的InnerConnection,我们直接看InnerConnection的connected方法实现:

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

紧接着会在注释1处调用ServiceDispatcher的connected方法,该方法的具体实现如下:

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

在connected方法中注释1处会给ActivityThead的消息处理H发送了一个带回调类型为RunConnection的消息,最终会执行它的run方法,我们该方法的具体实现:

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

RunConnection的run方法在注释1会调用ServiceDispatcher的doConnected方法,该方法如下所示:

 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 viable service, it is now connected.
            if (service != null) {
            	//注释1
                mConnection.onServiceConnected(name, service);
            } else {
                // The binding machinery worked, but the remote returned null from onBind().
                mConnection.onNullBinding(name);
            }
        }

在doConnected方法的注释1处最终会执行ServiceConnection的onServiceConnected方法。好了截止目前Service的onCreate,onBind方法都回调了,ServiceConnection的onServiceConnected也执行了,至此Service绑定的流程我们就讲完了,最后我画了一张流程来帮助大家进行理解。

总结

在这里插入图片描述
Activity.bindService
ContextWraper.bindService
ContextImpl.bindService
ContextImpl.bindServiceCommon
ActivityManagerService.bindIsolatedService
ActiveServices.bindServiceLocked
ActiveService.bringUpServiceLocked
ActiveService.realStartServiceLocked
ApplicationThread.scheduleCreateService
ActivityThread.handleCreateService
Service.onCreate

ActiveService.requestServiceBindingLocked
ApplicationThread.scheduleBindService
ActivityThread.handleBindService
Service.onBind

ActivityManagerService.publishService
ActiveService.publishServiceLocked
InnerConnection.connected
ServiceDispatcher.connected
RunConnection.run
ServiceDispatcher.doConnected
ServiceConnection.onServiceConnected

问题反馈

在使用学习中有任何问题,请留言,或加入Android、Java开发技术交流群

  • QQ群:810970432
  • email:geduo_83@163.com
文章最后发布于: 2019-11-16 16:20:04
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览