企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
下面来分析当应用进程收到广播后的处理流程,以动态接收者为例。 1. ApplicationThreadscheduleRegisteredReceiver函数分析 如前所述,AMS将通过scheduleRegisteredReceiver函数将广播交给应用进程,该函数代码如下: **ActivityThread.java::scheduleRegisteredReceiver** ~~~ public voidscheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, intresultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky) throws RemoteException { //又把receiver对象传了回来。还记得注册时传递的一个IIntentReceiver类型 //的对象吗? receiver.performReceive(intent,resultCode, dataStr, extras, ordered,sticky); } ~~~ 就本例而言,receiver对象的真实类型为LoadedApk.ReceiverDispatcher,来看它的performReceive函数,代码如下: **LoadedApk.java::performReceive** ~~~ public void performReceive(Intent intent, intresultCode, Stringdata, Bundle extras, boolean ordered, boolean sticky) { //Args是一个runnable对象 Args args= new Args(intent, resultCode, data, extras, ordered, sticky); // mActivityThread是一个Handler,还记得SDK提供的两个同名的registerReceiver //函数吗?如果没有传递Handler,则使用主线程的Handler。 if(!mActivityThread.post(args)) { if(mRegistered && ordered) { IActivityManager mgr = ActivityManagerNative.getDefault(); args.sendFinished(mgr); } } } ~~~ scheduleRegisteredReceiver最终向主线程的Handler投递了一个Args对象,这个对象的run函数将在主线程中被调用。 2. Args.run分析 **LoadedApk.java::Args.run** ~~~ publicvoid run() { finalBroadcastReceiver receiver = mReceiver; final boolean ordered = mOrdered; finalIActivityManager mgr = ActivityManagerNative.getDefault(); finalIntent intent = mCurIntent; mCurIntent = null; ...... try { //获取ClassLoader对象,千万注意,此处并没有通过反射机制创建一个广播接收者, //对于动态接收者来说,在注册前就已经创建完毕 ClassLoadercl = mReceiver.getClass().getClassLoader(); intent.setExtrasClassLoader(cl); setExtrasClassLoader(cl); receiver.setPendingResult(this);//设置pendingResult //调用该动态接收者的onReceive函数 receiver.onReceive(mContext, intent); }...... //调用finish完成工作 if(receiver.getPendingResult() != null) finish(); } ~~~ Finish的代码很简单,此处不在赘述,在其内部会通过sendFinished函数调用AMS的finishReceiver函数,以通知AMS。 3. AMS的finishReceiver函数分析 不论ordered还是非orded广播,AMS的finishReceiver函数都会被调用,它的代码如下: **ActivityManagerService.java::finishReceiver** ~~~ public void finishReceiver(IBinder who, intresultCode, String resultData, Bundle resultExtras, boolean resultAbort) { ...... booleandoNext; final long origId =Binder.clearCallingIdentity(); synchronized(this){ //判断是否还需要继续调度后续的广播发送 doNext = finishReceiverLocked( who, resultCode, resultData, resultExtras, resultAbort, true); } if(doNext) { //发起下一次广播发送 processNextBroadcast(false); } trimApplications(); Binder.restoreCallingIdentity(origId); } ~~~ 由以上代码可知,finishReceiver将根据情况调度下一次广播发送。