Android13 ActivityManagerService unbindService流程分析

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方法:

Android13 ActivityThread handleUnbindService流程分析-CSDN博客

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值