bindService用到的各数据结构
2018-12-01 本文已影响0人
weiinter105
bindService中涉及到的几种数据结构
AMS中相关数据结构
ServiceRecord
57final class ServiceRecord extends Binder {
58 private static final String TAG = TAG_WITH_CLASS_NAME ? "ServiceRecord" : TAG_AM;
59
60 // Maximum number of delivery attempts before giving up.
61 static final int MAX_DELIVERY_COUNT = 3;
62
63 // Maximum number of times it can fail during execution before giving up.
64 static final int MAX_DONE_EXECUTING_COUNT = 6;
65
66 final ActivityManagerService ams;
67 final BatteryStatsImpl.Uid.Pkg.Serv stats;
68 final ComponentName name; // service component.
69 final String shortName; // name.flattenToShortString().
70 final Intent.FilterComparison intent;
71 // original intent used to find service.
72 final ServiceInfo serviceInfo;
73 // all information about the service.
74 final ApplicationInfo appInfo;
75 // information about service's app.
76 final int userId; // user that this service is running as
77 final String packageName; // the package implementing intent's component
78 final String processName; // process where this component wants to run
79 final String permission;// permission needed to access service
80 final boolean exported; // from ServiceInfo.exported
81 final Runnable restarter; // used to schedule retries of starting the service
82 final long createTime; // when this service was created
83 final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
84 = new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
//Intent及其对应的IntentBindRecord
85 // All active bindings to the service.
86 final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections
87 = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
//IServiceConnection及其对应的ConnectionRecord list
88 // IBinder -> ConnectionRecord of all bound clients
89
90 ProcessRecord app; // where this service is running or null.
91 ProcessRecord isolatedProc; // keep track of isolated process, if requested
92 ServiceState tracker; // tracking service execution, may be null
93 ServiceState restartTracker; // tracking service restart
94 boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT?
95 boolean delayed; // are we waiting to start this service in the background?
96 boolean fgRequired; // is the service required to go foreground after starting?
97 boolean fgWaiting; // is a timeout for going foreground already scheduled?
98 boolean isForeground; // is service currently in foreground mode?
99 int foregroundId; // Notification ID of last foreground req.
100 Notification foregroundNoti; // Notification record of foreground state.
101 long lastActivity; // last time there was some activity on the service.
102 long startingBgTimeout; // time at which we scheduled this for a delayed start.
103 boolean startRequested; // someone explicitly called start?
104 boolean delayedStop; // service has been stopped but is in a delayed start?
105 boolean stopIfKilled; // last onStart() said to stop if service killed?
106 boolean callStart; // last onStart() has asked to alway be called on restart.
107 int executeNesting; // number of outstanding operations keeping foreground.
108 boolean executeFg; // should we be executing in the foreground?
109 long executingStart; // start time of last execute request.
110 boolean createdFromFg; // was this service last created due to a foreground process call?
111 int crashCount; // number of times proc has crashed with service running
112 int totalRestartCount; // number of times we have had to restart.
113 int restartCount; // number of restarts performed in a row.
114 long restartDelay; // delay until next restart attempt.
115 long restartTime; // time of last restart.
116 long nextRestartTime; // time when restartDelay will expire.
117 boolean destroying; // set when we have started destroying the service
118 long destroyTime; // time at which destory was initiated.
119
120 String stringName; // caching of toString
121
122 private int lastStartId; // identifier of most recent start request.
123
124 static class StartItem {
125 final ServiceRecord sr;
126 final boolean taskRemoved;
127 final int id;
128 final int callingId;
129 final Intent intent;
130 final ActivityManagerService.NeededUriGrants neededGrants;
131 long deliveredTime;
132 int deliveryCount;
133 int doneExecutingCount;
134 UriPermissionOwner uriPermissions;
135
136 String stringName; // caching of toString
IntentBindRecord
一个Service可能与多种Intent关联,从Intent的角度保存的数据结构
27/**
28 * A particular Intent that has been bound to a Service.
29 */
30final class IntentBindRecord {
31 /** The running service. */
32 final ServiceRecord service;
33 /** The intent that is bound.*/
34 final Intent.FilterComparison intent; //
35 /** All apps that have bound to this Intent. */
36 final ArrayMap<ProcessRecord, AppBindRecord> apps
37 = new ArrayMap<ProcessRecord, AppBindRecord>();
//保存所有使用了该种Intent的客户端
38 /** Binder published from service. */
39 IBinder binder;
//保存的服务端Service实例对应的binder对象
40 /** Set when we have initiated a request for this binder. */
//需要结合代码看
41 boolean requested;
42 /** Set when we have received the requested binder. */
43 boolean received;
44 /** Set when we still need to tell the service all clients are unbound. */
45 boolean hasBound;
46 /** Set when the service's onUnbind() has asked to be told about new clients. */
47 boolean doRebind;
48
49 String stringName; // caching of toString
AppBindRecord
其实代表了相应ServiceRecord的一个客户端在AMS中的表达方式
23/**
24 * An association between a service and one of its client applications.
25 */
26final class AppBindRecord {
27 final ServiceRecord service; // The running service.
//绑定的ServiceRecord
28 final IntentBindRecord intent; // The intent we are bound to.
//用于绑定的Intent (IntentBindRecord)
29 final ProcessRecord client; // Who has started/bound the service.
//客户端进程信息
30
31 final ArraySet<ConnectionRecord> connections = new ArraySet<>();
//客户端所持有的ConnectionRecord
32 // All ConnectionRecord for this client.
ConnectionRecord
代表一个最小的binding元素
25/**
26 * Description of a single binding to a service.
27 */
28final class ConnectionRecord {
29 final AppBindRecord binding; // The application/service binding.
//依附的客户端的相关信息
30 final ActivityRecord activity; // If non-null, the owning activity.
//从客户端的Activity bindService
31 final IServiceConnection conn; // The client connection.
//客户端ServiceConnection对应的binder对象
32 final int flags; // Binding options.
33 final int clientLabel; // String resource labeling this client.
34 final PendingIntent clientIntent; // How to launch the client.
35 String stringName; // Caching of toString.
36 boolean serviceDead; // Well is it?
总结
相当于客户端进程,Intent,ServiceConnection是bindService的三要素,这三者确定要绑定的ServiceRecord
1.三个要素都限定死了,那么就是ConnectionRecord
2.限定死了客户端进程和Intent,放松ServiceRecord就是AppBindRecord (ArraySet<ConnectionRecord> connections)
3.只限定Intent,那么可以有多个客户端使用Intent来bindService( final ArrayMap<ProcessRecord, AppBindRecord> apps = new ArrayMap<ProcessRecord, AppBindRecord>(); //保存所有使用了该种Intent的客户端)
客户端数据结构
ServiceDispatcher
124 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
125 = new ArrayMap<>();
1489 static final class ServiceDispatcher {
1490 private final ServiceDispatcher.InnerConnection mIServiceConnection;
//持有一个与ServiceConnection对象相关的binder对象传递给AMS,这样AMS就可以通过这个对象来操作客户端,这个对象是个内部类,其持有外部对象的弱引用,这样就可以调用到ServiceDispatcher中的方法,比较巧妙
1491 private final ServiceConnection mConnection;
1492 private final Context mContext;
1493 private final Handler mActivityThread;
1494 private final ServiceConnectionLeaked mLocation;
1495 private final int mFlags;
1496
1497 private RuntimeException mUnbindLocation;
1498
1499 private boolean mForgotten;
1500
1501 private static class ConnectionInfo {
1502 IBinder binder;
1503 IBinder.DeathRecipient deathMonitor;
1504 }
1505
1506 private static class InnerConnection extends IServiceConnection.Stub {
1507 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
//WeakReference的使用场景
//静态内部类持有外部对象(用WeakReference引用)
完整逻辑:
1489 static final class ServiceDispatcher {
1490 private final ServiceDispatcher.InnerConnection mIServiceConnection;
1491 private final ServiceConnection mConnection;
1492 private final Context mContext;
1493 private final Handler mActivityThread;
1494 private final ServiceConnectionLeaked mLocation;
1495 private final int mFlags;
1496
1497 private RuntimeException mUnbindLocation;
1498
1499 private boolean mForgotten;
1500
1501 private static class ConnectionInfo {
1502 IBinder binder;
1503 IBinder.DeathRecipient deathMonitor;
1504 }
1505
1506 private static class InnerConnection extends IServiceConnection.Stub {
1507 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher; //WeakReference的使用场景
//静态内部类持有外部对象(用WeakReference引用)
1508
1509 InnerConnection(LoadedApk.ServiceDispatcher sd) {
1510 mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
1511 }
1512
1513 public void connected(ComponentName name, IBinder service, boolean dead)
1514 throws RemoteException {
1515 LoadedApk.ServiceDispatcher sd = mDispatcher.get();
1516 if (sd != null) { //判断其是否已经被回收
1517 sd.connected(name, service, dead);
1518 }
1519 }
1520 }
1521
1522 private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
1523 = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
1524
1525 ServiceDispatcher(ServiceConnection conn,
1526 Context context, Handler activityThread, int flags) {
1527 mIServiceConnection = new InnerConnection(this);
1528 mConnection = conn;
1529 mContext = context;
1530 mActivityThread = activityThread;
1531 mLocation = new ServiceConnectionLeaked(null);
1532 mLocation.fillInStackTrace();
1533 mFlags = flags;
1534 }
1535
1536 void validate(Context context, Handler activityThread) {
1537 if (mContext != context) {
1538 throw new RuntimeException(
1539 "ServiceConnection " + mConnection +
1540 " registered with differing Context (was " +
1541 mContext + " now " + context + ")");
1542 }
1543 if (mActivityThread != activityThread) {
1544 throw new RuntimeException(
1545 "ServiceConnection " + mConnection +
1546 " registered with differing handler (was " +
1547 mActivityThread + " now " + activityThread + ")");
1548 }
1549 }
1550
1551 void doForget() {
1552 synchronized(this) {
1553 for (int i=0; i<mActiveConnections.size(); i++) {
1554 ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i);
1555 ci.binder.unlinkToDeath(ci.deathMonitor, 0);
1556 }
1557 mActiveConnections.clear();
1558 mForgotten = true;
1559 }
1560 }
1561
1562 ServiceConnectionLeaked getLocation() {
1563 return mLocation;
1564 }
1565
1566 ServiceConnection getServiceConnection() {
1567 return mConnection;
1568 }
1569
1570 IServiceConnection getIServiceConnection() {
1571 return mIServiceConnection;
1572 }
1573
1574 int getFlags() {
1575 return mFlags;
1576 }
1577
1578 void setUnbindLocation(RuntimeException ex) {
1579 mUnbindLocation = ex;
1580 }
1581
1582 RuntimeException getUnbindLocation() {
1583 return mUnbindLocation;
1584 }
1585
1586 public void connected(ComponentName name, IBinder service, boolean dead) {
1587 if (mActivityThread != null) {
1588 mActivityThread.post(new RunConnection(name, service, 0, dead));
1589 } else {
1590 doConnected(name, service, dead);
1591 }
1592 }
1593
1594 public void death(ComponentName name, IBinder service) {
1595 if (mActivityThread != null) {
1596 mActivityThread.post(new RunConnection(name, service, 1, false));
1597 } else {
1598 doDeath(name, service);
1599 }
1600 }
1601
1602 public void doConnected(ComponentName name, IBinder service, boolean dead) {
1603 ServiceDispatcher.ConnectionInfo old;
1604 ServiceDispatcher.ConnectionInfo info;
1605
1606 synchronized (this) {
1607 if (mForgotten) {
1608 // We unbound before receiving the connection; ignore
1609 // any connection received.
1610 return;
1611 }
1612 old = mActiveConnections.get(name);
1613 if (old != null && old.binder == service) {
1614 // Huh, already have this one. Oh well!
1615 return;
1616 }
1617
1618 if (service != null) {
1619 // A new service is being connected... set it all up.
1620 info = new ConnectionInfo();
1621 info.binder = service;
1622 info.deathMonitor = new DeathMonitor(name, service);
1623 try {
1624 service.linkToDeath(info.deathMonitor, 0);
1625 mActiveConnections.put(name, info);
1626 } catch (RemoteException e) {
1627 // This service was dead before we got it... just
1628 // don't do anything with it.
1629 mActiveConnections.remove(name);
1630 return;
1631 }
1632
1633 } else {
1634 // The named service is being disconnected... clean up.
1635 mActiveConnections.remove(name);
1636 }
1637
1638 if (old != null) {
1639 old.binder.unlinkToDeath(old.deathMonitor, 0);
1640 }
1641 }
1642
1643 // If there was an old service, it is now disconnected.
1644 if (old != null) {
1645 mConnection.onServiceDisconnected(name);
1646 }
1647 if (dead) {
1648 mConnection.onBindingDied(name);
1649 }
1650 // If there is a new service, it is now connected.
1651 if (service != null) {
1652 mConnection.onServiceConnected(name, service);
1653 }
1654 }
1655
1656 public void doDeath(ComponentName name, IBinder service) {
1657 synchronized (this) {
1658 ConnectionInfo old = mActiveConnections.get(name);
1659 if (old == null || old.binder != service) {
1660 // Death for someone different than who we last
1661 // reported... just ignore it.
1662 return;
1663 }
1664 mActiveConnections.remove(name);
1665 old.binder.unlinkToDeath(old.deathMonitor, 0);
1666 }
1667
1668 mConnection.onServiceDisconnected(name);
1669 }
1670
1671 private final class RunConnection implements Runnable {
1672 RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
1673 mName = name;
1674 mService = service;
1675 mCommand = command;
1676 mDead = dead;
1677 }
1678
1679 public void run() {
1680 if (mCommand == 0) {
1681 doConnected(mName, mService, mDead);
1682 } else if (mCommand == 1) {
1683 doDeath(mName, mService);
1684 }
1685 }
1686
1687 final ComponentName mName;
1688 final IBinder mService;
1689 final int mCommand;
1690 final boolean mDead;
1691 }
1692
1693 private final class DeathMonitor implements IBinder.DeathRecipient
1694 {
1695 DeathMonitor(ComponentName name, IBinder service) {
1696 mName = name;
1697 mService = service;
1698 }
1699
1700 public void binderDied() {
1701 death(mName, mService);
1702 }
1703
1704 final ComponentName mName;
1705 final IBinder mService;
1706 }
1707 }
1708}
服务端数据结构
就是一个Service实例,没什么特别值得说的
总结结构图

可见,IntentBindRecord.binder中保存的Service实例的binder对象,ConnectionRecord.conn保存客户端ServiceConnection对应的binder对象