【源码分析】BroadcastReceiver启动源码分析

本文详细分析了Android动态BroadcastReceiver的注册流程,从registerReceiver()开始,经过ContextImpl到AMS的registerReceiver(),最终完成广播注册。在广播发送和接收过程中,通过sendBroadcast()、AMS的broadcastIntentLocked()以及handler的处理,最后到达receiver.onReceive()进行消息处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.实际使用流程
(1). 创建一个类继承自BroadcastReceiver
(2). 注册:静态注册,动态注册
(3). 消息发送

创建一个类:
public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        
    }
}

静态注册 在AndroidManifest.xml文件里面添加:
  <receiver android:name=".MyReceiver">
            <intent-filter>
                <action android:name="com.mirko.reveicer.LANUCH"/>
            </intent-filter>
        </receiver>

或者动态注册:
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.mirko.reveicer.LANUCH");
        registerReceiver(new MyReceiver(),filter);
        
发送消息:

		Intent intent1 = new Intent();
        intent1.setAction("com.mirko.reveicer.LANUCH");
        sendBroadcast(intent1);


  1. 广播注册过程

注册分为动态注册和静态注册,静态广播在应用安装时完成注册,下面看动态广播注册的流程:

registerReceiver() —> ContextImpl里面的registerReceiver()—>进入 registerReceiverInternal() 创建ReceiverDispatcher对象 返回InnerReceiver,同时调用AMS里面的registerReceiver()–> 进入AMS的registerReceiver()方法,储存InnerReceiver及IntentFilter 完成广播注册

/**
	mBase.registerReceiver执行的是 ContextImpl里面的registerReceiver()方法
**/
Override
public Intent registerReceiver(
    BroadcastReceiver receiver, IntentFilter filter) {
    return mBase.registerReceiver(receiver, filter);
}

@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. mPackageInfo.getReceiverDispatcher()方法获取IntentReceiver对象
	2. 通过跨进程注册广播,在AMS里面完成
**/
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
            IntentFilter filter, String broadcastPermission,
            Handler scheduler, Context context) {
        IIntentReceiver rd = null;
        if (receiver != null) {
            if (mPackageInfo != null && context != null) {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = mPackageInfo.getReceiverDispatcher(
                    receiver, context, scheduler,
                    mMainThread.getInstrumentation(), true); // 1.获取IntentReceiver对象
            } else {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = new LoadedApk.ReceiverDispatcher(
                        receiver, context, scheduler, null, true).getIIntentReceiver();
            }
        }
        try {
            final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName,
                    rd, filter, broadcastPermission, userId); //2.通过跨进程注册广播,在AMS里面完成
            if (intent != null) {
                intent.setExtrasClassLoader(getClassLoader());
                intent.prepareToEnterProcess();
            }
            return intent;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

/**
	进入getReceiverDispatcher()方法
	1.创建ReceiverDispatcher对象,构造方法中保存InnerReceiver和BroadcastReceiver
	2.返回InnerReceiver
**/
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
         Context context, Handler handler,
         Instrumentation instrumentation, boolean registered) {
     synchronized (mReceivers) {
         LoadedApk.ReceiverDispatcher rd = null;
         ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
         if (registered) {
             map = mReceivers.get(context);
             if (map != null) {
                 rd = map.get(r);
             }
         }
         if (rd == null) {
             rd = new ReceiverDispatcher(r, context, handler,
                     instrumentation, registered);  //创建ReceiverDispatcher对象
             if (registered) {
                 if (map == null) {
                     map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
                     mReceivers.put(context, map);
                 }
                 map.put(r, rd);
             }
         } else {
             rd.validate(context, handler);
         }
         rd.mForgotten = false;
         return rd.getIIntentReceiver();
     }
 }
/**
	进入AMS的registerReceiver()方法
	储存InnerReceiver及IntentFilter 完成广播注册
**/
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
        IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   ...
        mRegisteredReceivers.put(receiver.asBinder(), rl); //获取远程InnerReceiver存储
     
        BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                permission, callingUid, userId); //存储IntentFilter 
     
        rl.add(bf);
        if (!bf.debugCheck()) {
            Slog.w(TAG, "==> For Dynamic broadcast");
        }
        mReceiverResolver.addFilter(bf);
