最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

android framework開發(fā)之廣播broadcast源碼分析-千里馬

2023-09-29 13:50 作者:千里馬學(xué)框架  | 我要投稿

hi,粉絲朋友大家好! ?

今天是中秋節(jié),希望大家中秋國(guó)慶快樂,也祝大家新的一年技術(shù)進(jìn)步,與千里馬共同學(xué)習(xí)共同進(jìn)步,共同升職加薪。今天要給大家分享的一個(gè)課題是大家都很熟悉的廣播。 這里將要分為2個(gè)部分來對(duì)廣播進(jìn)行分析:


在這里插入圖片描述

更多framework干貨課程內(nèi)容點(diǎn)擊這里:


需要的可以加馬哥微信(androidframework007)獲取優(yōu)惠及1v1的技術(shù)答疑


?1、廣播發(fā)送部分 一般我們正常使用發(fā)送廣播都會(huì)有調(diào)用一個(gè)context的sendBroadcas,方法原型如下:?public?void?sendBroadcast(Intent?intent)

這里我們一般就是只想要傳遞一個(gè)intent參數(shù)既可以,這里調(diào)用context方法,其實(shí)和上一節(jié)講解service一樣,最后都會(huì)調(diào)用到ContextImpl方法中的sendBroadcast:

????@Override
????public?void?sendBroadcast(Intent?intent)?{
????????warnIfCallingFromSystemProcess();
????????String?resolvedType?=?intent.resolveTypeIfNeeded(getContentResolver());
????????try?{
????????????intent.prepareToLeaveProcess(this);//只是對(duì)intent進(jìn)行一下預(yù)處理
????????????ActivityManager.getService().broadcastIntent(
????????????????????mMainThread.getApplicationThread(),?intent,?resolvedType,?null,
????????????????????Activity.RESULT_OK,?null,?null,?null,?AppOpsManager.OP_NONE,?null,?false,?false,
????????????????????getUserId());//最后調(diào)用到了AMS里面的broadcastIntent
????????}?catch?(RemoteException?e)?{
????????????throw?e.rethrowFromSystemServer();
????????}
????}

下面來看AMS的broadcastIntent方法,這里我們暫時(shí)只分析最常見的一類平行廣播,不看有序部分,感興趣可以自己分析:

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?realCallingUid,
????????????int?realCallingPid,?int?userId,?boolean?allowBackgroundActivityStarts)
?{
?????//省略部分
?//?Figure?out?who?all?will?receive?this?broadcast.
????????List?receivers?=?null;
????????List<BroadcastFilter>?registeredReceivers?=?null;//獲取接受者的List
????????//?Need?to?resolve?the?intent?to?interested?receivers...
????????if?((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
?????????????????==?0)?{
????????????receivers?=?collectReceiverComponents(intent,?resolvedType,?callingUid,?users);
????????}
????????if?(intent.getComponent()?==?null)?{
????????//具體根據(jù)intent進(jìn)行filter獲取接受者的List
????????????if?(userId?==?UserHandle.USER_ALL?&&?callingUid?==?SHELL_UID)?{
????????????????//?Query?one?target?user?at?a?time,?excluding?shell-restricted?users
????????????????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?/*defaultOnly*/,?users[i]);
????????????????????if?(registeredReceivers?==?null)?{
????????????????????????registeredReceivers?=?registeredReceiversForUser;
????????????????????}?else?if?(registeredReceiversForUser?!=?null)?{
????????????????????????registeredReceivers.addAll(registeredReceiversForUser);
????????????????????}
????????????????}
????????????}?else?{
????????????????registeredReceivers?=?mReceiverResolver.queryIntent(intent,
????????????????????????resolvedType,?false?/*defaultOnly*/,?userId);
????????????}
????????}
????????
???????????????if?(!ordered?&&?NR?>?0)?{
??????????
????????????final?BroadcastQueue?queue?=?broadcastQueueForIntent(intent);
????????????BroadcastRecord?r?=?new?BroadcastRecord(queue,?intent,?callerApp,
????????????????????callerPackage,?callingPid,?callingUid,?callerInstantApp,?resolvedType,
????????????????????requiredPermissions,?appOp,?brOptions,?registeredReceivers,?resultTo,
????????????????????resultCode,?resultData,?resultExtras,?ordered,?sticky,?false,?userId,
????????????????????allowBackgroundActivityStarts,?timeoutExempt);//構(gòu)造出一個(gè)BroadcastRecord
????????????if?(DEBUG_BROADCAST)?Slog.v(TAG_BROADCAST,?"Enqueueing?parallel?broadcast?"?+?r);
????????????final?boolean?replaced?=?replacePending
????????????????????&&?(queue.replaceParallelBroadcastLocked(r)?!=?null);
????????????//?Note:?We?assume?resultTo?is?null?for?non-ordered?broadcasts.
????????????if?(!replaced)?{
????????????????queue.enqueueParallelBroadcastLocked(r);//插入平行廣播隊(duì)列
????????????????queue.scheduleBroadcastsLocked();
????????????}
????????????registeredReceivers?=?null;
????????????NR?=?0;
????????}
//省略部分
????????return?ActivityManager.BROADCAST_SUCCESS;
????}

