真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

android廣播大全,Android廣播的作用

Android動態(tài)廣播(Android8.0)

(a).動態(tài)注冊 ? ? ? ? ? ? 在UI中注冊的廣播,例如:

為鳳臺等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及鳳臺網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、成都外貿(mào)網(wǎng)站建設(shè)、鳳臺網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!

(b).靜態(tài)注冊 ? ? ? ? ? ??

需要在manifest中進(jìn)行注冊(在安卓8.0后系統(tǒng)廢除了大部分靜態(tài)廣播,最好使用動態(tài)注冊)。

(a).系統(tǒng)廣播 ? ? ? ? ? ??

系統(tǒng)中已經(jīng)定義的廣播,此類廣播只能由系統(tǒng)發(fā)出,并且需要在intent-filter中加上系統(tǒng)已經(jīng)寫的action。? ? ? ? ? ? ?

(b).自定義廣播 ? ? ? ??

顧名思義,是用戶自己定義的廣播。

(a)我們首先需要一個(gè)廣播接收類 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

(b)其次注冊動態(tài)廣播

(c)最后需要通過send方法發(fā)送一個(gè)廣播供廣播接收者接受

另外還有有序廣播和無序廣播,這篇博客寫的比較詳細(xì),供大家參考: Android的有序廣播和無序廣播(解決安卓8.0版本之后有序廣播的接收問題) - ming3 - 博客園 (cnblogs.com)

BroadcastReceiver詳解(基礎(chǔ)篇)

Broadcast (廣播)是一種廣泛運(yùn)用的應(yīng)用程序之間傳輸信息的機(jī)制,而 BroadcastReceiver (廣播接收器)則是用于接收來自系統(tǒng)和應(yīng)用的廣播對并對其進(jìn)行響應(yīng)的組件,Android中我們要發(fā)送的廣播內(nèi)容是一個(gè) Intent ,這個(gè) Intent 中可以攜帶我們要傳送的數(shù)據(jù)

創(chuàng)建一個(gè)廣播接收器非常簡單,只需要繼承 BroadcastReceiver ,并重寫 onReceive() 即可

BroadcastReceiver 也是四大組件之一,所以我們也需要對 BroadcastReceiver 進(jìn)行注冊,不同于其他四大組件, BroadcastReceiver 有兩種注冊方式,分別是 靜態(tài)注冊 和 動態(tài)注冊

靜態(tài)注冊

當(dāng)我們的應(yīng)用首次啟動的時(shí)候,系統(tǒng)會自動實(shí)例化我們靜態(tài)注冊的 BroadcastReceiver ,然后將這個(gè) BroadcastReceiver 注冊到系統(tǒng)中,系統(tǒng)接收到廣播之后,就會做出相應(yīng)的判斷,調(diào)用 onReceive() 方法。通過這種方式注冊的廣播,即使我們的應(yīng)用被銷毀,依然能收到廣播。 這里要注意的是,我們的應(yīng)用一定要被啟動過 ,如果沒有被啟動可能就無法接收到廣播,可以參考文章 Android應(yīng)用在未啟動的情況下無法收到指定廣播的問題總結(jié)

正是因?yàn)殪o態(tài)注冊耗電、占內(nèi)存、不受程序生命周期影響,所以Google在Android 8.0上禁止大部分廣播的靜態(tài)注冊,可以參考官文文檔 Android 8.0 功能和 API

動態(tài)注冊

通過動態(tài)注冊的廣播, BroadcastReceiver 的生命周期跟隨Activity的生命周期

注意: 要在 Activity 的 onPause() 中 unRegeisterReceiver() ,否則會引起內(nèi)存泄漏。比較推薦 onResume() 中去注冊廣播,在 onPause() 中去注銷廣播。因?yàn)樵趦?nèi)存資源比較吃緊的情況下,可能我們的 Activity 執(zhí)行完 onPause() 之后就被銷毀,這時(shí)候 Activity 的 onStop() 和 onDestory() 方法就不會執(zhí)行了

BroadcastReceiver注冊完之后,這個(gè) BroadcastReceiver 就能夠接收響應(yīng)的廣播,下面我們來說說如何發(fā)送一條廣播

普通廣播(Normal Broadcast)

普通廣播完全是異步的,通過 context.sendBroadcast() 方法發(fā)送,消息傳遞效率比較高,但所有接收器的執(zhí)行順序不確定。缺點(diǎn)是接收者不能將處理結(jié)果傳遞給下一個(gè)接收者,并且無法終止廣播的傳播

有序廣播(Ordered Broadcast)

有序廣播是通過 context.sendOrderedBroadcast() 方法發(fā)送,所有的廣播者按照優(yōu)先級依次執(zhí)行,廣播接收器的優(yōu)先級通過 receiver 的 intent-filter 中的 android:priority 屬性來設(shè)置,數(shù)值越大優(yōu)先級越高。當(dāng)廣播接收器接收到廣播后,可以使用 setResult() 方法把結(jié)果傳遞給下一個(gè)接收者,通過 getResult() 方法獲取上一個(gè)接收者傳遞過來的結(jié)果,并可以通過 abortBroadcast() 方法丟棄該廣播,使該廣播不再傳遞給下一個(gè)接收者

粘性廣播(Sticky Broadcast)

粘性廣播通過 context.sendStickBroadcast() 方法來發(fā)送,用此方法發(fā)送的廣播會一直滯留,當(dāng)有匹配此廣播的接收器被注冊后,該廣播接收器就會收到此廣播。使用此廣播時(shí),需要獲得 BROADCAST_STICKY 權(quán)限

由于在Android5.0 API 21中已經(jīng)失效,所以不建議使用。

本地廣播(Local Broadcast)

前三種廣播都是全局廣播,所有應(yīng)用都可以接收到,這樣就帶來安全隱患,而本地廣播只在進(jìn)程內(nèi)傳播,可以起到保護(hù)數(shù)據(jù)安全的作用

其實(shí),本地廣播的使用與其十分類似,之前的步驟均是一樣的,調(diào)用者不同而已,本地廣播調(diào)用的是 LocalBroadcastManager 相關(guān)方法,全局廣播調(diào)用的是 Context 的相關(guān)方法,其方法名都是一樣的

這里需要說一下, 使用本地廣播并沒有靜態(tài)注冊的方法 ,因?yàn)殪o態(tài)注冊主要是為了讓程序在未啟動的情況下也能收到廣播,而發(fā)動本地廣播的時(shí)候,我們的程序已經(jīng)是啟動了,所以,自然是沒有靜態(tài)注冊這個(gè)方法

Android中內(nèi)置了多個(gè)系統(tǒng)廣播,當(dāng)使用系統(tǒng)廣播時(shí),只需要在注冊廣播接收者時(shí)定義相關(guān)的 action 即可,并不需要手動發(fā)送廣播,當(dāng)系統(tǒng)有相關(guān)操作(如開機(jī)、網(wǎng)絡(luò)狀態(tài)變化、拍照等等)時(shí)會自動進(jìn)行系統(tǒng)廣播

Android系統(tǒng)廣播 action 如下:

本文介紹了 BroadcastReceiver 的兩種注冊方式(動態(tài)注冊、靜態(tài)注冊),四種發(fā)送方式(普通廣播、有序廣播、粘性廣播(API21廢棄)、本地廣播),以及系統(tǒng)廣播的用法。幾乎涵蓋了 BoradcastReceiver 在應(yīng)用開發(fā)過程中的所有知識,對于BroadcastReceiver原理感興趣的可以繼續(xù)看 BroadcastReceiver詳解(原理篇)

Android系統(tǒng)廣播(Broadcast)注冊,發(fā)送,接收流程解析

以下廣播簡稱Broadcast

?? 是Android四大組件之一,在四大組件的另外兩個(gè)組件 和 擁有發(fā)送和接收廣播的能力。Android 是在 進(jìn)程間通信機(jī)制的基礎(chǔ)上實(shí)現(xiàn)的,內(nèi)部基于消息發(fā)布和訂閱的事件驅(qū)動模型,廣播發(fā)送者負(fù)責(zé)發(fā)送消息,廣播接收者需要先訂閱消息,然后才能收到消息。 進(jìn)程間通信與 的區(qū)別在于:

?? 有三種類型

?? 存在一個(gè)注冊中心,也可以說是一個(gè)調(diào)度中心,即 。廣播接收者將自己注冊到 中,并指定要接收的廣播類型;廣播發(fā)送者發(fā)送廣播時(shí),發(fā)送的廣播首先會發(fā)送到 , 根據(jù)廣播的類型找到對應(yīng)的 ,找到后邊將廣播發(fā)送給其處理。

?? 這里以普通廣播為例子, 接收者有兩種注冊方式,一種是 ,一種是 :

