ActivityManagerService的unbindService用于解绑Service,代码如下:
//frameworks/base/service/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
final ActiveServices mServices;
public boolean unbindService(IServiceConnection connection) {
synchronized (this) {
return mServices.unbindServiceLocked(connection);
}
}
}
ActiveServices unbindServiceLocked
调用ActiveServices的unbindServiceLocked方法:
//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
final ActivityManagerService mAm;
boolean unbindServiceLocked(IServiceConnection connection) {
IBinder binder = connection.asBinder();
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "unbindService: conn=" + binder);
ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
if (clist == null) {
Slog.w(TAG, "Unbind failed: could not find connection for "
+ connection.asBinder());
return false;
}
final long origId = Binder.clearCallingIdentity();
try {
while (clist.size() > 0) {
ConnectionRecord r = clist.get(0);
removeConnectionLocked(r, null, null, true);
if (clist.size() > 0 && clist.get(0) == r) {
// In case it didn't get removed above, do it now.
Slog.wtf(TAG, "Connection " + r + " not removed for binder " + binder);
clist.remove(0);
}
final ProcessRecord app = r.binding.service.app;
if (app != null) {
final ProcessServiceRecord psr = app.mServices;
if (psr.mAllowlistManager) {
updateAllowlistManagerLocked(psr);
}
// This could have made the service less important.
if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
psr.setTreatLikeActivity(true);
mAm.updateLruProcessLocked(app, true, null);
}
mAm.enqueueOomAdjTargetLocked(app);
}
}
mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
} finally {
Binder.restoreCallingIdentity(origId);
}
return true;
}
}
ActiveServices removeConnectionLocked
调用ActiveServices的removeConnectionLocked方法:
//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
void removeConnectionLocked(ConnectionRecord c, ProcessRecord skipApp,
ActivityServiceConnectionsHolder skipAct, boolean enqueueOomAdj) {
IBinder binder = c.conn.asBinder();
AppBindRecord b = c.binding;
ServiceRecord s = b.service;
ArrayList<ConnectionRecord> clist = s.getConnections().get(binder);
if (clist != null) {
clist.remove(c);
if (clist.size() == 0) {
s.removeConnection(binder);
}
}
b.connections.remove(c);
c.stopAssociation();
if (c.activity != null && c.activity != skipAct) {
c.activity.removeConnection(c);
}
if (b.client != skipApp) {
final ProcessServiceRecord psr = b.client.mServices;
psr.removeConnection(c);
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
psr.updateHasAboveClientLocked();
}
// If this connection requested allowlist management, see if we should
// now clear that state.
if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
s.updateAllowlistManager();
if (!s.allowlistManager && s.app != null) {
updateAllowlistManagerLocked(s.app.mServices);
}
}
// And do the same for bg activity starts ability.
if ((c.flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
s.updateIsAllowedBgActivityStartsByBinding();
}
// And for almost perceptible exceptions.
if ((c.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0) {
psr.updateHasTopStartedAlmostPerceptibleServices();
}
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app.mServices, c, true);
}
}
clist = mServiceConnections.get(binder);
if (clist != null) {
clist.remove(c);
if (clist.size() == 0) {
mServiceConnections.remove(binder);
}
}
mAm.stopAssociationLocked(b.client.uid, b.client.processName, s.appInfo.uid,
s.appInfo.longVersionCode, s.instanceName, s.processName);
if (b.connections.size() == 0) {
b.intent.apps.remove(b.client);
}
if (!c.serviceDead) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Disconnecting binding " + b.intent
+ ": shouldUnbind=" + b.intent.hasBound);
if (s.app != null && s.app.getThread() != null && b.intent.apps.size() == 0
&& b.intent.hasBound) {
try {
bumpServiceExecutingLocked(s, false, "unbind",
OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
&& s.app.mState.getSetProcState() <= PROCESS_STATE_HEAVY_WEIGHT) {
// If this service's process is not already in the cached list,
// then update it in the LRU list here because this may be causing
// it to go down there and we want it to start out near the top.
mAm.updateLruProcessLocked(s.app, false, null);
}
b.intent.hasBound = false;
// Assume the client doesn't want to know about a rebind;
// we will deal with that later if it asks for one.
b.intent.doRebind = false;
s.app.getThread().scheduleUnbindService(s, b.intent.intent.getIntent());
} catch (Exception e) {
Slog.w(TAG, "Exception when unbinding service " + s.shortInstanceName, e);
serviceProcessGoneLocked(s, enqueueOomAdj);
}
}
// If unbound while waiting to start and there is no connection left in this service,
// remove the pending service
if (s.getConnections().isEmpty()) {
mPendingServices.remove(s);
mPendingBringups.remove(s);
}
if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
boolean hasAutoCreate = s.hasAutoCreateConnections();
if (!hasAutoCreate) {
if (s.tracker != null) {
synchronized (mAm.mProcessStats.mLock) {
s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis());
}
}
}
bringDownServiceIfNeededLocked(s, true, hasAutoCreate, enqueueOomAdj);
}
}
}
}
ApplicationThread scheduleUnbindService
s.app.getThread()返回IApplicationThread接口,调用IApplicationThread的scheduleUnbindService方法,IApplicationThread是一个接口由ActivityThread的内部类ApplicationThread实现:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
private class ApplicationThread extends IApplicationThread.Stub {
public final void scheduleUnbindService(IBinder token, Intent intent) {
BindServiceData s = new BindServiceData();
s.token = token;
s.intent = intent;
sendMessage(H.UNBIND_SERVICE, s);
}
}
}
发送UNBIND_SERVICE消息,消息在H的handleMessage中处理:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {
class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case UNBIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
handleUnbindService((BindServiceData)msg.obj);
schedulePurgeIdler();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
}
}
ActivityThread handleBindService
调用ActivityThread的handleBindService方法: