写点什么

BindService 的生命周期分析【我读源码你不读,我吃螃蟹你吃土

用户头像
Android架构
关注
发布于: 刚刚

if (r.state == ActivityState.DESTROYING) {


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


cleanUpActivityLocked(r, true, false);removeActivityFromHistoryLocked(r, reason);}}mStackSupervisor.resumeFocusedStackTopActivityLocked();} finally {Binder.restoreCallingIdentity(origId);}}


当判断 ActivityRecord 对象的 state 为 ActivityState.DESTROYING 时,又调用了 cleanUpActivityLocked 方法,注意这里的第二个参数值为 true。如下所示:


private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean setState) {onActivityRemovedFromStack(r);


r.deferRelaunchUntilPaused = false;r.frozenBeforeDestroy = false;


...省略


if (cleanServices) {cleanUpActivityServicesLocked(r);}


removeTimeoutsForActivityLocked(r);mWindowManager.notifyAppRelaunchesCleared(r.appToken);}


从上一步骤可以看到,cleanServices 的参数值为 true,所以这里调用了 cleanUpActivityServicesLocked 方法,如下所示:


private void cleanUpActivityServicesLocked(ActivityRecord r) {if (r.connections != null) {Iterator<ConnectionRecord> it = r.connections.iterator();while (it.hasNext()) {ConnectionRecord c = it.next();mService.mServices.removeConnectionLocked(c, null, r);}r.connections = null;}}

2.3、分析阶段 3

承接上面的逻辑,在 cleanUpActivityServicesLocked 方法中,执行了一个判空操作 r.connection != null,而从[Service 的工作过程](


)这篇文章可知,当 Service 绑定在 Activity 时,在 ActiveService 类的 bindServiceLocked 方法中会将为 ActivityRecord 对象的 connections 赋值。因此得出以下结论:


当 Activity 没有绑定任何 Service 时,然后 cleanUpActivityServicesLocked 方法内的逻辑并不会执行


所以,当 Activity 绑定了 Service 时,会继续执行 ActiveServices 的 removeConnectionLocked 方法。如下所示:


void removeConnectionLocked(ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {IBinder binder = c.conn.asBinder();AppBindRecord b = c.binding;ServiceRecord s = b.service;ArrayList<ConnectionRecord> clist = s.connections.get(binder);if (clist != null) {clist.remove(c);if (clist.size() == 0) {s.connections.remove(binder);}}b.connections.remove(c);if (c.activity != null && c.activity != skipAct) {if (c.activity.connections != null) {//1、将 ConnectionRecord 对象从 ActivityRecord 对象的 connections 中去掉 c.activity.connections.remove(c);}}


...省略 if (!c.serviceDead) {if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0&& b.intent.hasBound) {try {bumpServiceExecutingLocked(s, false, "unbind");if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0&& s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {mAm.updateLruProcessLocked(s.app, false, null);}mAm.updateOomAdjLocked(s.app, true);b.intent.hasBound = false;b.intent.doRebind = false;s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());} catch (Exception e) {Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);serviceProcessGoneLocked(s);}}mPendingServices.remove(s);


if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {boolean hasAutoCreate = s.hasAutoCreateConnections();if (!hasAutoCreate) {if (s.tracker != null) {s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),SystemClock.uptimeMillis());}}//2、调用 bringDownServiceIfNeededLocked 方法 bringDownServiceIfNeededLocked(s, true, hasAutoCreate);}}}


上面的代码有点长,但是总体来说就做了两步逻辑: 1、将 ConnectionRecord 对象从 ActivityRecord 对象的 connections 中去掉。 2、调用 bringDownServiceIfNeededLocked 方法,而 bringDownServiceIfNeededLocked 方法又调用了 bringDownServiceLocked 方法,如下所示:


private final void bringDownServiceLocked(ServiceRecord r) {


// Tell the service that it has been unbound.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 {bumpServiceExecutingLocked(r, false, "bring down unbind");mAm.updateOomAdjLocked(r.app, true);ibr.hasBound = false;ibr.requested = false;//1、调用 ActivityThread 的 scheduleUnbindService 方法 r.app.thread.scheduleUnbindService(r,ibr.intent.getIntent());} catch (Exception e) {Slog.w(TAG, "Exception when unbinding service "


  • r.shortName, e);serviceProcessGoneLocked(r);}}}}...省略


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);//2、调用了 ActivityThread 的 scheduleStopService 方法 r.app.thread.scheduleStopService(r);} catch (Exception e) {


}}}


...省略}


上面的代码逻辑主要做了两步: 1、调用了 ActivityThread 的 scheduleUnbindService 方法。该方法主要是将绑定的 Service 进行解绑,最终会调用 Service 的 onUnbind 方法。 2、调用了 ActivityThread 的 scheduleStopService 方法。该方法会将绑定的 Service 进行销毁,最终会调用 Service 的 onDestroy 方法。

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
BindService的生命周期分析【我读源码你不读,我吃螃蟹你吃土