(廣播的發(fā)送分為 兩種,這里針對有序的廣播) 中的android:priority=""和 中的IntentFilter.setPriority(int)可以用來設(shè)置廣播接收者的優(yōu)先級,默認(rèn)都是0 , 范圍是[-1000, 1000],值越大優(yōu)先級越高,優(yōu)先級越高越早收到。

?? 在相同優(yōu)先級接收同個(gè)類型廣播時(shí), 的廣播接收器比 的廣播接收者更快的接收到對應(yīng)的廣播,這個(gè)之后會進(jìn)行分析。

?? 注:以下源碼基于rk3399_industry Android7.1.2

?? 的流程可分為 , 和 三個(gè)部分,這里依次分析下

?? 在Android系統(tǒng)的 機(jī)制中,前面提到, 作為一個(gè)注冊和調(diào)度中心負(fù)責(zé)注冊和轉(zhuǎn)發(fā) 。所以 的注冊過程就是把它注冊到 的過程。

?? 這里我們分析 廣播的過程, 和 有一個(gè)共同的父類 ,所以它們對應(yīng)的注冊過程其實(shí)是調(diào)用 ,接下來我們按照流程逐步分析調(diào)用流程的源碼。

frameworks/base/core/java/android/content/ContextWrapper.java

?? 在之前的 Android應(yīng)用程序啟動入口ActivityThread.main流程分析 分析過,在我們啟動 Activity 時(shí)會創(chuàng)建一個(gè) 對象,然后通過 傳給我們啟動的 ,其內(nèi)部就會將該對象賦值給 ; 的 方法也是類似的賦值流程,這里放個(gè)簡易的源碼應(yīng)該更好理解

?? 可以看到最后都會將生成的 對象賦值給對應(yīng)的

對象。接下來繼續(xù)分析 , 即 函數(shù)。

/frameworks/base/core/java/android/app/ContextImpl.java

?? 這里我們首先看下如何將廣播接收者 封裝成一個(gè) 接口的 本地對象

/frameworks/base/core/java/android/app/LoadedApk.java

?? 每一個(gè)注冊過廣播接收者的 或 組件在font color='Crimson' LoadedApk /font類中都有個(gè)對應(yīng)的 對象,該對象負(fù)責(zé)將 與 組件關(guān)聯(lián)起來。這些對象,以關(guān)聯(lián)的 作為關(guān)鍵字保存在一個(gè) 中。之后對應(yīng)的 又以 的 作為關(guān)鍵字保存在 的成員變量 對象中。最后通過 對應(yīng)的 方法獲得其 接口的 本地對象。之后再回到 注冊方法內(nèi),將 對象發(fā)給 進(jìn)行注冊。

/frameworks/base/core/java/android/app/ActivityManagerNative.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

?? 在的 或 注冊一個(gè) 時(shí),并不是將其注冊到font color='OrangeRed'AMS/font中,而是將與它關(guān)聯(lián)的font color='OrangeRed'InnerReceiver/font對象注冊到font color='OrangeRed'AMS/font中,當(dāng)font color='OrangeRed'AMS/font接收到廣播時(shí),會根據(jù) 在內(nèi)部找到對應(yīng)的font color='OrangeRed'InnerReceiver/font對象,然后在通過這個(gè)對象將這個(gè)廣播發(fā)送給對應(yīng)的 處理。

?? 注冊過程這邊畫了一個(gè)簡單的流程圖:

?? font color='OrangeRed'Broadcast/font的發(fā)送過程可簡單描述為以下幾個(gè)過程:

frameworks/base/core/java/android/content/ContextWrapper.java

/frameworks/base/core/java/android/app/ContextImpl.java

/frameworks/base/core/java/android/app/ActivityManagerNative.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

android 廣播機(jī)制(2) 粘性廣播

android的粘性廣播,是指廣播接收器一注冊馬上就能接收到廣播的一種機(jī)制,當(dāng)然首先系統(tǒng)要存在廣播。而普通廣播就是要先注冊廣播接收器,然后廣播被發(fā)送到系統(tǒng),廣播接收器才能接收到廣播。

所以他們的區(qū)別是:

粘性廣播調(diào)用registerReceiver能馬上接受廣播,而普通廣播不行。

對于粘性廣播:

1.系統(tǒng)首先存在粘性廣播

2.注冊廣播接收器

3.處理廣播

下面用一個(gè)例子展示下他們的區(qū)別

主Acitivity

布局