接下來看看最重要的enqueueParallelBroadcastLocked和scheduleBroadcastsLocked部分:

?????public?void?enqueueParallelBroadcastLocked(BroadcastRecord?r)?{
????????mParallelBroadcasts.add(r);//這里動(dòng)作很簡(jiǎn)單就是把BroadcastRecord插入到mParallelBroadcasts這個(gè)list
????????enqueueBroadcastHelper(r);
????}

接下來看scheduleBroadcastsLocked:

????public?void?scheduleBroadcastsLocked()?{
????????//省略部分
????????mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG,?this));
????????mBroadcastsScheduled?=?true;
????}

這里其實(shí)就只是發(fā)送了一個(gè)BROADCAST_INTENT_MSG消息: 來看看對(duì)這個(gè)消息的處理

????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?["
????????????????????????????+?mQueueName?+?"]");
????????????????????processNextBroadcast(true);//調(diào)用了processNextBroadcast方法
????????????????}?break;
????????????????case?BROADCAST_TIMEOUT_MSG:?{
????????????????????synchronized?(mService)?{
????????????????????????broadcastTimeoutLocked(true);
????????????????????}
????????????????}?break;
????????????}
????????}
????}

這里我們來看processNextBroadcast:

???final?void?processNextBroadcast(boolean?fromMsg)?{
????????synchronized?(mService)?{
????????????processNextBroadcastLocked(fromMsg,?false);
????????}
????}

重點(diǎn)看看processNextBroadcastLocked:

???final?void?processNextBroadcastLocked(boolean?fromMsg,?boolean?skipOomAdj)?{
????????BroadcastRecord?r;
????????while?(mParallelBroadcasts.size()?>?0)?{
????????????r?=?mParallelBroadcasts.remove(0);//獲取平行廣播的BroadcastRecord對(duì)象

????????????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);//這里是核心調(diào)用了deliverToRegisteredReceiverLocked方法
????????????}
????????????addBroadcastToHistoryLocked(r);
????????????if?(DEBUG_BROADCAST_LIGHT)?Slog.v(TAG_BROADCAST,?"Done?with?parallel?broadcast?["
????????????????????+?mQueueName?+?"]?"?+?r);
????????}
//省略部分
}

下面來看deliverToRegisteredReceiverLocked方法:

private?void?deliverToRegisteredReceiverLocked(BroadcastRecord?r,
????????????BroadcastFilter?filter,?boolean?ordered,?int?index)
?{
???????//省略部分
????????try?{
????????????if?(filter.receiverList.app?!=?null?&&?filter.receiverList.app.inFullBackup)?{
????????????????//省略部分
????????????}?else?{
????????????????r.receiverTime?=?SystemClock.uptimeMillis();
????????????????maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app,?r);
????????????????performReceiveLocked(filter.receiverList.app,?filter.receiverList.receiver,
????????????????????????new?Intent(r.intent),?r.resultCode,?r.resultData,
????????????????????????r.resultExtras,?r.ordered,?r.initialSticky,?r.userId);
????????????????????????//最重要調(diào)用了performReceiveLocked
????????????????//省略部分
????????????}
???????????//省略部分
????????}?catch?(RemoteException?e)?{
????????????//省略部分
????????}
????}

