廣播的發送與接收

之前看過 Activity 的啓動過程,也看過 Service 啓動過程,今天又重新對廣播的發送和接收過程做一個源碼的瞭解和查看。

1. registerReceiver

        MyBroadcastReceiver mBroadcastReceiver  = new MyBroadcastReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.example.qq");
        registerReceiver(mBroadcastReceiver, filter);

我們通常會自定義一個類 MyBroadcastReceiver extends BroadcastReceiver.

跟隨 registerReceiver 我們走到第二個步驟:

1.1 ContextImpl#registerReceiver

@Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return registerReceiver(receiver, filter, null, null);
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler) {
        return registerReceiverInternal(receiver, getUserId(),
                filter, broadcastPermission, scheduler, getOuterContext());
    }

最終會執行到 registerReceiverInternal() 這個方法,緊接着到第三個步驟:

1.2. ContextImpl#registerReceiverInternal

private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
            IntentFilter filter, String broadcastPermission,
            Handler scheduler, Context context) {
        IIntentReceiver rd = null;//這個IItentReceiver 是一個aidl ,一個Binder
        if (receiver != null) {
            if (mPackageInfo != null && context != null) {
                //這個爲null, 因爲前面我們傳的是null,獲取主線程的一個handler
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = mPackageInfo.getReceiverDispatcher(
                    receiver, context, scheduler,
                    mMainThread.getInstrumentation(), true);
            } else {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = new LoadedApk.ReceiverDispatcher(
                        receiver, context, scheduler, null, true).getIIntentReceiver();
            }
        }
        try {
            //這裏我們仔細查看,這裏對比我們平時寫的Aidl
            final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName,
                    rd, filter, broadcastPermission, userId);
            if (intent != null) {
                intent.setExtrasClassLoader(getClassLoader());
                intent.prepareToEnterProcess();
            }
            return intent;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

對於 :

final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName,
                    rd, filter, broadcastPermission, userId);

ActivityManagerNative.getDefault() 獲取到一個 IActivityManager 對象,此時我發現,我進入一個類名爲:
ActivityManagerNative 的一個類中。

這裏補充 IActivityManager ,它是一個 aidl 文件,如下:

public interface IActivityManager extends IInterface {
    ....
}

這時讓我想起我們以前寫 aidl 的示例時,系統自動幫我們生成的文件,下面我們來對比一下,可以加深對 aidl 的理解:

自動生成的aidl文件
我們創建一個 IMyAidl.aidl 文件,編譯系統會自動生成大致如下:

public interface IMyAidl extends android.os.IInterface{
    
    public static abstract class Stub extends android.os.Binder implements xx.IMyAidl{
        public Stub(){
            this.attachInterface(this, DESCRIPTOR);
        }
        public static com.example.service.bean.IMyAidl asInterface(android.os.IBinder obj) {
           xxx...
            return new com.example.service.bean.IMyAidl.Stub.Proxy(obj);
      }
        @Override
        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel            reply, int flags) throws android.os.RemoteException {
             case TRANSACTION_addPerson: {//其中一個方法
                                data.enforceInterface(DESCRIPTOR);
                                com.example.service.bean.Person _arg0;
                                if ((0 != data.readInt())) {
                                    _arg0 = com.example.service.bean.Person.CREATOR.createFromParcel(data);
                                } else {
                                    _arg0 = null;
                                }
                                this.addPerson(_arg0);
                                reply.writeNoException();
                                return true;
                            }
        }
    }
    
     private static class Proxy implements xx.IMyAidl {
            private android.os.IBinder mRemote;

            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }
         @Override
            public void addPerson(com.example.service.bean.Person person) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    if ((person != null)) {
                        _data.writeInt(1);
                        person.writeToParcel(_data, 0);
                    } else {
                        _data.writeInt(0);
                    }
                    //調用遠程binder,transact
                    mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }
     }
    static final int TRANSACTION_addPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}

其中我們最主要關心的是 StubProxy .那麼類比下 ActivityManagerNative 類(我簡化了一下):

public abstract class ActivityManagerNative extends Binder implements IActivityManager{
    
    class ActivityManagerProxy implements IActivityManager{
        public ActivityManagerProxy(IBinder remote) {
           mRemote = remote;
        }
    }
}

你會發現這與系統幫我們自動生成文件的結構有異曲同工之處,那麼在這裏:

