當前位置:首頁 » 安卓系統 » android廣播用法

android廣播用法

發布時間: 2023-03-02 07:07:38

❶ android中的廣播怎麼使用

廣播操作有兩種
1、發送廣播,就是你自己發送出去一個廣播,讓別人接收
2、接收廣播,這個是自己實現一個廣播接收器,接收那些你自己過濾的廣播,然後處理
具體的代碼實現,可以在網上找找

❷ 說說Android的廣播(1)

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

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

普通的廣播是不在意順序的,最簡單的理解是同時可以收到這個廣播。如果應用是動態注冊這個廣播的,且廣播發送時這個進程還活著,那麼當然可以並發的把廣播盡快地傳送出去是最好的。
但是,如果是通過AndroidManifest.xml靜態注冊的情況,也就是說這個廣播首先要把一個進程啟動起來,這時並發啟動很多進程就是個問題了。Android目前的做法是,對這種靜態的廣播接收者,自動按有序廣播的方式來串列處理。但是這對應用是透明的,應用不能假設系統已經把靜態的無序廣播當成有序廣播來處理。

這個時候講粘性廣播有福了,因為從Android 5.0(API 21)開始,因為安全性的問題,官方已經正式廢棄了粘性廣播。

Context類提供兩個方法可以用於發送普通廣播:

差別是第二個設置許可權。

發給特定的用戶:

有序廣播因為要處理消息的處理結果,所以要復雜一些。

如果只是想讓廣播可以按優先順序來收取,並不在意處理的結果,可以用下面的版本:

同樣,在多用戶環境下,也可以選擇給哪個用戶發廣播:

不管是普通的還是有序的廣播都對應有粘性的版本:

以上的API都是定義於Context類中: https://developer.android.com/reference/android/content/Context.html

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

我們先看應用發送普通廣播的一個簡單的例子:

非常簡單,調用ContentWrapper的sendBroadcast方法就可以了。
然後我們順藤摸瓜就好了。
Activity中的sendBroadcast,實際上調用的是:

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

ContextWrapper只是一個包裝,真正的實現在ContextImpl中

我們來看/frameworks/base/core/java/android/app/ContextImpl.java中真正實現sendBroadcast的功能:

它會通過IPC去調用AMS的broadcastIntent。由於我們這個普通的廣播的方法參數最少,所以好多都是傳null。

加鎖,定參數,然後調用真正的邏輯的實現。

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

ContextWrapper.sendOrderedBroadcast

Context是abstract方法,調用的是ContextWrapper的實現:

跟普通廣播一樣,還是會調用到ContextImpl.sendOrderedBroadcast

有序廣播調用broadcastIntent的區別在於serialized參數,普通廣播為false,有序廣播為true.

原型為:

前面講過帶有回調的版本,我們看看它是如何實現的:

當然還是調用ContextImpl.sendOrderedBroadcast

這次變成只是一個封裝了,它會調用一個更多參數的版本:

這次是一個全參數調用broadcastIntent的版本了,除了sticky就齊了

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

❸ Android啟動廣播時怎樣往廣播中傳遞參數

在android中使用廣播來讓其他監聽廣播的地方能夠對相應的事情做處理,但有的時候需要傳遞一些其他的附帶值,而這個時候是可以直接用播放廣播的intent來傳遞的。x0dx0a例:x0dx0aIntent intent = new Intent();x0dx0aintent.putExtra("msgPersons", msgPersons);x0dx0aintent.setAction(Constant.hasMsgUpdatedAction);x0dx0aintent.putExtra("userId", userId);x0dx0aintent.putExtra("msgCount", messages.size());x0dx0asendBroadcast(intent);

❹ Android系統廣播(Broadcast)注冊,發送,接收流程解析

以下廣播簡稱Broadcast

   是Android四大組件之一,在四大組件的另外兩個組件 和 擁有發送和接收廣播的能力。Android 是在 進程間通信機制的基礎上實現的,內部基於消息發布和訂閱的事件驅動模型,廣播發送者負責發送消息,廣播接收者需要先訂閱消息,然後才能收到消息。 進程間通信與 的區別在於:

   有三種類型

   存在一個注冊中心,也可以說是一個調度中心,即 。廣播接收者將自己注冊到 中,並指定要接收的廣播類型;廣播發送者發送廣播時,發送的廣播首先會發送到 , 根據廣播的類型找到對應的 ,找到後邊將廣播發送給其處理。

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

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

   在相同優先順序接收同個類型廣播時, 的廣播接收器比 的廣播接收者更快的接收到對應的廣播,這個之後會進行分析。

   註:以下源碼基於rk3399_instry Android7.1.2

   的流程可分為 , 和 三個部分,這里依次分析下

   在Android系統的 機制中,前面提到, 作為一個注冊和調度中心負責注冊和轉發 。所以 的注冊過程就是把它注冊到 的過程。

   這里我們分析 廣播的過程, 和 有一個共同的父類 ,所以它們對應的注冊過程其實是調用 ,接下來我們按照流程逐步分析調用流程的源碼。

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

   在之前的 Android應用程序啟動入口ActivityThread.main流程分析 分析過,在我們啟動 Activity 時會創建一個 對象,然後通過 傳給我們啟動的 ,其內部就會將該對象賦值給 ; 的 方法也是類似的賦值流程,這里放個簡易的源碼應該更好理解

   可以看到最後都會將生成的 對象賦值給對應的
對象。接下來繼續分析 , 即 函數。

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

   這里我們首先看下如何將廣播接收者 封裝成一個 介面的 本地對象
/frameworks/base/core/java/android/app/LoadedApk.java

   每一個注冊過廣播接收者的 或 組件在<font color='Crimson'> LoadedApk </font>類中都有個對應的 對象,該對象負責將 與 組件關聯起來。這些對象,以關聯的 作為關鍵字保存在一個 中。之後對應的 又以 的 作為關鍵字保存在 的成員變數 對象中。最後通過 對應的 方法獲得其 介面的 本地對象。之後再回到 注冊方法內,將 對象發給 進行注冊。

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

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

   在的 或 注冊一個 時,並不是將其注冊到<font color='OrangeRed'>AMS</font>中,而是將與它關聯的<font color='OrangeRed'>InnerReceiver</font>對象注冊到<font color='OrangeRed'>AMS</font>中,當<font color='OrangeRed'>AMS</font>接收到廣播時,會根據 在內部找到對應的<font color='OrangeRed'>InnerReceiver</font>對象,然後在通過這個對象將這個廣播發送給對應的 處理。

   注冊過程這邊畫了一個簡單的流程圖:

   <font color='OrangeRed'>Broadcast</font>的發送過程可簡單描述為以下幾個過程:

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 使用廣播系統解決app開機自啟動問題

關注 【網羅開發】微信公眾號,回復【160】便可領取。
網羅天下方法,方便你我開發 ,更多Android技術干貨等待領取,所有文檔會持續更新,歡迎關注一起成長!

總結一下使用ACTION_BOOT_COMPLETED的廣播,解決app開機自啟動的問題
1.首先在你的工程上建一個廣播接受的類,繼承BroadcastReceiver:

2.然後要在AndroidManifest.xml中加入許可權和配置相關信息:

3.在application標簽中,配置以下相關信息:

補充說明:
1.查看系統中是否安裝了類似360管家的軟體,為了加快開機速度,默認是關閉掉開機廣播的,只需要在設置中打開即可。
2.如果監聽不到廣播,可以嘗試同時監聽廣播和sd卡。
3.同時監聽廣播和sd卡,在application標簽中,配置以下相關信息:

❻ 22 AndroidBroadcast廣播機制

廣播(Broadcast)機制用於進程/線程間通信,廣播分為廣播發送和廣播接收兩個過程,其中廣播接收者BroadcastReceiver便是Android四大組件之一。

BroadcastReceiver分為兩類:

從廣播發送方式可分為三類:

廣播在系統中以BroadcastRecord對象來記錄, 該對象有幾個時間相關的成員變數.

廣播注冊,對於應用開發來說,往往是在Activity/Service中調用 registerReceiver() 方法,而Activity或Service都間接繼承於Context抽象類,真正幹活是交給ContextImpl類。另外調用getOuterContext()可獲取最外層的調用者Activity或Service。