接下來重點(diǎn)看performReceiveLocked:

?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)?{
????????????????
????????????????try?{
????????????????//調(diào)用到了具體應(yīng)用進(jìn)程的scheduleRegisteredReceiver方法
????????????????????app.thread.scheduleRegisteredReceiver(receiver,?intent,?resultCode,
????????????????????????????data,?extras,?ordered,?sticky,?sendingUser,?app.getReportedProcState());
?????????????
????????????????}?catch?(RemoteException?ex)?{
???????????????????//省略
????????????????}
????????????}?else?{
????????????????throw?new?RemoteException("app.thread?must?not?be?null");
????????????}
????????}?else?{
????????????receiver.performReceive(intent,?resultCode,?data,?extras,?ordered,
????????????????????sticky,?sendingUser);
????????}
????}

這里的scheduleRegisteredReceiver方法是在應(yīng)用進(jìn)程的ActivityThread類中實(shí)現(xiàn)的:

????????//?This?function?exists?to?make?sure?all?receiver?dispatching?is
????????//?correctly?ordered,?since?these?are?one-way?calls?and?the?binder?driver
????????//?applies?transaction?ordering?per?object?for?such?calls.
????????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);
????????}

這里會(huì)調(diào)用到receiver的performReceive方法,其中IIntentReceiver實(shí)際實(shí)在LoadedApk.java中:

?final?static?class?InnerReceiver?extends?IIntentReceiver.Stub?{
????????????//省略

????????????@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);
????????????????}?else?{
?????????????????//省略
????????????????}
????????????}
????????}

這里就調(diào)用了 LoadedApk.ReceiverDispatcher的performReceive方法,其中ReceiverDispatcher也在LoadedApk.java:

?????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.getRunnable()))?{?
????????????//這句mActivityThread.post(args.getRunnable())是核心
????????????????if?(mRegistered?&&?ordered)?{
????????????????????IActivityManager?mgr?=?ActivityManager.getService();
????????????????????if?(ActivityThread.DEBUG_BROADCAST)?Slog.i(ActivityThread.TAG,
????????????????????????????"Finishing?sync?broadcast?to?"?+?mReceiver);
????????????????????args.sendFinished(mgr);
????????????????}
????????????}
????????}

這里mActivityThread.post(args.getRunnable())是核心,就是往主線程post了一個(gè)runnable,我們來看getRunnable這個(gè)方法:

public?final?Runnable?getRunnable()?{
????????????????return?()?->?{
????????????????????//省略部分
????????????????????try?{
????????????????????????ClassLoader?cl?=?mReceiver.getClass().getClassLoader();
????????????????????????intent.setExtrasClassLoader(cl);
????????????????????????intent.prepareToEnterProcess();
????????????????????????setExtrasClassLoader(cl);
????????????????????????receiver.setPendingResult(this);
????????????????????????receiver.onReceive(mContext,?intent);//調(diào)用到具體應(yīng)用廣播接收器的onReceive
????????????????????}?catch?(Exception?e)?{
?????????????????????//省略部分
????????????????};
????????????}
????????}
主要就 receiver.onReceive(mContext, intent)這里就調(diào)用到具體應(yīng)用廣播接收器的onReceive,也就是我們經(jīng)常onReceive寫處理業(yè)務(wù)地方 總結(jié)圖如下:

在這里插入圖片描述
在這里插入圖片描述

2、廣播注冊(cè)接受部分 下一節(jié)講解

引用鏈接



android framework開發(fā)之廣播broadcast源碼分析-千里馬的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
郁南县| 台中县| 龙井市| 桓仁| 黄冈市| 水富县| 紫阳县| 墨玉县| 景东| 定西市| 全椒县| 海南省| 鄂托克前旗| 来凤县| 景东| 嫩江县| 印江| 宜兰县| 惠来县| 永善县| 星子县| 宁乡县| 昭平县| 钟山县| 修文县| 杭锦后旗| 偃师市| 南投县| 镇宁| 遂川县| 诸暨市| 平乐县| 金阳县| 红河县| 台东县| 昌黎县| 京山县| 唐河县| 康定县| 基隆市| 乐昌市|