布局有兩個(gè)按鈕,一個(gè)是注冊粘性廣播,一個(gè)是注冊普通廣播。點(diǎn)擊注冊粘性廣播按鈕會馬上返回結(jié)果。而點(diǎn)擊注冊普通廣播按鈕則沒有反應(yīng)

android 之廣播機(jī)制

Android 中的廣播主要可以分為兩種類型:標(biāo)準(zhǔn)廣播和有序廣播

一種完全異步執(zhí)行的廣播,在廣播發(fā)出之后,所有的BroadcastReceiver幾乎會在同一時(shí)刻收到這條廣播消息,因此它們之間沒有任何先后順序可言。這種廣播的效率會比較高,但同時(shí)也意味著它是無法被截?cái)?/p>

標(biāo)準(zhǔn)廣播工作示意圖:

一種同步執(zhí)行的廣播,在廣播發(fā)出之后,同一時(shí)刻只會有一個(gè)BroadcastReceiver能夠收到這條廣播消息,當(dāng)這個(gè)BroadcastReceiver中的邏輯執(zhí)行完畢后,廣播才會繼續(xù)傳遞。所以此時(shí)的BroadcastReceiver是有先后順序的,優(yōu)先級高的BroadcastReceiver就可以先收到廣播消息,并且前面的BroadcastReceiver還可以截?cái)嗾趥鬟f的廣播,這樣后面的BroadcastReceiver就無法收到廣播消息了

有序廣播工作示意圖:

可以讓程序在未啟動的情況下接收廣播

在Android 8.0系統(tǒng)之后,所有隱式廣播都不允許使用靜態(tài)注冊的方式來接收了。隱式廣播指的是那些沒有具體指定發(fā)送給哪個(gè)應(yīng)用程序的廣播,大多數(shù)系統(tǒng)廣播屬于隱式廣播,但是少數(shù)特殊的系統(tǒng)廣播目前仍然允許使用靜態(tài)注冊的方式來接收,詳見網(wǎng)址:

在 AndroidManifest.xml 文件中注冊

在 AndroidManifest.xml 文件中進(jìn)行權(quán)限聲明

不要在 onReceive() 方法中添加過多的邏輯或者進(jìn)行任何的耗時(shí)操作,因?yàn)锽roadcastReceiver中是不允許開啟線程的,當(dāng) onReceive() 方法運(yùn)行了較長時(shí)間而沒有結(jié)束時(shí),程序就會出現(xiàn)錯(cuò)誤

先定義一個(gè)BroadcastReceiver來準(zhǔn)備接收此廣播

在 AndroidManifest.xml 文件中注冊

有序廣播是一種同步執(zhí)行的廣播,并且是可以被截?cái)嗟?。為了?yàn)證這一點(diǎn),我們需要再創(chuàng)建一個(gè)新的BroadcastReceiver。新建AnotherBroadcastReceiver

同樣,在 AndroidManifest.xml 文件中注冊,同時(shí),使用 intent-filter 標(biāo)簽的 android:priority 屬性設(shè)置優(yōu)先級

前面的 AnotherBroadcastReceiver 的優(yōu)先級比較高,因此 AnotherBroadcastReceiver 一定比 MyBroadcastReceiver 先收到廣播,因此,可以在 AnotherBroadcastReceiver 的 onReceive 方法中使用 abortBroadcast() 方法截?cái)鄰V播,這樣 MyBroadcastReceiver 就收不到該廣播了

在界面上彈出一個(gè)對話框,讓用戶無法進(jìn)行任何其他操作,必須點(diǎn)擊對話框中的“確定”按鈕,關(guān)閉所有的Activity,然后回到登錄界面即可

ActivityCollector 類用于管理所有的Activity,具有關(guān)閉所有Activity的功能

創(chuàng)建 BaseActivity 類作為所有 Activity 的父類,并在里面實(shí)現(xiàn)強(qiáng)制下線功能,在這里實(shí)現(xiàn)此功能,有以下幾點(diǎn)原因

創(chuàng)建一個(gè)LoginActivity來作為登錄界面

activity_login.xml

LoginActivity 如果輸入 123 就到 MainActivity界面

MainActivity 中點(diǎn)擊強(qiáng)制下線按鈕,就發(fā)送強(qiáng)制下線的廣播

MainActivity 布局

說說Android的廣播(1)

對于Activity的啟動流程,我們已經(jīng)有了幾個(gè)版本的分析了。這里我們分析一個(gè)更容易一些的,四大組件中最簡單的Broadcast Receiver。

