基于Android10.0 bindService流程

前言

本文基于Android10.0源码,从client端调用bindService()方法开始,一步步跟进源码,看看源码中是如何调用到service端代码,执行service生命周期方法,并回调client端ServiceConnection中onServiceConnected()回调方法的。示例代码请参考AIDL实现两app间通信

代码分析

从client端调用bindService()方法开始,第一个参数传入Intent,第二个参数传入创建的ServiceConnection,其中包括两个回调函数。bindService()是在ContextWrapper类中实现的。

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

mBase是ContextImpl类型对象,调用ContextImpl的bindService()方法。

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

注意一下第5个参数,传入了主线程的handler,对应着client端的主线程handler,后面会用到它。
调用bindServiceCommon()方法。

ContextImpl.java
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;
	...
    //1
    if (mPackageInfo != null) {
        if (executor != null) {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
        } else {
            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) {
			...
		}
		return res != 0;
	} catch (RemoteException e) {
		throw e.rethrowFromSystemServer();
	}
}

将这个方法分为两部分来看,一部分是注释1处创建sd对象,第二部是注释2处调用bindIsolatedService()方法与系统进程交互。先来看sd是如何被赋值的。在注释1处,这里mPackageInfo不为1,并且executor传入的为null,所以执行else分支调用mPackageInfo的getServiceDispatcher()方法得到一个sd对象,其中第一个参数conn为我们在客户端创建的ServiceConnection,第三个参数handler为前文提到的客户端app主线程的handler。mPackageInfo是LoadedApk类型对象。

LoadedApk.java
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
        Context context, Handler handler, int flags) {
    return getServiceDispatcherCommon(c, context, handler, null, flags);
}

调用getServiceDispatcherCommon()方法。

LoadedApk.java
private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
        Context context, Handler handler, Executor executor, 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) {
            if (executor != null) {
                sd = new ServiceDispatcher(c, context, executor, flags);
            } else {
                //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, executor);
        }
        return sd.getIServiceConnection();
    }
}

executor为空,执行注释2所在的else分支,创建一个ServiceDispatcher实例。

LoadedApk.java
static final class ServiceDispatcher {
    private final ServiceDispatcher.InnerConnection mIServiceConnection;
    @UnsupportedAppUsage
    private final ServiceConnection mConnection;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final Context mContext;
    private final Handler mActivityThread;
    private final Executor mActivityExecutor;
    private final ServiceConnectionLeaked mLocation;
    private final int mFlags;

    ...

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

    private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
        = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();

    //ServiceDispatcher构造方法
    @UnsupportedAppUsage
    ServiceDispatcher(ServiceConnection conn,
            Context context, Handler activityThread, int flags) {
        //创建一个InnerConnection对象,是一个IBinder
        mIServiceConnection = new InnerConnection(this);
        mConnection = conn;
        mContext = context;
        mActivityThread = activityThread;
        mActivityExecutor = null;
        mLocation = new ServiceConnectionLeaked(null);
        mLocation.fillInStackTrace();
        mFlags = flags;
    }

    ...

}

将客户端conn赋值给mConnection,主线程handler赋值给mActivityThread,并实例化了内部类InnerConnection赋值给mIServiceConnection,内部类InnerConnection继承了IServiceConnection.Stub,并实现了IServiceConnection中的connected()接口。接着看getServiceDispatcherCommon()方法,最后调用了sd.getIServiceConnection()方法。

LoadedApk.java
IServiceConnection getIServiceConnection() {
    return mIServiceConnection;
}

返回了创建的InnerConnection对象。
回到bindServiceCommon()方法,接着会调用bindIsolatedService()方法,这个最终会调用到ActivityManagerService的bindIsolatedService方法。

ActivityManagerService.java
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
	...

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

首先做了一下参数检查,代码省略了,主要调用了bindServiceLocked()方法。mServices是ActiveServices类型对象。