....
    }
}

  1. 广播的发送和接收

sendBroadcast() —> 进入ContextImpl里面sendBroadcast() —> 进入AMS里面broadcastIntent() —> 进入broadcastIntentLocked()方法 过滤广播—> 进入BroadcastQueue里 scheduleBroadcastsLocked() 来发送广播 —> handler发送一条消息----> handler接收消息调用processNextBroadcast()方法 —>进入processNextBroadcast()方法,遍历mParallelBroadcasts中存储的广播, 通过deliverToRegisteredReceiverLocked()方法发送出去 —>进入deliverToRegisteredReceiverLocked()方法,调用performReceiveLocked()方法 —> 进入performReceiveLocked()方法 —> 进入ApplicationThread,执行scheduleRegisteredReceiver() —> IIntentReceiver里performReceive()方法 —> 调用LoadedApk.ReceiverDispatcher里面的performReceive()—> LoadedApk.ReceiverDispatcher里面的performReceive() —> Args的run()方法 —> receiver.onReceive()接收到消息


/**
进入ContextWrapper里面sendBroadcast()
**/
  @Override
    public void sendBroadcast(Intent intent) {
        mBase.sendBroadcast(intent);
    }
/**
进入ContextImpl里面sendBroadcast()
进入AMS里面broadcastIntent()进行处理
**/
   @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());  //进入AMS
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

/**
	进入AMS里面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;
    }
}

/**
	进入broadcastIntentLocked()方法
	1.默认情况下广播不会发送给已经停止的应用,处于停止应用的两种情形:
	  (1). 安装未运行
	  (2). 手动或被其他应用停止
	2. 经过一系列的过滤,将符合条件的广播接收者添加到BroadcastQueue里面
	3. 通过BroadcastQueue里 scheduleBroadcastsLocked()来发送广播
**/
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) {
     intent = new Intent(intent);

     // By default broadcasts do not go to stopped apps.
     intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); //默认情况下广播不会发送给已经停止的应用
	....
	//经过一系列的过滤,将符合条件的广播接收者添加到BroadcastQueue里面
     if (!ordered && NR > 0) {
       // If we are not serializing this broadcast, then send the
       // registered receivers separately so they don't wait for the
       // components to be launched.
       if (isCallerSystem) {
           checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
                   isProtectedBroadcast, registeredReceivers);
       }
       final BroadcastQueue queue = broadcastQueueForIntent(intent);
       BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
               callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
               appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
               resultExtras, ordered, sticky, false, userId);
       if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
       final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
       if (!replaced) {
           queue.enqueueParallelBroadcastLocked(r);
           queue.scheduleBroadcastsLocked(); //广播发送
       }
       registeredReceivers = null;
       NR = 0;
   }
}


/**
	进入BroadcastQueue 里面scheduleBroadcastsLocked()
	发送一个handler消息
**/
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)); //发送一个handler消息
    mBroadcastsScheduled = true;
}

/**
	Handler处理广播的发送:processNextBroadcast()方法
**/
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: {
              if (DEBUG_BROADCAST) Slog.v(
                      TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
              processNextBroadcast(true);
          } break;
          case BROADCAST_TIMEOUT_MSG: {
              synchronized (mService) {
                  broadcastTimeoutLocked(true);
              }
          } break;
          case SCHEDULE_TEMP_WHITELIST_MSG: {
              DeviceIdleController.LocalService dic = mService.mLocalDeviceIdleController;
              if (dic != null) {
                  dic.addPowerSaveTempWhitelistAppDirect(UserHandle.getAppId(msg.arg1),
                          msg.arg2, true, (String)msg.obj);
              }
          } break;
      }
  }
}

/**
	进入processNextBroadcast()方法
    1.遍历mParallelBroadcasts中存储的广播, 通过deliverToRegisteredReceiverLocked()方法发送出去
**/
final void processNextBroadcast(boolean fromMsg) {

	....
	
    // First, deliver any non-serialized broadcasts right away.
   while (mParallelBroadcasts.size() > 0) { //无序广播存储在mParallelBroadcasts,遍历将其中广播发送给它的所有接收者
        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++) {
            Object target = r.receivers.get(i);
            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                    "Delivering non-ordered on [" + mQueueName + "] to registered "
                    + target + ": " + r);
            deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i); //具体发送实现,将广播发送给一个特定的接收者
        }
        addBroadcastToHistoryLocked(r);
        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
                + mQueueName + "] " + r);
    }

}