[ContextImpl.java]

其中broadcastPermission擁有廣播的許可權控制,scheler用於指定接收到廣播時onRecive執行線程,當scheler=null則默認代表在主線程中執行,這也是最常見的用法

[ContextImpl.java]

ActivityManagerNative.getDefault()返回的是ActivityManagerProxy對象,簡稱AMP.
該方法中參數有mMainThread.getApplicationThread()返回的是ApplicationThread,這是Binder的Bn端,用於system_server進程與該進程的通信。

[-> LoadedApk.java]

不妨令 以BroadcastReceiver(廣播接收者)為key,LoadedApk.ReceiverDispatcher(分發者)為value的ArrayMap 記為 A 。此處 mReceivers 是一個以 Context 為key,以 A 為value的ArrayMap。對於ReceiverDispatcher(廣播分發者),當不存在時則創建一個。

此處mActivityThread便是前面傳遞過來的當前主線程的Handler.

ReceiverDispatcher(廣播分發者)有一個內部類 InnerReceiver ,該類繼承於 IIntentReceiver.Stub 。顯然,這是一個Binder服務端,廣播分發者通過rd.getIIntentReceiver()可獲取該Binder服務端對象 InnerReceiver ,用於Binder IPC通信。

[-> ActivityManagerNative.java]

這里有兩個Binder服務端對象 caller 和 receiver ,都代表執行注冊廣播動作所在的進程. AMP通過Binder驅動將這些信息發送給system_server進程中的AMS對象,接下來進入AMS.registerReceiver。

[-> ActivityManagerService.java]

其中 mRegisteredReceivers 記錄著所有已注冊的廣播,以receiver IBinder為key, ReceiverList為value為HashMap。

在BroadcastQueue中有兩個廣播隊列mParallelBroadcasts,mOrderedBroadcasts,數據類型都為ArrayList<broadcastrecord style="box-sizing: border-box;">:</broadcastrecord>

mLruProcesses數據類型為 ArrayList<ProcessRecord> ,而ProcessRecord對象有一個IApplicationThread欄位,根據該欄位查找出滿足條件的ProcessRecord對象。

該方法用於匹配發起的Intent數據是否匹配成功,匹配項共有4項action, type, data, category,任何一項匹配不成功都會失敗。

broadcastQueueForIntent(Intent intent)通過判斷intent.getFlags()是否包含FLAG_RECEIVER_FOREGROUND 來決定是前台或後台廣播,進而返回相應的廣播隊列mFgBroadcastQueue或者mBgBroadcastQueue。

注冊廣播:

另外,當注冊的是Sticky廣播:

廣播注冊完, 另一個操作便是在廣播發送過程.

發送廣播是在Activity或Service中調用 sendBroadcast() 方法,而Activity或Service都間接繼承於Context抽象類,真正幹活是交給ContextImpl類。

[ContextImpl.java]

[-> ActivityManagerNative.java]

[-> ActivityManagerService.java]

broadcastIntent()方法有兩個布爾參數serialized和sticky來共同決定是普通廣播,有序廣播,還是Sticky廣播,參數如下:

broadcastIntentLocked方法比較長,這里劃分為8個部分來分別說明。

這個過程最重要的工作是:

BroadcastReceiver還有其他flag,位於Intent.java常量:

主要功能:

這個過主要處於系統相關的10類廣播,這里不就展開講解了.

這個過程主要是將sticky廣播增加到list,並放入mStickyBroadcasts裡面。

其他說明:

AMS.collectReceiverComponents

廣播隊列中有一個成員變數 mParallelBroadcasts ,類型為ArrayList<broadcastrecord style="box-sizing: border-box;">,記錄著所有的並行廣播。</broadcastrecord>

動態注冊的registeredReceivers,全部合並都receivers,再統一按串列方式處理。

廣播隊列中有一個成員變數 mOrderedBroadcasts ,類型為ArrayList<broadcastrecord style="box-sizing: border-box;">,記錄著所有的有序廣播。</broadcastrecord>

發送廣播過程:

處理方式:

可見不管哪種廣播方式,都是通過broadcastQueueForIntent()來根據intent的flag來判斷前台隊列或者後台隊列,然後再調用對應廣播隊列的scheleBroadcastsLocked方法來處理廣播;

在發送廣播過程中會執行 scheleBroadcastsLocked 方法來處理相關的廣播

[-> BroadcastQueue.java]

在BroadcastQueue對象創建時,mHandler=new BroadcastHandler(handler.getLooper());那麼此處交由mHandler的handleMessage來處理:

由此可見BroadcastHandler採用的是」ActivityManager」線程的Looper

[-> BroadcastQueue.java]

此處mService為AMS,整個流程還是比較長的,全程持有AMS鎖,所以廣播效率低的情況下,直接會嚴重影響這個手機的性能與流暢度,這里應該考慮細化同步鎖的粒度。

❼ android 之廣播機制

Android 中的廣播主要可以分為兩種類型:標准廣播和有序廣播

一種完全非同步執行的廣播,在廣播發出之後,所有的BroadcastReceiver幾乎會在同一時刻收到這條廣播消息,因此它們之間沒有任何先後順序可言。這種廣播的效率會比較高,但同時也意味著它是無法被截斷

標准廣播工作示意圖:

一種同步執行的廣播,在廣播發出之後,同一時刻只會有一個BroadcastReceiver能夠收到這條廣播消息,當這個BroadcastReceiver中的邏輯執行完畢後,廣播才會繼續傳遞。所以此時的BroadcastReceiver是有先後順序的,優先順序高的BroadcastReceiver就可以先收到廣播消息,並且前面的BroadcastReceiver還可以截斷正在傳遞的廣播,這樣後面的BroadcastReceiver就無法收到廣播消息了

有序廣播工作示意圖:

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

在Android 8.0系統之後,所有隱式廣播都不允許使用靜態注冊的方式來接收了。隱式廣播指的是那些沒有具體指定發送給哪個應用程序的廣播,大多數系統廣播屬於隱式廣播,但是少數特殊的系統廣播目前仍然允許使用靜態注冊的方式來接收,詳見網址: https://developer.android.google.cn/guide/components/broadcast-exceptions.html

在 AndroidManifest.xml 文件中注冊

在 AndroidManifest.xml 文件中進行許可權聲明

不要在 onReceive() 方法中添加過多的邏輯或者進行任何的耗時操作,因為BroadcastReceiver中是不允許開啟線程的,當 onReceive() 方法運行了較長時間而沒有結束時,程序就會出現錯誤

先定義一個BroadcastReceiver來准備接收此廣播

在 AndroidManifest.xml 文件中注冊

有序廣播是一種同步執行的廣播,並且是可以被截斷的。為了驗證這一點,我們需要再創建一個新的BroadcastReceiver。新建AnotherBroadcastReceiver

同樣,在 AndroidManifest.xml 文件中注冊,同時,使用 intent-filter 標簽的 android:priority 屬性設置優先順序

前面的 AnotherBroadcastReceiver 的優先順序比較高,因此 AnotherBroadcastReceiver 一定比 MyBroadcastReceiver 先收到廣播,因此,可以在 AnotherBroadcastReceiver 的 onReceive 方法中使用 abortBroadcast() 方法截斷廣播,這樣 MyBroadcastReceiver 就收不到該廣播了

在界面上彈出一個對話框,讓用戶無法進行任何其他操作,必須點擊對話框中的「確定」按鈕,關閉所有的Activity,然後回到登錄界面即可

ActivityCollector 類用於管理所有的Activity,具有關閉所有Activity的功能

創建 BaseActivity 類作為所有 Activity 的父類,並在裡面實現強制下線功能,在這里實現此功能,有以下幾點原因

創建一個LoginActivity來作為登錄界面

activity_login.xml

LoginActivity 如果輸入 123 就到 MainActivity界面

MainActivity 中點擊強制下線按鈕,就發送強制下線的廣播

MainActivity 布局

❽ Android BroadcastReceiver詳解

BroadcastReceiver(廣播接收器)是Android四大組件之一,顧名思義,通過廣播的方式進行消息傳遞,其本質是一個全局的監聽器,可以監聽到各種廣播,可以用來實現不同組件之間的通信。廣播最大的特點就是發送方並不關心接收方是否接到數據,也不關心接收方是如何處理數據的,通過這樣的形式來達到接、收雙方的完全解耦合。