ActiveServices.java
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
		String resolvedType, final IServiceConnection connection, int flags,
		String instanceName, String callingPackage, final int userId)
		throws TransactionTooLargeException {

	...
	ServiceRecord s = res.record;

	boolean permissionsReviewRequired = false;

	...

	try {
		...
        //1记录需要bind的service
		AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
        //2
        ConnectionRecord c = new ConnectionRecord(b, activity,
                connection, flags, clientLabel, clientIntent,
                callerApp.uid, callerApp.processName, callingPackage);

        IBinder binder = connection.asBinder();
        s.addConnection(binder, c);
        b.connections.add(c);
		...

		if ((flags&Context.BIND_AUTO_CREATE) != 0) {
			s.lastActivity = SystemClock.uptimeMillis();
			//调用bringUpServiceLocked()方法
			if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
					permissionsReviewRequired) != null) {
				return 0;
			}
		}

		...

		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) {
				...
			}

			// 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()方法
			requestServiceBindingLocked(s, b.intent, callerFg, false);
		}

		getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);

	} finally {
		Binder.restoreCallingIdentity(origId);
	}

	return 1;
}

在注释2处创建ConnectionRecord对象,传入IServiceConnection对象。

ConnectionRecord.java
final class 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;
    conn = _conn;
    flags = _flags;
    clientLabel = _clientLabel;
    clientIntent = _clientIntent;
    clientUid = _clientUid;
    clientProcessName = _clientProcessName;
    clientPackageName = _clientPackageName;
}
}

将前面的IServiceConnection也就是InnerConnection赋值给conn。
接着通过asBinder得到IBinder对象,然后调用ServiceRecord的addConnection()方法。

ServiceRecord.java
private final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections
            = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
void addConnection(IBinder binder, ConnectionRecord c) {
    ArrayList<ConnectionRecord> clist = connections.get(binder);
    if (clist == null) {
        clist = new ArrayList<>();
        connections.put(binder, clist);
    }
    clist.add(c);

    // if we have a process attached, add bound client uid of this connection to it
    if (app != null) {
        app.addBoundClientUid(c.clientUid);
    }
}

connections是一个ArrayMap,其key保存了IBinder,value保存了一个由ConnectionRecord对象组成的ArrayList,也就是clist。每一个ServiceConnection,都会有一个对应的InnerConnection(IBinder)。每一次bindService都会创建一个ConnectionRecord,里面保存了InnerConnection。对同一个ServiceConnection调用多次bindService,会得到多个ConnectionRecord,并且这些ConnectionRecord会保存在clist中,但是只有一个InnerConnection(IBinder)。
回到bindServiceLocked()方法,在try中,会调用bringUpServiceLocked()方法。

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
		boolean whileRestarting, boolean permissionsReviewRequired)
		throws TransactionTooLargeException {
	...

	// Not running -- get it started, and enqueue this service record
	// to be executed when the app comes up.
	if (app == null && !permissionsReviewRequired) {
		if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
				hostingRecord, false, isolated, false)) == null) {
			String msg = "Unable to launch app "
					+ r.appInfo.packageName + "/"
					+ r.appInfo.uid + " for service "
					+ r.intent.getIntent() + ": process is bad";
			Slog.w(TAG, msg);
			bringDownServiceLocked(r);
			return msg;
		}
		if (isolated) {
			r.isolatedProc = app;
		}
	}

	...

	return null;
}

判断app是否为空,如果service所在的app还没有启动,所在的进程也就为空,需要先创建service所属app所在的进程,这个流程和activity启动是一样的,会通过Zygote进程fork出新app的进程,然后反射调用ActivityThread的attach()方法,接着会在attach()方法中调用ActivityManagerService的attachApplication()方法,然后调用attachApplicationLocked()方法。这一部分就不一步一步看了,可以参考Activity启动流程。直接看ActivityManagerService的attachApplicationLocked()方法。

ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread,
		int pid, int callingUid, long startSeq) {

    ...

	// See if the top visible activity is waiting to run in this process...
	if (normalMode) {
		try {
            //启动Activity调用了该方法
			didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
		} catch (Exception e) {
			...
		}
	}

    // Find any services that should be running in this process...
    if (!badApp) {
        try {
            //启动service时会调用这个方法
            didSomething |= mServices.attachApplicationLocked(app, processName);
            checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
            badApp = true;
        }
    }

    ...

    return true;
}

这里是与启动Activity有区别的地方,启动service会调用mServices的attachApplicationLocked()方法,mServices是ActiveServices类型对象。

