美文网首页原理解析Android进阶之旅Android开发
发送广播(sendBroadcast)的分析

发送广播(sendBroadcast)的分析

作者: umbrella1 | 来源:发表于2017-06-16 19:13 被阅读174次

    sendBroadcast通过Binder进程间通信机制发给ActivityManagerService进程,ActivityManagerService会找出相应的广播接收器,放到自己的消息队列中去,对广播的异步分发,通过binder进程间通信机制分发给注册广播进程接收器LoadedApk.ReceiverDispatcher,
    ReceiverDispatcher的内部类Args在接收广播进程的UI线程里面处理注册的BroadcastReceiver实例的onReceive函数
    Step1:ContextImpl.broadcastIntent

    Intent intent = new Intent("cn.umbrella.chanage");
    intent.putExtra("key","vaule");
    sendBroadcast(intent);
    class ContextImpl extends Context {
        @Override
        public void sendBroadcast(Intent intent) {
            warnIfCallingFromSystemProcess();
            String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
            try {
                intent.prepareToLeaveProcess(this);
                ActivityManagerNative.getDefault().broadcastIntent(
                        mMainThread.getApplicationThread(), intent, resolvedType, null,
                        Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
                        getUserId());
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }
    

    Step2:ActivityManagerProxy.broadcastIntent:

    class ActivityManagerProxy implements IActivityManager{
        public int broadcastIntent(IApplicationThread caller,
                Intent intent, String resolvedType, IIntentReceiver resultTo,
                int resultCode, String resultData, Bundle map,
                String[] requiredPermissions, int appOp, Bundle options, boolean serialized,
                boolean sticky, int userId) throws RemoteException
        {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IActivityManager.descriptor);
            data.writeStrongBinder(caller != null ? caller.asBinder() : null);
            intent.writeToParcel(data, 0);
            data.writeString(resolvedType);
            data.writeStrongBinder(resultTo != null ? resultTo.asBinder() : null);
            data.writeInt(resultCode);
            data.writeString(resultData);
            data.writeBundle(map);
            data.writeStringArray(requiredPermissions);
            data.writeInt(appOp);
            data.writeBundle(options);
            data.writeInt(serialized ? 1 : 0);
            data.writeInt(sticky ? 1 : 0);
            data.writeInt(userId);
            mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);
            reply.readException();
            int res = reply.readInt();
            reply.recycle();
            data.recycle();
            return res;
        }
    }
    

    要传递的参数封装好,然后通过Binder驱动程序进入到ActivityManagerService进程的broadcastIntent函数中
    Step3:ActivityManagerService.broadcastIntent及broadcastIntent:

    public final class ActivityManagerService extends ActivityManagerNative
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        public final int broadcastIntent(IApplicationThread caller,
                Intent intent, String resolvedType, IIntentReceiver resultTo,
                int resultCode, String resultData, Bundle resultExtras,
                String[] requiredPermissions, int appOp, Bundle bOptions,
                boolean serialized, boolean sticky, int userId) {
            enforceNotIsolatedCaller("broadcastIntent");
            synchronized(this) {
                intent = verifyBroadcastLocked(intent);
    
                final ProcessRecord callerApp = getRecordForAppLocked(caller);
                final int callingPid = Binder.getCallingPid();
                final int callingUid = Binder.getCallingUid();
                final long origId = Binder.clearCallingIdentity();
                int res = broadcastIntentLocked(callerApp,
                        callerApp != null ? callerApp.info.packageName : null,
                        intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
                        requiredPermissions, appOp, bOptions, serialized, sticky,
                        callingPid, callingUid, userId);
                Binder.restoreCallingIdentity(origId);
                return res;
            }
        }
    }
    
    public final class ActivityManagerService extends ActivityManagerNative
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        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) {
            ....
            // Figure out who all will receive this broadcast.
            List receivers = null;
            List<BroadcastFilter> registeredReceivers = null;
            // Need to resolve the intent to interested receivers...
            ...
                    registeredReceivers = mReceiverResolver.queryIntent(intent,
                            resolvedType, false, userId);
            ....
            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);
                boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
                if (!replaced) {
                    queue.enqueueOrderedBroadcastLocked(r);
                    queue.scheduleBroadcastsLocked();
                }
            } 
            ....
            return ActivityManager.BROADCAST_SUCCESS;
        }
    }
    

    根据intent找出相应的广播接收器,BroadcastQueue queue.enqueueOrderedBroadcastLocked(r)把所有相应的广播接收器放到数组里面,queue.scheduleBroadcastsLocked再做广播消息处理.
    Step4:BroadcastQueue.scheduleBroadcastsLocked、
    Step5:mHandler.sendMessage

    public final class BroadcastQueue {
        final BroadcastHandler mHandler;
        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;
                    ...
                }
            }
        }
        public void scheduleBroadcastsLocked() {
            ...
            if (mBroadcastsScheduled) {
                return;
            }      
            mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
            mBroadcastsScheduled = true;
        }
    }
    

    Step6:BroadcastQueue.processNextBroadcast:

    public final class BroadcastQueue {
        final void processNextBroadcast(boolean fromMsg) {
            synchronized(mService) {
                BroadcastRecord r;
                ...
                // First, deliver any non-serialized broadcasts right away.
                while (mParallelBroadcasts.size() > 0) {
                    r = mParallelBroadcasts.remove(0);
                    r.dispatchTime = SystemClock.uptimeMillis();
                    r.dispatchClockTime = System.currentTimeMillis();
                    final int N = r.receivers.size();
                    for (int i=0; i《N; i++) {
                        Object target = r.receivers.get(i);
                        deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
                    }
                    addBroadcastToHistoryLocked(r);
                }
                ...
            }
        }
    }
    

    while循环中的for循环把这个广播发送给每一个订阅了该广播的接收器
    Step 7:BroadcastQueue .deliverToRegisteredReceiverLocked

    public final class BroadcastQueue {
        private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
                BroadcastFilter filter, boolean ordered, int index) {
            boolean skip = false;
            ...
            try {
                ...
                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                         new Intent(r.intent), r.resultCode, r.resultData,
                         r.resultExtras, r.ordered, r.initialSticky, r.userId);
                
                ...
            } catch (RemoteException e) {
                ...
            }
        }
    }
    

    检查广播发送和接收的权限,然后performReceiveLocked处理。
    Step 8:BroadcastQueue .performReceiveLocked:

    public final class BroadcastQueue {
        void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
                Intent intent, int resultCode, String data, Bundle extras,
                boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
            if (app != null) {
                if (app.thread != null) {
                    ..
                        app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                                data, extras, ordered, sticky, sendingUser, app.repProcState);
                   ...
            } else {
                ...
            }
        }
    }
    

    ProcessRecord app,进程记录块,是接收广播的进程,app.thread是一个Binder远程对象,它的类型是ApplicationThreadProxy。
    Step 9:ApplicationThreadProxy.performReceiveLocked:

    class ApplicationThreadProxy implements IApplicationThread {
        void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
                Intent intent, int resultCode, String data, Bundle extras,
                boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
            if (app != null) {
                if (app.thread != null) {
                    ..
                        app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                                data, extras, ordered, sticky, sendingUser, app.repProcState);
                   ...
            } else {
                ...
            }
        }
    }
    

    通过Binder驱动程序就进入到接收广播的进程的ApplicationThread.scheduleRegisteredReceiver函数:
    Step10:ApplicationThread.scheduleRegisteredReceiver

    public final class ActivityThread {
        private class ApplicationThread extends ApplicationThreadNative {
            public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
                    int resultCode, String dataStr, Bundle extras, boolean ordered,
                    boolean sticky, int sendingUser, int processState) throws RemoteException {
                updateProcessState(processState, false);
                receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
                        sticky, sendingUser);
            }
        }
    }
    

    其中receiver就是LoadedApk.ReceiverDispatcher.InnerReceiver
    Step 11:ReceiverDispatcher.InnerReceiver.performReceive:

    public final class LoadedApk {
        ...
        static final class ReceiverDispatcher {
            final static class InnerReceiver extends IIntentReceiver.Stub {
                final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
                final LoadedApk.ReceiverDispatcher mStrongRef;
                InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
                    mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
                    mStrongRef = strong ? rd : null;
                }
                @Override
                public void performReceive(Intent intent, int resultCode, String data,
                        Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                    final LoadedApk.ReceiverDispatcher rd;
                    ...
                    if (rd != null) {
                        rd.performReceive(intent, resultCode, data, extras,
                                ordered, sticky, sendingUser);
                    } 
                    ...
                }
            }
    }
    

    调用LoadedApk类里面的一个内部类ReceiverDispatcher的performReceive函数来处理
    Step 12:ReceiverDispatcher.performReceive:

    public final class LoadedApk {
        static final class ReceiverDispatcher {
            public void performReceive(Intent intent, int resultCode, String data,
                    Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                final Args args = new Args(intent, resultCode, data, extras, ordered,
                        sticky, sendingUser);
                ...
                if (intent == null || !mActivityThread.post(args)) {
                    if (mRegistered && ordered) {
                       ...
                    }
                }
            }
        }
    }
    

    mActivityThread是handler,post放到消息队列中,到接收广播的UI线程里实行Runnable 的run:
    Step 12:mActivityThread.post(args):

    public final class LoadedApk {
        ...
        static final class ReceiverDispatcher {
            final class Args extends BroadcastReceiver.PendingResult implements Runnable {
                private Intent mCurIntent;
                private final boolean mOrdered;
                private boolean mDispatched;
                ...
                public void run() {
                    final BroadcastReceiver receiver = mReceiver;
                    final boolean ordered = mOrdered;
                    ...
                    try {
                        ClassLoader cl =  mReceiver.getClass().getClassLoader();
                        intent.setExtrasClassLoader(cl);
                        intent.prepareToEnterProcess();
                        setExtrasClassLoader(cl);
                        receiver.setPendingResult(this);
                        receiver.onReceive(mContext, intent);
                    } catch (Exception e) {
                        ...
                    }
                    ...
                }
            }
        }   
    }
    

    这样就实行到onReceive:
    Step 13:TestReceiver.onReceive:

    public class TestReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
        }
    }
    

    相关文章

      网友评论

        本文标题:发送广播(sendBroadcast)的分析

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