又稱無序廣播,這種廣播完全是非同步的,所有與廣播Intent匹配的BroadcastReceiver,都可以收到這條廣播,並且不分先後順序,視為同時收到,通過Context.sendBroadcast()方法發送。這種廣播的效率比較高,但缺點是接收器不能將處理結果傳遞給下一個接收器,並且無法在中途終止廣播。

這是一種同步執行的廣播,通過Context.sendOrderedBroadcast()方法發送,這種廣播發出後,通過receiver的intent-filter中的android:priority屬性來設置優先順序,優先順序從-1000~1000,數越大,優先順序越高,使用setResult()方法把結果傳遞給下一個接收者,通過getResult()方法獲取上一個接收者傳遞過來的結果,並可以通過abortBroadcast()方法丟棄該廣播,使該廣播不再傳遞給下一個接收者。

粘性廣播通過Context.sendStickBroadcast()方法來發送,用此方法發送的廣播會一直滯留,當有匹配此廣播的接收器被注冊後,該廣播接收器就會收到此廣播。使用此廣播時,需要獲得BROADCAST_STICKY許可權。(在 android 5.0/api 21後不再推薦使用)

Android系統中內置了多個系統廣播,只要涉及到手機的基本操作,基本上都會發出相應的系統廣播。如:開啟啟動,網路狀態改變,拍照,屏幕關閉與開啟,點亮不足等等。每個系統廣播都具有特定的intent-filter,其中主要包括具體的action,系統廣播發出後,將被相應的BroadcastReceiver接收。系統廣播在系統內部當特定事件發生時,有系統自動發出。

以上廣播都屬於全局廣播,發出去的廣播,只要有匹配的接收者,就可以收到廣播。這樣一來會造成一些問題,一是消耗性能,二是容易引起安全性的問題,為了能夠簡單的解決這方面的問題,Android引入了一套廣播本地廣播機制,使用該機制發出的廣播只能夠在本應用內部進行傳遞,並且廣播接收器也只能接收來自本應用發出的廣播。

使用方法
1.注冊本地廣播接收器

2.發送本地廣播

3.注銷本地廣播接收器

本文用到的BroadcastReceiver

Android 8.0(API級別26)取消大部分靜態注冊廣播,建議使用動態廣播
https://developer.android.google.cn/about/versions/oreo/android-8.0

❾ android 廣播機制(2) 粘性廣播

android的粘性廣播,是指廣播接收器一注冊馬上就能接收到廣播的一種機制,當然首先系統要存在廣播。而普通廣播就是要先注冊廣播接收器,然後廣播被發送到系統,廣播接收器才能接收到廣播。
所以他們的區別是:
粘性廣播調用registerReceiver能馬上接受廣播,而普通廣播不行。

對於粘性廣播:
1.系統首先存在粘性廣播

2.注冊廣播接收器

3.處理廣播

下面用一個例子展示下他們的區別
主Acitivity

布局

布局有兩個按鈕,一個是注冊粘性廣播,一個是注冊普通廣播。點擊注冊粘性廣播按鈕會馬上返回結果。而點擊注冊普通廣播按鈕則沒有反應

熱點內容
加密ovpn 發布:2025-05-12 12:01:55 瀏覽:43
python練手項目 發布:2025-05-12 11:14:07 瀏覽:122
壓縮聽算音頻 發布:2025-05-12 10:58:12 瀏覽:801
資料庫系統報告 發布:2025-05-12 10:43:17 瀏覽:603
日產高配有哪些配置 發布:2025-05-12 10:32:16 瀏覽:475
大眾朗逸哪個配置值得入手 發布:2025-05-12 10:31:20 瀏覽:505
壓縮包的後綴 發布:2025-05-12 10:20:35 瀏覽:942
煙台招聘編程 發布:2025-05-12 10:04:21 瀏覽:53
sql查詢所有表名 發布:2025-05-12 10:01:28 瀏覽:666
用python編譯器的簡單代碼 發布:2025-05-12 09:48:40 瀏覽:358