ActiveServices.java
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);
				if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
						|| !processName.equals(sr.processName))) {
					continue;
				}

				mPendingServices.remove(i);
				i--;
				proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode,
						mAm.mProcessStats);
				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.java
private final void realStartServiceLocked(ServiceRecord r,
		ProcessRecord app, boolean execInFg) throws RemoteException {
	if (app.thread == null) {
		throw new RemoteException();
	}
	...

	boolean created = false;
	
	...

	if (r.whitelistManager) {
		app.whitelistManager = true;
	}

	requestServiceBindingsLocked(r, execInFg);

	updateServiceClientActivitiesLocked(app, null, true);

	if (newService && created) {
		app.addBoundClientUidsOfNewService(r);
	}

	// 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, 0));
	}

	sendServiceArgsLocked(r, execInFg, true);

	...
}

首先会调用app.thread.scheduleCreateService()方法。这个方法最后会执行service的OnCreate生命周期函数。先往下看,一会再回来看这里。接着会调用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请求,前面提到的bindServiceLockedbindServiceLocked()方法中会通过s.retrieveAppBindingLocked()方法记录r.bindings数组,所以这里的r.bindings不为空,执行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);
			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) {
			...
		} catch (RemoteException e) {
			...
		}
	}
	return true;
}

首先判断service所在app和所在进程是否为空,如果为空的话,直接返回,无法进行bind。接着会在try中调用r.app.thread.scheduleBindService()方法。和前面的scheduleCreateService一起看一下。r.app.thread返回的是一个IApplicationThread对象,ApplicationThread是ActivityThread的内部类,它继承自IApplicationThread.Stub,这里用到了aidl,系统进程通过IApplicationThread与app进程通信,这个在Activity启动流程中也提到了,我们先看一下ApplicationThread的scheduleCreateService()方法,它是先于scheduleBindService()方法调用的。

ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
	private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";

	...

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

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

从系统进程切换到了app进程,调用了scheduleCreateService()方法。H类上篇文章也说过,这是一个Hander。

class H extends Handler {
	...
	public void handleMessage(Message msg) {
		if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
		switch (msg.what) {
			...
			case CREATE_SERVICE:
				Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
				handleCreateService((CreateServiceData)msg.obj);
				Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
				break;
			case BIND_SERVICE:
				Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
				handleBindService((BindServiceData)msg.obj);
				Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
				break;
	}
}

先执行CREATE_SERVICE这个case,调用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 = packageInfo.getAppFactory()
				.instantiateService(cl, data.info.name, data.intent);
	} 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方法
		service.attach(context, this, data.info.name, data.token, app,
				ActivityManager.getService());
                //调用service的onCreate方法
		service.onCreate();
		mServices.put(data.token, service);
		...
	} catch (Exception e) {
		...
	}
}

首先通过调用instantiateService()方法返回一个service的实例,接着会调用这个service的onCreate方法。先看一下instantiateService()方法是如何返回一个service实例的,packageInfo是一个LoadedApk对象。

LoadedApk.java
private AppComponentFactory mAppComponentFactory;
public AppComponentFactory getAppFactory() {
	return mAppComponentFactory;
}

返回一个AppComponentFactory对象,调用AppComponentFactory类的instantiateService()方法。

AppComponentFactory.java
public @NonNull Service instantiateService(@NonNull ClassLoader cl,
        @NonNull String className, @Nullable Intent intent)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Service) cl.loadClass(className).newInstance();
}

可以看到,最终会通过反射创建一个Service实例,这里的className是我们自己服务端的service,所以就是创建了我们的service实例并返回。接着回到ActivityThread.java方法,会通调用已经创建service的onCreate()生命周期方法。最终会将这个service添加到mServices map中。
回到handler中,接着会执行BIND_SERVICE这个case,调用handleBindService()方法。

ActivityThread.java
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) {
                    IBinder binder = s.onBind(data.intent);
                    ActivityManager.getService().publishService(
                            data.token, data.intent, binder);
                } else {
                    s.onRebind(data.intent);
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                }
            } 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);
            }
        }
    }
}