關(guān)于Broadcast,有幾點(diǎn)需要了解。首先是廣播的類型,然后是廣播的發(fā)送方法,最后是廣播是如何被接收的。這三者相輔相承的,比如普通廣播和有序廣播只有在詳細(xì)了解了廣播的接收過程了之后,才能真正明白它的含義。

普通的廣播是不在意順序的,最簡單的理解是同時(shí)可以收到這個(gè)廣播。如果應(yīng)用是動態(tài)注冊這個(gè)廣播的,且廣播發(fā)送時(shí)這個(gè)進(jìn)程還活著,那么當(dāng)然可以并發(fā)的把廣播盡快地傳送出去是最好的。

但是,如果是通過AndroidManifest.xml靜態(tài)注冊的情況,也就是說這個(gè)廣播首先要把一個(gè)進(jìn)程啟動起來,這時(shí)并發(fā)啟動很多進(jìn)程就是個(gè)問題了。Android目前的做法是,對這種靜態(tài)的廣播接收者,自動按有序廣播的方式來串行處理。但是這對應(yīng)用是透明的,應(yīng)用不能假設(shè)系統(tǒng)已經(jīng)把靜態(tài)的無序廣播當(dāng)成有序廣播來處理。

這個(gè)時(shí)候講粘性廣播有福了,因?yàn)閺腁ndroid 5.0(API 21)開始,因?yàn)榘踩缘膯栴},官方已經(jīng)正式廢棄了粘性廣播。

Context類提供兩個(gè)方法可以用于發(fā)送普通廣播:

差別是第二個(gè)設(shè)置權(quán)限。

發(fā)給特定的用戶:

有序廣播因?yàn)橐幚硐⒌奶幚斫Y(jié)果,所以要復(fù)雜一些。

如果只是想讓廣播可以按優(yōu)先級來收取,并不在意處理的結(jié)果,可以用下面的版本:

同樣,在多用戶環(huán)境下,也可以選擇給哪個(gè)用戶發(fā)廣播:

不管是普通的還是有序的廣播都對應(yīng)有粘性的版本:

以上的API都是定義于Context類中:

首先我們先看看發(fā)送端是如何發(fā)送的。

我們首先先放一個(gè)大圖,讓大家先有一個(gè)直觀的印象,不管普通廣播、有序廣播、粘性廣播如何組合,最終都匯集到一個(gè)大方法中。

我們先看應(yīng)用發(fā)送普通廣播的一個(gè)簡單的例子:

非常簡單,調(diào)用ContentWrapper的sendBroadcast方法就可以了。

然后我們順藤摸瓜就好了。

Activity中的sendBroadcast,實(shí)際上調(diào)用的是:

我們來看frameworks/base/core/java/android/content/ContextWrapper.java中對sendBroadcast的定義:

ContextWrapper只是一個(gè)包裝,真正的實(shí)現(xiàn)在ContextImpl中

我們來看/frameworks/base/core/java/android/app/ContextImpl.java中真正實(shí)現(xiàn)sendBroadcast的功能:

它會通過IPC去調(diào)用AMS的broadcastIntent。由于我們這個(gè)普通的廣播的方法參數(shù)最少,所以好多都是傳null。

加鎖,定參數(shù),然后調(diào)用真正的邏輯的實(shí)現(xiàn)。

我們先把broadcastIntentLocked的真正邏輯放一下,先看看有序廣播是如何發(fā)送的。

ContextWrapper.sendOrderedBroadcast

Context是abstract方法,調(diào)用的是ContextWrapper的實(shí)現(xiàn):

跟普通廣播一樣,還是會調(diào)用到ContextImpl.sendOrderedBroadcast

有序廣播調(diào)用broadcastIntent的區(qū)別在于serialized參數(shù),普通廣播為false,有序廣播為true.

原型為:

前面講過帶有回調(diào)的版本,我們看看它是如何實(shí)現(xiàn)的:

當(dāng)然還是調(diào)用ContextImpl.sendOrderedBroadcast

這次變成只是一個(gè)封裝了,它會調(diào)用一個(gè)更多參數(shù)的版本:

這次是一個(gè)全參數(shù)調(diào)用broadcastIntent的版本了,除了sticky就齊了

我們也不繞圈子了,直接看ContextImpl.sendStickyBroadcast.


分享標(biāo)題:android廣播大全,Android廣播的作用
URL鏈接:http://weahome.cn/article/dscijsg.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部