/**
	进入deliverToRegisteredReceiverLocked()方法
	调用performReceiveLocked()方法
**/
private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
         BroadcastFilter filter, boolean ordered, int index) {
         .....
         performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
         new Intent(r.intent), r.resultCode, r.resultData,
         r.resultExtras, r.ordered, r.initialSticky, r.userId);
         .....
 }

/**
	进入performReceiveLocked()方法
	1. app不为空,app.thread指向 ApplicationThread,执行scheduleRegisteredReceiver()方法
	2. app为空 执行receiver.performReceive()方法
**/

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) { //app不为空
       if (app.thread != null) {
           try {
               app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                       data, extras, ordered, sticky, sendingUser, app.repProcState); //进入ApplicationThread执行scheduleRegisteredReceiver()
           } catch (RemoteException ex) {
               // Failed to call into the process. It's either dying or wedged. Kill it gently.
               synchronized (mService) {
                   Slog.w(TAG, "Can't deliver broadcast to " + app.processName
                           + " (pid " + app.pid + "). Crashing it.");
                   app.scheduleCrash("can't deliver broadcast");
               }
               throw ex;
           }
       } else {
           throw new RemoteException("app.thread must not be null");
       }
   } else {
       receiver.performReceive(intent, resultCode, data, extras, ordered,
               sticky, sendingUser); //执行IIntentReceiver里performReceive()方法
   }
}

/**
	进入ActivityThread里ApplicationThread的 scheduleRegisteredReceiver()方法
	执行IIntentReceiver里performReceive()方法
**/
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()方法
 }
     
/**
	进入LoadedApk类ReceiverDispatcher类 ,IIntentReceiver的具体实现为 InnerReceiver 进入performReceive()方法
	1. 调用LoadedApk.ReceiverDispatcher里面的performReceive
**/
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 (intent == null) {
           Log.wtf(TAG, "Null intent received");
           rd = null;
       } else {
           rd = mDispatcher.get();
       }
       if (ActivityThread.DEBUG_BROADCAST) {
           int seq = intent.getIntExtra("seq", -1);
           Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
                   + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
       }
       if (rd != null) {
           rd.performReceive(intent, resultCode, data, extras,
                   ordered, sticky, sendingUser); //调用LoadedApk.ReceiverDispatcher里面的performReceive
       } else {
           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();
           }
       }
   }
}

/**
	进入LoadedApk.ReceiverDispatcher里面的performReceive
	1.创建Args对象
	2.通过mActivityThread.post(),最终进入Args的run()方法
**/

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); //1.创建Args对象
    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);
        }
    }
    if (intent == null || !mActivityThread.post(args)) { // 2. 通过mActivityThread.post(),最终进入Args的run()方法
        if (mRegistered && ordered) {
            IActivityManager mgr = ActivityManagerNative.getDefault();
            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                    "Finishing sync broadcast to " + mReceiver);
            args.sendFinished(mgr);
        }
    }
}

/**
	进入Args的run()方法
	
**/
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;
   if (receiver == null || intent == null || mForgotten) {
       if (mRegistered && ordered) {
           if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                   "Finishing null broadcast to " + mReceiver);
           sendFinished(mgr);
       }
       return;
   }

   Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
   try {
       ClassLoader cl =  mReceiver.getClass().getClassLoader();
       intent.setExtrasClassLoader(cl);
       intent.prepareToEnterProcess();
       setExtrasClassLoader(cl);
       receiver.setPendingResult(this);
       receiver.onReceive(mContext, intent); //执行onReceive()已经接收到广播
   } catch (Exception e) {
       if (mRegistered && ordered) {
           if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                   "Finishing failed broadcast to " + mReceiver);
           sendFinished(mgr);
       }
       if (mInstrumentation == null ||
               !mInstrumentation.onException(mReceiver, e)) {
           Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
           throw new RuntimeException(
               "Error receiving broadcast " + intent
               + " in " + mReceiver, e);
       }
   }
   
   if (receiver.getPendingResult() != null) {
       finish();
   }
   Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值