通过mServices,找到已经创建的service。首先调用service的onBind()方法返回一个IBinder对象,也就是我们创建的那个IBinder。到这里,从一开始调用bindService方法,会在服务端service调用onCreate和onBind两个service生命周期方法的流程就梳理完了,还剩最后一步客户端的onServiceConnected()方法什么时候回调。接着看代码,在得到IBinder后,会调用
ActivityManager.getService()的publishService方法,调用ActivityManagerService的publishService()方法。

ActivityManagerService.java
final ActiveServices mServices;
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的publishServiceLocked()方法。

ActiveServices.java
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);
                        ...
                        try {
                            c.conn.connected(r.name, service, false);
                        } catch (Exception e) {
                            ...
                        }
                    }
                }
            }

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

重点在try中执行了c.conn.connected()方法。这个其实就是把上面讲的保存ConnectionRecord那个流程反过来,通过for循环取出ConnectionRecord的过程。得到ConnectionRecord,其中conn保存的是InnerConnection,这是在创建ConnectionRecord对象时传入的,这里如果不是很明白是怎么得到InnerConnection对象的话,可以往前看看,最终是调用了InnerConnection的connected()方法。

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

其中sd为前面创建的ServiceDispatch对象,调用connected()方法。

LoadedApk.java
public void connected(ComponentName name, IBinder service, boolean dead) {
    //executor为空
    if (mActivityExecutor != null) {
        mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
    } else if (mActivityThread != null) {
        //mActivityThread不为空
        mActivityThread.post(new RunConnection(name, service, 0, dead));
    } else {
        doConnected(name, service, dead);
    }
}

mActivityThread为前面传入的客户端app主线程handler,所以不为空,调用主线程handler的post()方法,其中RunConnection为一个Runnable,会执行其中的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() {
        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;
}

执行run()方法,调用doConnected()方法。

public void doConnected(ComponentName name, IBinder service, boolean dead) {
    ServiceDispatcher.ConnectionInfo old;
    ServiceDispatcher.ConnectionInfo info;

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

mConnection为一开始传入的客户端创建的ServiceConnection对象,调用onServiceConnected()方法,也就回调了客户端的onServiceConnected()方法,其中service就是服务端onBinder()方法返回的IBinder对象。
到这里,从客户端发起bindService请求,到服务端Service执行onCreate()、onBinder()返回IBinder对象生命周期方法,并通过onBinder()返回一个IBinder对象,到带着这个IBinder对象回调到客户端ServiceConnection的onServiceConnected()方法整个流程就梳理完了,如有错误欢迎指出。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
bindServiceAndroid中一种组件之间进行通信的方式,它可以在两个组件之间建立一种长期的连接,使得它们可以进行交互。下面是bindService流程详解: 1. 调用bindService方法:在客户端组件中调用bindService方法,该方法接受两个参数,第一个参数是Intent对象,用于指定要绑定的服务组件,第二个参数是ServiceConnection对象,用于指定连接建立和断开时的回调。 2. 系统查找并启动服务组件:系统会查找并启动指定的服务组件,如果服务还没有启动,则将先启动服务。 3. 创建服务组件:系统会创建服务组件,并在其中调用onCreate方法进行初始化。 4. 调用ServiceConnection的onServiceConnected方法:当服务组件创建完成后,系统会调用ServiceConnection的onServiceConnected方法,通知客户端组件连接已建立,并将IBinder对象传递给客户端组件。 5. 获取IBinder对象:客户端组件可以通过ServiceConnection的onServiceConnected方法中传递的IBinder对象与服务组件进行交互。 6. 交互:客户端组件可以通过IBinder对象调用服务组件中的方法,完成交互。 7. 断开连接:当客户端组件不再需要服务组件时,可以调用unbindService方法断开连接,系统会调用ServiceConnection的onServiceDisconnected方法通知客户端组件连接已断开。 8. 销毁服务组件:如果没有任何客户端组件绑定服务组件,系统会调用服务组件的onDestroy方法进行销毁。 总体来说,bindService流程就是客户端组件通过Intent对象指定要绑定的服务组件,系统查找并启动服务组件,客户端组件通过IBinder对象与服务组件进行交互,当客户端组件不再需要服务组件时,调用unbindService方法断开连接,系统会调用服务组件的onDestroy方法进行销毁。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值