android之基础学习攻克

广播相关学习-数据结构

2018-12-21  本文已影响0人  weiinter105

动态注册广播相关的

app端

LoadedApk#ReceiverDispatcher

1203    static final class ReceiverDispatcher {
1204
1205        final static class InnerReceiver extends IIntentReceiver.Stub {
1206            final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
1207            final LoadedApk.ReceiverDispatcher mStrongRef;
1208
1209            InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
1210                mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
1211                mStrongRef = strong ? rd : null;
1212            }
1213
1214            @Override
1215            public void performReceive(Intent intent, int resultCode, String data,
1216                    Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
1217                final LoadedApk.ReceiverDispatcher rd;
1218                if (intent == null) {
1219                    Log.wtf(TAG, "Null intent received");
1220                    rd = null;
1221                } else {
1222                    rd = mDispatcher.get();
1223                }
1224                if (ActivityThread.DEBUG_BROADCAST) {
1225                    int seq = intent.getIntExtra("seq", -1);
1226                    Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
1227                            + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
1228                }
1229                if (rd != null) {
1230                    rd.performReceive(intent, resultCode, data, extras,
1231                            ordered, sticky, sendingUser);
1232                } else {
1233                    // The activity manager dispatched a broadcast to a registered
1234                    // receiver in this process, but before it could be delivered the
1235                    // receiver was unregistered.  Acknowledge the broadcast on its
1236                    // behalf so that the system's broadcast sequence can continue.
1237                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1238                            "Finishing broadcast to unregistered receiver");
1239                    IActivityManager mgr = ActivityManager.getService();
1240                    try {
1241                        if (extras != null) {
1242                            extras.setAllowFds(false);
1243                        }
1244                        mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
1245                    } catch (RemoteException e) {
1246                        throw e.rethrowFromSystemServer();
1247                    }
1248                }
1249            }
1250        }
1251
1252        final IIntentReceiver.Stub mIIntentReceiver;
1253        final BroadcastReceiver mReceiver;
1254        final Context mContext;
1255        final Handler mActivityThread;
1256        final Instrumentation mInstrumentation;
1257        final boolean mRegistered;
1258        final IntentReceiverLeaked mLocation;
1259        RuntimeException mUnregisterLocation;
1260        boolean mForgotten;
1261
1262        final class Args extends BroadcastReceiver.PendingResult {
1263            private Intent mCurIntent;
1264            private final boolean mOrdered;
1265            private boolean mDispatched;
1266            private Throwable mPreviousRunStacktrace; // To investigate b/37809561. STOPSHIP remove.
1267
1268            public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
1269                    boolean ordered, boolean sticky, int sendingUser) {
1270                super(resultCode, resultData, resultExtras,
1271                        mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
1272                        sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
1273                mCurIntent = intent;
1274                mOrdered = ordered;
1275            }
1276
1277            public final Runnable getRunnable() {
1278                return () -> {
1279                    final BroadcastReceiver receiver = mReceiver;
1280                    final boolean ordered = mOrdered;
1281
1282                    if (ActivityThread.DEBUG_BROADCAST) {
1283                        int seq = mCurIntent.getIntExtra("seq", -1);
1284                        Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
1285                                + " seq=" + seq + " to " + mReceiver);
1286                        Slog.i(ActivityThread.TAG, "  mRegistered=" + mRegistered
1287                                + " mOrderedHint=" + ordered);
1288                    }
1289
1290                    final IActivityManager mgr = ActivityManager.getService();
1291                    final Intent intent = mCurIntent;
1292                    if (intent == null) {
1293                        Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
1294                                + ": run() previously called at "
1295                                + Log.getStackTraceString(mPreviousRunStacktrace));
1296                    }
1297
1298                    mCurIntent = null;
1299                    mDispatched = true;
1300                    mPreviousRunStacktrace = new Throwable("Previous stacktrace");
1301                    if (receiver == null || intent == null || mForgotten) {
1302                        if (mRegistered && ordered) {
1303                            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1304                                    "Finishing null broadcast to " + mReceiver);
1305                            sendFinished(mgr);
1306                        }
1307                        return;
1308                    }
1309
1310                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
1312                    long startTime = SystemClock.uptimeMillis();
1313                    try {
1314                        ClassLoader cl = mReceiver.getClass().getClassLoader();
1315                        intent.setExtrasClassLoader(cl);
1316                        intent.prepareToEnterProcess();
1317                        setExtrasClassLoader(cl);
1318                        receiver.setPendingResult(this);
1319                        receiver.onReceive(mContext, intent);
1320                    } catch (Exception e) {
1321                        if (mRegistered && ordered) {
1322                            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1323                                    "Finishing failed broadcast to " + mReceiver);
1324                            sendFinished(mgr);
1325                        }
1326                        if (mInstrumentation == null ||
1327                                !mInstrumentation.onException(mReceiver, e)) {
1328                            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1329                            throw new RuntimeException(
1330                                    "Error receiving broadcast " + intent
1331                                            + " in " + mReceiver, e);
1332                        }
1333                    }
1334
1335                    if (receiver.getPendingResult() != null) {
1336                        finish();
1337                    }
1340                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1341                };
1342            }
1343        }

        ReceiverDispatcher(BroadcastReceiver receiver, Context context,
1424                Handler activityThread, Instrumentation instrumentation,
1425                boolean registered) {
1426            if (activityThread == null) {
1427                throw new NullPointerException("Handler must not be null");
1428            }
1429
1430            mIIntentReceiver = new InnerReceiver(this, !registered);
1431            mReceiver = receiver;
1432            mContext = context;
1433            mActivityThread = activityThread;
1434            mInstrumentation = instrumentation;
1435            mRegistered = registered;
1436            mLocation = new IntentReceiverLeaked(null);
1437            mLocation.fillInStackTrace();
1438        }
1439
1440        void validate(Context context, Handler activityThread) {
1441            if (mContext != context) {
1442                throw new IllegalStateException(
1443                    "Receiver " + mReceiver +
1444                    " registered with differing Context (was " +
1445                    mContext + " now " + context + ")");
1446            }
1447            if (mActivityThread != activityThread) {
1448                throw new IllegalStateException(
1449                    "Receiver " + mReceiver +
1450                    " registered with differing handler (was " +
1451                    mActivityThread + " now " + activityThread + ")");
1452            }
1453        }
1454
1455        IntentReceiverLeaked getLocation() {
1456            return mLocation;
1457        }
1458
1459        BroadcastReceiver getIntentReceiver() {
1460            return mReceiver;
1461        }
1462
1463        IIntentReceiver getIIntentReceiver() {
1464            return mIIntentReceiver;
1465        }
1466
1467        void setUnregisterLocation(RuntimeException ex) {
1468            mUnregisterLocation = ex;
1469        }
1470
1471        RuntimeException getUnregisterLocation() {
1472            return mUnregisterLocation;
1473        }
1474
1475        public void performReceive(Intent intent, int resultCode, String data,
1476                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
1477            final Args args = new Args(intent, resultCode, data, extras, ordered,
1478                    sticky, sendingUser);
1479            if (intent == null) {
1480                Log.wtf(TAG, "Null intent received");
1481            } else {
1482                if (ActivityThread.DEBUG_BROADCAST) {
1483                    int seq = intent.getIntExtra("seq", -1);
1484                    Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
1485                            + " seq=" + seq + " to " + mReceiver);
1486                }
1487            }
1488            if (intent == null || !mActivityThread.post(args.getRunnable())) {
1489                if (mRegistered && ordered) {
1490                    IActivityManager mgr = ActivityManager.getService();
1491                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1492                            "Finishing sync broadcast to " + mReceiver);
1493                    args.sendFinished(mgr);
1494                }
1495            }
1496        }
1497
1498    }