ActivityManagerNative ------ 對應的就是 Stub

ActivityManagerProxy ------- 對應的就是 Proxy

那麼真正實現 ActivityManagerNative 又是誰呢,其實就是 ActivityManagerService , 可看到:

public final class ActivityManagerService extends ActivityManagerNative ...{
    ...
}

這樣的話,我們回到之前的那個步驟:

final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName,
                    rd, filter, broadcastPermission, userId);

這裏我們就知道了 這裏調用 ActivityManagerNative.getDefault().registerReceiver 其實就是調用 ActivityManagerService.registerReceiver() 方法。

還有一個補充的是 mMainThread.getApplicationThread() 實際上對應的是 ApplicationThread

1.3 ActivityManagerService#registerReceiver

這個方法有點長,不過沒關係,分塊看就行:

public Intent registerReceiver(IApplicationThread caller, String callerPackage,
            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
        enforceNotIsolatedCaller("registerReceiver");
        ArrayList<Intent> stickyIntents = null;
        ProcessRecord callerApp = null;
        int callingUid;
        int callingPid;
        synchronized(this) {
            //這個肯定不爲null
            if (caller != null) {
                //表示啓動app的進程信息保存在ProcessRecord類型的對象中
                callerApp = getRecordForAppLocked(caller);
                if (callerApp == null) {
                    throw new SecurityException(
                            "Unable to find app for caller " + caller
                            + " (pid=" + Binder.getCallingPid()
                            + ") when registering receiver " + receiver);
                }
                ....
            } else {
              ...
            }

            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
           ....  

            // Collect stickies of users
            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
            //遍歷 action 
            while (actions.hasNext()) {
                String action = actions.next();
                for (int id : userIds) {
                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
                    if (stickies != null) {
                        ArrayList<Intent> intents = stickies.get(action);
                        if (intents != null) {
                            if (stickyIntents == null) {
                                stickyIntents = new ArrayList<Intent>();
                            }
                            stickyIntents.addAll(intents);
                        }
                    }
                }
            }
        }

        ArrayList<Intent> allSticky = null;
        if (stickyIntents != null) {
          final ContentResolver resolver = mContext.getContentResolver();
            // Look for any matching sticky broadcasts...
            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
                Intent intent = stickyIntents.get(i);
                // If intent has scheme "content", it will need to acccess
                // provider that needs to lock mProviderMap in ActivityThread
                // and also it may need to wait application response, so we
                // cannot lock ActivityManagerService here.
                if (filter.match(resolver, intent, true, TAG) >= 0) {
                    if (allSticky == null) {
                        allSticky = new ArrayList<Intent>();
                    }
                    allSticky.add(intent);
                }
            }
        }

        // The first sticky in the list is returned directly back to the client.
        Intent sticky = allSticky != null ? allSticky.get(0) : null;
        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
        if (receiver == null) {
            return sticky;
        }

        synchronized (this) {
            ...
            //獲取接收者的一個集合 ReceiverList
            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);
            } 
            ...
            //IntentFilter 相關的
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                    permission, callingUid, userId);
            rl.add(bf);
            if (!bf.debugCheck()) {
                Slog.w(TAG, "==> For Dynamic broadcast");
            }
            //最後添加到了mReceiverResolver 中,最後發送廣播也是從這裏面去取
            ///**
            //* Keeps track of all IIntentReceivers that have been registered for broadcasts.
             // * Hash keys are the receiver IBinder, hash value is a ReceiverList.
             //*/
             //final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
            mReceiverResolver.addFilter(bf);

            // Enqueue broadcasts for all existing stickies that match
            // this filter.
            if (allSticky != null) {
                ArrayList receivers = new ArrayList();
                receivers.add(bf);

                final int stickyCount = allSticky.size();
                for (int i = 0; i < stickyCount; i++) {
                    Intent intent = allSticky.get(i);
                    //得到一個接收此廣播的隊列 BroadcastQueue
                    BroadcastQueue queue = broadcastQueueForIntent(intent);
                    //廣播的信息封裝在一個BroadcastRecord 對象中
                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
                            null, 0, null, null, false, true, true, -1);
                    // 這裏可以認爲是一個入隊操作,就像Handler 中的 Message中一樣        
                    queue.enqueueParallelBroadcastLocked(r);
                    //調用 scheduleBroadcastsLocked
                    queue. scheduleBroadcastsLocked();
                }
            }
            return sticky;
        }
    }

