android之基础学习攻克

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实例,没什么特别值得说的

总结结构图

bindService数据结构.png

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

上一篇下一篇

猜你喜欢

热点阅读