system_server端

ReceiverList

32final class ReceiverList extends ArrayList<BroadcastFilter>
33        implements IBinder.DeathRecipient {
34    final ActivityManagerService owner;
35    public final IIntentReceiver receiver;
36    public final ProcessRecord app;
37    public final int pid;
38    public final int uid;
39    public final int userId;
40    BroadcastRecord curBroadcast = null;
41    boolean linkedToDeath = false;
42
43    String stringName;
44

BroadcastFilter

25final class BroadcastFilter extends IntentFilter {
26    // Back-pointer to the list this filter is in.
27    final ReceiverList receiverList;
28    final String packageName;
29    final String requiredPermission;
30    final int owningUid;
31    final int owningUserId;
32    final boolean instantApp;
33    final boolean visibleToInstantApp;
34

一个ReceiverList可以包含多个BroadcastFilter ,及一个BoradcastReceiver对象可以见多个IntentFilter,这也是正常的


broadcast_register_s.jpg

InnerReceiver为IIntentReceiver对象,用于AMS binder call到客户端(oneway),最终调用客户端的onReceive

发送广播相关的另加

BroadcastQueue

68    private static final String TAG = "BroadcastQueue";
69    private static final String TAG_MU = TAG + POSTFIX_MU;
70    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
71
72    static final int MAX_BROADCAST_HISTORY = ActivityManager.isLowRamDeviceStatic() ? 10 : 50;
73    static final int MAX_BROADCAST_SUMMARY_HISTORY
74            = ActivityManager.isLowRamDeviceStatic() ? 25 : 300;
75
76    final ActivityManagerService mService;
77
78    /**
79     * Recognizable moniker for this queue
80     */
81    final String mQueueName;
82
83    /**
84     * Timeout period for this queue's broadcasts
85     */
86    final long mTimeoutPeriod;
87
88    /**
89     * If true, we can delay broadcasts while waiting services to finish in the previous
90     * receiver's process.
91     */
92    final boolean mDelayBehindServices;
93
94    /**
95     * Lists of all active broadcasts that are to be executed immediately
96     * (without waiting for another broadcast to finish).  Currently this only
97     * contains broadcasts to registered receivers, to avoid spinning up
98     * a bunch of processes to execute IntentReceiver components.  Background-
99     * and foreground-priority broadcasts are queued separately.
100     */
101    final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>();
102
103    /**
104     * List of all active broadcasts that are to be executed one at a time.
105     * The object at the top of the list is the currently activity broadcasts;
106     * those after it are waiting for the top to finish.  As with parallel
107     * broadcasts, separate background- and foreground-priority queues are
108     * maintained.
109     */
110    final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<>();
111
112    /**
113     * Historical data of past broadcasts, for debugging.  This is a ring buffer
114     * whose last element is at mHistoryNext.
115     */
116    final BroadcastRecord[] mBroadcastHistory = new BroadcastRecord[MAX_BROADCAST_HISTORY];
117    int mHistoryNext = 0;
118
119    /**
120     * Summary of historical data of past broadcasts, for debugging.  This is a
121     * ring buffer whose last element is at mSummaryHistoryNext.
122     */
123    final Intent[] mBroadcastSummaryHistory = new Intent[MAX_BROADCAST_SUMMARY_HISTORY];
124    int mSummaryHistoryNext = 0;
125
126    /**
127     * Various milestone timestamps of entries in the mBroadcastSummaryHistory ring
128     * buffer, also tracked via the mSummaryHistoryNext index.  These are all in wall
129     * clock time, not elapsed.
130     */
131    final long[] mSummaryHistoryEnqueueTime = new  long[MAX_BROADCAST_SUMMARY_HISTORY];
132    final long[] mSummaryHistoryDispatchTime = new  long[MAX_BROADCAST_SUMMARY_HISTORY];
133    final long[] mSummaryHistoryFinishTime = new  long[MAX_BROADCAST_SUMMARY_HISTORY];
134
135    /**
136     * Set when we current have a BROADCAST_INTENT_MSG in flight.
137     */
138    boolean mBroadcastsScheduled = false;
139
140    /**
141     * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
142     */
143    boolean mPendingBroadcastTimeoutMessage;
144
145    /**
146     * Intent broadcasts that we have tried to start, but are
147     * waiting for the application's process to be created.  We only
148     * need one per scheduling class (instead of a list) because we always
149     * process broadcasts one at a time, so no others can be started while
150     * waiting for this one.
151     */
152    BroadcastRecord mPendingBroadcast = null;
153
154    /**
155     * The receiver index that is pending, to restart the broadcast if needed.
156     */
157    int mPendingBroadcastRecvIndex;
158
159    static final int BROADCAST_INTENT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG;
160    static final int BROADCAST_TIMEOUT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 1;
161
162    final BroadcastHandler mHandler;
163
166    final class BroadcastHandler extends Handler {
167        public BroadcastHandler(Looper looper) {
168            super(looper, null, true);
169        }
170
171        @Override
172        public void handleMessage(Message msg) {
173            switch (msg.what) {
174                case BROADCAST_INTENT_MSG: {
175                    if (DEBUG_BROADCAST) Slog.v(
176                            TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
177                    processNextBroadcast(true);
178                } break;
179                case BROADCAST_TIMEOUT_MSG: {
180                    synchronized (mService) {
181                        broadcastTimeoutLocked(true);
182                    }
183                } break;
184            }
185        }
186    }

BroadcastRecord

45final class BroadcastRecord extends Binder {
46    final Intent intent;    // the original intent that generated us
47    final ComponentName targetComp; // original component name set on the intent
48    final ProcessRecord callerApp; // process that sent this
49    final String callerPackage; // who sent this
50    final int callingPid;   // the pid of who sent this
51    final int callingUid;   // the uid of who sent this
52    final boolean callerInstantApp; // caller is an Instant App?
53    final boolean ordered;  // serialize the send to receivers?
54    final boolean sticky;   // originated from existing sticky data?
55    final boolean initialSticky; // initial broadcast from register to sticky?
56    final int userId;       // user id this broadcast was for
57    final String resolvedType; // the resolved data type
58    final String[] requiredPermissions; // permissions the caller has required
59    final int appOp;        // an app op that is associated with this broadcast
60    final BroadcastOptions options; // BroadcastOptions supplied by caller
61    final List receivers;   // contains BroadcastFilter and ResolveInfo
62    final int[] delivery;   // delivery state of each receiver
63    IIntentReceiver resultTo; // who receives final result if non-null
64    long enqueueClockTime;  // the clock time the broadcast was enqueued
65    long dispatchTime;      // when dispatch started on this set of receivers
66    long dispatchClockTime; // the clock time the dispatch started
67    long receiverTime;      // when current receiver started for timeouts.
68    long finishTime;        // when we finished the broadcast.
69    int resultCode;         // current result code value.
70    String resultData;      // current result data value.
71    Bundle resultExtras;    // current result extra data values.
72    boolean resultAbort;    // current result abortBroadcast value.
73    int nextReceiver;       // next receiver to be executed.
74    IBinder receiver;       // who is currently running, null if none.
75    int state;
76    int anrCount;           // has this broadcast record hit any ANRs?
77    int manifestCount;      // number of manifest receivers dispatched.
78    int manifestSkipCount;  // number of manifest receivers skipped.
79    BroadcastQueue queue;   // the outbound queue handling this broadcast
broadcast_send_dispatch.jpg

参考从源码角度看广播

上一篇 下一篇

猜你喜欢

热点阅读