2. sendBoradcastReceiver

        Intent intent = new Intent();
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction("com.example.qq");
        sendBroadcast(intent);

2.1 ContextImpl#sendBroadcast

@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();
        }
    }

這裏我們就知道 ActivityManagerNative.getDefault() 實際上可以認爲是 ActivityManagerService ,調用 broadcastIntent 方法。

2.2 ActivityManagerService#broadcastIntent

 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;
       }
   }

2.3 ActivityManagerService#broadcastIntentLocked

這個裏面方法挺長的

....
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);

            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
                    + ": prev had " + queue.mOrderedBroadcasts.size());
            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
                    "Enqueueing broadcast " + r.intent.getAction());

            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
            if (!replaced) {
                queue.enqueueOrderedBroadcastLocked(r);
                queue.scheduleBroadcastsLocked();
            }
            ....

2.4 BroadcastQueue#scheduleBroadcastsLocked

public void scheduleBroadcastsLocked() {
        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
                + mQueueName + "]: current="
                + mBroadcastsScheduled);

        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: {
                    if (DEBUG_BROADCAST) Slog.v(
                            TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
                    processNextBroadcast(true);
                } break;
                ...

2.5 BroadcastQueue#processNextBroadcast

這個方法也比較長,挑一些重點的看下:

final void processNextBroadcast(boolean fromMsg) {
    ...
    // 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();
                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
                        + mQueueName + "] " + r);
                for (int i=0; i<N; i++) {
                    //取出一個接收者target
                    Object target = r.receivers.get(i);
                    if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                            "Delivering non-ordered on [" + mQueueName + "] to registered "
                            + target + ": " + r);
                    //又調用   deliverToRegisteredReceiverLocked      
                     deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
                }
                addBroadcastToHistoryLocked(r);
                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
                        + mQueueName + "] " + r);
            }
}

2.6 BroadcastQueue#deliverToRegisteredReceiverLocked

 private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
            BroadcastFilter filter, boolean ordered, int index) {
            //根據上面所傳的ordered 爲false 表示無序廣播
            ....
            if (ordered) {//這個表示有序廣播
                r.receiver = filter.receiverList.receiver.asBinder();
                r.curFilter = filter;
                filter.receiverList.curBroadcast = r;
                r.state = BroadcastRecord.CALL_IN_RECEIVE;
                if (filter.receiverList.app != null) {
                    // Bump hosting application to no longer be in background
                    // scheduling class.  Note that we can't do that if there
                    // isn't an app...  but we can only be in that case for
                    // things that directly call the IActivityManager API, which
                    // are already core system stuff so don't matter for this.
                    r.curApp = filter.receiverList.app;
                    
                    filter.receiverList.app.curReceiver = r;
                    mService.updateOomAdjLocked(r.curApp);
                }
            }
        try {
            
            //關於isFullBackup  Process is currently hosting a backup agent for backup or restore
             //public boolean inFullBackup;默認是false
            if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
                // Skip delivery if full backup in progress
                // If it's an ordered broadcast, we need to continue to the next receiver.
                if (ordered) {
                    skipReceiverLocked(r);
                }
            } else {
                //到這裏
                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                        new Intent(r.intent), r.resultCode, r.resultData,
                        r.resultExtras, r.ordered, r.initialSticky, r.userId);
            }
            if (ordered) {
                r.state = BroadcastRecord.CALL_DONE_RECEIVE;
            }
        } catch (RemoteException e) {
        ....
    }

2.7 BroadcastQueue#performReceiveLocked

void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
            Intent intent, int resultCode, String data, Bundle extras,
            boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
        // Send the intent to the receiver asynchronously using one-way binder calls.
        ....
        if (app != null) {
            if (app.thread != null) {
                 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                            data, extras, ordered, sticky, sendingUser, app.repProcState);
            
       }
        ....    
    }

app.threadApplicationThread , 此時迴歸到了客戶端進程,ApplicationThread 中了

2.8 ApplicationThread#scheduleRegisteredReceiver

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);
        }

這裏調用了 IIntentReceiver#performReceive 方法, 其中 IIntentReceiver 是一個 aidl ,如下:
/framworkds/base/core/java/android/content/IIntentReceiver.aidl

