Android中间层分析1.【AMS】进程的启动-广播的注册和发送

1.广播的注册

public Intent registerReceiver(IApplicationThread caller, String callerPackage,
            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
        enforceNotIsolatedCaller("registerReceiver");
        ArrayList<Intent> stickyIntents = null;
        ProcessRecord callerApp = null;

        synchronized (this) {
            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
            if (rl == null) {
                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
                        userId, receiver);
                if (rl.app != null) {
                    rl.app.receivers.add(rl);
                } else {
                    try {
                        receiver.asBinder().linkToDeath(rl, 0);
                    } catch (RemoteException e) {
                        return sticky;
                    }
                    rl.linkedToDeath = true;
                }
                mRegisteredReceivers.put(receiver.asBinder(), rl);
            } else if (rl.uid != callingUid) {

            } else if (rl.pid != callingPid) {

            } else if (rl.userId != userId) {

            }
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                    permission, callingUid, userId);
            rl.add(bf);
            if (!bf.debugCheck()) {
                Slog.w(TAG, "==> For Dynamic broadcast");
            }
            mReceiverResolver.addFilter(bf);
            return sticky;
        }
    }

应用从应用注册的广播最终会到ams的registerReceiver接口。这个接口做了一下事情

  • 1、检查是否在mRegisteredReceivers列表里面
  • 2、如果没有就新建
  • 3、然后添加
    这个是常用的三段式代码
  • 4、后面是对BroadcastFilter进行生产 和添加。

2.广播的发送—broadcastIntentLocked

final int broadcastIntentLocked(ProcessRecord callerApp,
            String callerPackage, Intent intent, String resolvedType,
            IIntentReceiver resultTo, int resultCode, String resultData,
            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
        if (intent.getComponent() == null) {
            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
                for (int i = 0; i < users.length; i++) {
                    if (mUserController.hasUserRestriction(
                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
                        continue;
                    }
                    List<BroadcastFilter> registeredReceiversForUser =  mReceiverResolver.queryIntent(intent, resolvedType, false, users[i]);
                    if (registeredReceivers == null) {
                        registeredReceivers = registeredReceiversForUser;
                    } else if (registeredReceiversForUser != null) {
                        registeredReceivers.addAll(registeredReceiversForUser);
                    }
                }
            } else {
                registeredReceivers = mReceiverResolver.queryIntent(intent,resolvedType, false, userId);
            }
        }

        while (ir < NR) {
            if (receivers == null) {
                receivers = new ArrayList();
            }
            receivers.add(registeredReceivers.get(ir));
            ir++;
        }

        if ((receivers != null && receivers.size() > 0) || resultTo != null) {
            BroadcastQueue queue = broadcastQueueForIntent(intent);
            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
                    callerPackage, callingPid, callingUid, resolvedType,
                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
                    resultData, resultExtras, ordered, sticky, false, userId);
            r.enqueueTime = SystemClock.uptimeMillis();
            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
            if (!replaced) {
                queue.enqueueOrderedBroadcastLocked(r);
                queue.scheduleBroadcastsLocked();
            }
        } else {
            if (intent.getComponent() == null && intent.getPackage() == null
                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
            }
        }

        return ActivityManager.BROADCAST_SUCCESS;
    }

其实这个函数比较复杂的,我们删减来关键部分,看到黑体部分:
1、将intent所描述的发送的receiver在mReceiverResolver 去找到
2、当然接受者不仅仅是一个,有可能是多个。然后通过broadcastQueueForIntent 去拿到这个 queue
3、然后queue调用相应的函数处理。

3.广播的发送 — scheduleBroadcastsLocked

queue调用 scheduleBroadcastsLocked 函数进行广播发送的下一步工作。

public void scheduleBroadcastsLocked() {
        if (mBroadcastsScheduled) {
            return;
        }
        mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
        mBroadcastsScheduled = true;
    }


    private final class BroadcastHandler extends Handler {
        public BroadcastHandler(Looper looper) {
            super(looper, null, true);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BROADCAST_INTENT_MSG: {
                    processNextBroadcast(true);
                } break;
.....
            }
        }
    }

scheduleBroadcastsLocked 函数发送了消息,这个消息又调用了processNextBroadcast。

4.广播的发送 — processNextBroadcast

    final void processNextBroadcast(boolean fromMsg) {
        synchronized(mService) {
            BroadcastRecord r;
            mService.updateCpuStats();
            if (fromMsg) {
                mBroadcastsScheduled = false;
            }

            while (mParallelBroadcasts.size() > 0) {
                r = mParallelBroadcasts.remove(0);
                r.dispatchTime = SystemClock.uptimeMillis();
                r.dispatchClockTime = System.currentTimeMillis();
                final int N = r.receivers.size();

if (app != null && app.thread != null) {
                try {
                    app.addPackage(info.activityInfo.packageName,
                            info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
                    processCurBroadcastLocked(r, app);
                    return;
                } catch (RemoteException e) {

                } catch (RuntimeException e) {

                    return;
                }

            if ((r.curApp=mService.startProcessLocked(targetProcess,info.activityInfo.applicationInfo, true, r.intent.getFlags() | 			   Intent.FLAG_FROM_BACKGROUND,
                    "broadcast", r.curComponent,
                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
                            == null) {
                finishReceiverLocked(r, r.resultCode, r.resultData,r.resultExtras, r.resultAbort, false);
                scheduleBroadcastsLocked();//重新调度  然后又会回到  deliverToRegisteredReceiverLocked
                r.state = BroadcastRecord.IDLE;
                return;
            }

            mPendingBroadcast = r;
            mPendingBroadcastRecvIndex = recIdx;
        }
    }

processNextBroadcast 继续做广播发送的处理,如果目标在processCurBroadcastLocked
如果目标不存在 就会先建立process,然后重新调度scheduleBroadcastsLocked

private final void processCurBroadcastLocked(BroadcastRecord r,
        ProcessRecord app) throws RemoteException {
    r.receiver = app.thread.asBinder();
    r.curApp = app;
    app.curReceiver = r;
    app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
    mService.updateLruProcessLocked(app, false, null);
    mService.updateOomAdjLocked();
    r.intent.setComponent(r.curComponent);

    boolean started = false;
    try {

        mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
                                  PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);


        app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
                mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
                r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
                app.repProcState);

        started = true;
    } finally {

    }
}

processCurBroadcastLocked 里面就去调用scheduleReceiver 表现在应用层就是OnReceiver接收到广播。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沈万三djh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值