美文网首页android之基础学习攻克
广播相关学习-数据结构

广播相关学习-数据结构

作者: weiinter105 | 来源:发表于2018-12-21 18:56 被阅读0次

    动态注册广播相关的

    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

    参考从源码角度看广播

    相关文章

      网友评论

        本文标题:广播相关学习-数据结构

        本文链接:https://www.haomeiwen.com/subject/afpvkqtx.html