/**
 * System private API for dispatching intent broadcasts.  This is given to the
 * activity manager as part of registering for an intent broadcasts, and is
 * called when it receives intents.
 *
 * {@hide}
 */
oneway interface IIntentReceiver {
    void performReceive(in Intent intent, int resultCode,
            String data, in Bundle extras, boolean ordered, boolean sticky);
}

既然是 aidl 肯定有最終實現者,全局搜索發現:

InnerReceiver 是最終實現者,是ReceiverDispatcher 的一個靜態內部類,在 LoadedApk.java 文件中

LoadedApk#ReceiverDispatcher

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;
            }

            //這裏是最終執行的方法 performReceive
            @Override
            public void performReceive(Intent intent, int resultCode, String data,
                    Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                final LoadedApk.ReceiverDispatcher rd;
                if (intent == null) {
                    Log.wtf(TAG, "Null intent received");
                    rd = null;
                } else {
                    rd = mDispatcher.get();
                }
                ...
                if (rd != null) {
                //不爲null  執行到這裏 
                    rd.performReceive(intent, resultCode, data, extras,
                            ordered, sticky, sendingUser);
                } else {
                    // The activity manager dispatched a broadcast to a registered
                    // receiver in this process, but before it could be delivered the
                    // receiver was unregistered.  Acknowledge the broadcast on its
                    // behalf so that the system's broadcast sequence can continue.
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing broadcast to unregistered receiver");
                    IActivityManager mgr = ActivityManagerNative.getDefault();
                    try {
                        if (extras != null) {
                            extras.setAllowFds(false);
                        }
                        mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                }
            }
        }

2.9 ReceiverDispatcher#performReceive

public void performReceive(Intent intent, int resultCode, String data,
                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                //將信息封裝到Args 中
            final Args args = new Args(intent, resultCode, data, extras, ordered,
                    sticky, sendingUser);
            if (intent == null) {
                Log.wtf(TAG, "Null intent received");
            } else {
                if (ActivityThread.DEBUG_BROADCAST) {
                    int seq = intent.getIntExtra("seq", -1);
                    Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
                            + " seq=" + seq + " to " + mReceiver);
                }
            }
            //這裏 IActivityThread 一個Handler 類型。post了一條runnable,
            if (intent == null || !mActivityThread.post(args)) {
                if (mRegistered && ordered) {
                    IActivityManager mgr = ActivityManagerNative.getDefault();
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing sync broadcast to " + mReceiver);
                    args.sendFinished(mgr);
                }
            }
        }

這裏補充下 : mActivityThread 賦值是在構造方法中賦值的:

ReceiverDispatcher(BroadcastReceiver receiver, Context context,
                Handler activityThread, Instrumentation instrumentation,
                boolean registered) {
          ...
            mIIntentReceiver = new InnerReceiver(this, !registered);
            .... 這裏也能猜到 是ActivityThread 中的那個H
            mActivityThread = activityThread;
           ...
        }

這裏就可以看 Args ,一個 Runnable, 看下 run 方法:

final class Args extends BroadcastReceiver.PendingResult implements Runnable {
    public void run() {
                final BroadcastReceiver receiver = mReceiver;
                final boolean ordered = mOrdered;
                
                if (ActivityThread.DEBUG_BROADCAST) {
                    int seq = mCurIntent.getIntExtra("seq", -1);
                    Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
                            + " seq=" + seq + " to " + mReceiver);
                    Slog.i(ActivityThread.TAG, "  mRegistered=" + mRegistered
                            + " mOrderedHint=" + ordered);
                }
                
                final IActivityManager mgr = ActivityManagerNative.getDefault();
                final Intent intent = mCurIntent;
                if (intent == null) {
                    Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched);
                }

                mCurIntent = null;
                mDispatched = true;
                ...

                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
                try {
                    //獲取receiver的類加載類加載
                    ClassLoader cl =  mReceiver.getClass().getClassLoader();
                    intent.setExtrasClassLoader(cl);
                    intent.prepareToEnterProcess();
                    setExtrasClassLoader(cl);
                    receiver.setPendingResult(this);
                    //這裏回調receiver 的onReceive 方法
                    receiver.onReceive(mContext, intent);
                } catch (Exception e) {
                   ...
                }
            ...
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
    
}

這樣我們就可以在 sendBroadcast 時,在 Receiver 方法中收到相應的回調了,完畢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章