91亚洲精华国内精华精华液_国产高清在线精品一区不卡_精品特级一级毛片免费观看_欧美日韩中文制服有码_亚洲精品无码你懂的网站369

BroadCastReceiver 簡(jiǎn)介 (末尾有源碼)

BroadCastReceiver 源碼位于: framework/base/core/java/android.content.BroadcastReceiver.java

 

廣 播接收者( BroadcastReceiver )用于接收廣播 Intent ,廣播 Intent 的發(fā)送是通過調(diào)用 Context.sendBroadcast() 、 Context.sendOrderedBroadcast() 來實(shí)現(xiàn)的。通常一個(gè)廣播 Intent 可以被訂閱了此 Intent 的多個(gè)廣播接收者所接收。

 

廣播是一種廣泛運(yùn)用的在應(yīng)用程序之間傳輸信息的機(jī)制 。而 BroadcastReceiver 是對(duì)發(fā)送出來的廣播進(jìn)行過濾接收并響應(yīng)的一類組件;

 

來自普通應(yīng)用程序,如一個(gè)應(yīng)用程序通知其他應(yīng)用程序某些數(shù)據(jù)已經(jīng)下載完畢。

 BroadcastReceiver 自身并不實(shí)現(xiàn)圖形用戶界面,但是當(dāng)它收到某個(gè)通知后, BroadcastReceiver 可以啟動(dòng) Activity 作為響應(yīng),或者通過 NotificationMananger 提醒用戶,或者啟動(dòng) Service 等等。

BroadCastReceiver 的機(jī)制

1. 機(jī)制

在  Android  里面有各種各樣的廣播,比如電池的使用狀態(tài),電話的接收和短信的接收都會(huì)產(chǎn)生一個(gè)廣播,應(yīng)用程序開發(fā)者也可以監(jiān)聽這些廣播并做出程序邏輯的處理。如圖:


 

2. 實(shí)現(xiàn)

用接收短信舉例:

 

第一種方式

實(shí)現(xiàn)

public   class MyBroadcastReceiver extends BroadcastReceiver {

 

      // action 名稱

     String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED" ;

 

      public   void onReceive(Context context, Intent intent) {

 

         if (intent.getAction().equals( SMS_RECEIVED )) {

             // 相關(guān)處理 : 地域變換、電量不足、來電來信;

        }

     }

}

系統(tǒng)注冊(cè):在 AndroidManifest.xml 中注冊(cè)

< receiver android:name = ".MyBroadcastReceiver" >

             < intent-filter android:priority = "1000" >

                

< action android:name = " android.provider.Telephony.SMS_RECEIVED" />

             </ intent-filter >

         </ receiver > 當(dāng)然了需要權(quán)限

 

< uses-permission android:name = "android.permission.RECEIVE_SMS" />

< uses-permission android:name = "android.permission.SEND_SMS"  />

 

 

第二種方式:

 

// 廣播接收者 - 廣播的接收

private BroadcastReceiver myBroadcastReceiver   = new BroadcastReceiver() {

 

         @Override

         public   void onReceive(Context context, Intent intent) {

             // 相關(guān)處理,如收短信,監(jiān)聽電量變化信息

        }

 

     };

 

代碼中注冊(cè):

IntentFilter intentFilter = new IntentFilter( "android.provider.Telephony.SMS_RECEIVED " );

registerReceiver( mBatteryInfoReceiver , intentFilter);

 

3. 生命周期

 

描述了 Android  中廣播的生命周期,其次它并不像 Activity  一樣復(fù)雜,運(yùn)行原理很簡(jiǎn)單如下圖:


 

 

生命周期只有十秒左右,如果在 onReceive() 內(nèi)做超過十秒內(nèi)的事情,就會(huì)報(bào)錯(cuò) 。

 

每 次廣播到來時(shí) , 會(huì)重新創(chuàng)建 BroadcastReceiver 對(duì)象 , 并且調(diào)用 onReceive() 方法 , 執(zhí)行完以后 , 該對(duì)象即被銷毀 . 當(dāng) onReceive() 方法在 10 秒內(nèi)沒有執(zhí)行完畢, Android 會(huì)認(rèn)為該程序無響應(yīng) . 所以在

BroadcastReceiver 里不能做一些比較耗時(shí)的操作 , 否側(cè)會(huì)彈出 ANR(Application No  

Response) 的對(duì)話框 . 。(如圖):

 

怎么用好 BroadcastReceiver ?

如果需要完成一項(xiàng)比較耗時(shí)的工作 , 應(yīng)該通過發(fā)送 Intent 給 Service, 由 Service 來完成 . 這里不能使用子線程來解決 , 因?yàn)?BroadcastReceiver 的生命周期很短 , 子線程可能還沒有結(jié)束

BroadcastReceiver 就先結(jié)束了 .BroadcastReceiver 一旦結(jié)束 , 此時(shí) BroadcastReceiver 的

所在進(jìn)程很容易在系統(tǒng)需要內(nèi)存時(shí)被優(yōu)先殺死 , 因?yàn)樗鼘儆诳者M(jìn)程 ( 沒有任何活動(dòng)組件的進(jìn)程 ). 如果它的宿主進(jìn)程被殺死 , 那么正在工作的子線程也會(huì)被殺死 . 所以采用子線程來解決是不可靠的 .

 

廣播類型及廣播的收發(fā)

廣播類型

普通廣播 (Normal broadcasts)

   發(fā)送一個(gè)廣播,所以監(jiān)聽該廣播的廣播接收者都可以監(jiān)聽到改廣播。

異步廣播 ,   當(dāng)處理完之后的Intent ,依然存在,這時(shí)候registerReceiver(BroadcastReceiver, IntentFilter) 還能收到他的值,直到你把它去掉 , 不能將處理結(jié)果傳給下一個(gè)接收者 , 無法終止廣播 .

 

有序廣播 (Ordered broadcasts)

按照接收者的優(yōu)先級(jí)順序接收廣播 , 優(yōu)先級(jí)別在 intent-filter 中的 priority 中聲明 ,-1000 到

1000 之間 , 值越大 , 優(yōu)先級(jí)越高 . 可以終止廣播意圖的繼續(xù)傳播 . 接收者可以篡改內(nèi)容 .

 

 

 

廣播的收發(fā)

該組件接收被廣播的 intent,Context 可以通過 sendBroadcast() 和 sendOrderedBroadcast()

方法實(shí)現(xiàn)廣播的發(fā)送 .

首先在需要發(fā)送信息的地方 ,把要發(fā)送的信息和用于過濾的信息 ( 如 Action 、 Category) 裝入一個(gè) Intent 對(duì)象 ,然后通過調(diào)用  Context.sendBroadcast() 、 sendOrderBroadcast() 或 sendStickyBroadcast() 方法,把  Intent 對(duì)象以廣播方式發(fā)送出去。

 

使用 sendBroadcast()  或 sendStickyBroadcast() 方法發(fā)出去的 Intent ,所有滿足條件的 BroadcastReceiver 都會(huì)隨機(jī)地執(zhí)行其 onReceive() 方法

普通廣播的發(fā)送和接收:

sendBroadcast(intent);

 

Intent intent = new Intent( "cn.lenovo.yangguangf " );

         sendBroadcast(intent);

priority :這個(gè)是 AndroidManifest.xml intent-filter 的參數(shù)。

 

< receiver android:name = ".MyBroadcastReceiver" >

             < intent-filter android:priority = "1000" >

                

< action android:name = "cn.lenovo.yangguangfu" />

</ intent-filter >

</ receiver >

 

sendOrderedBroadcast(intent, receiverPermission);

 

1 ,他決定該廣播的級(jí)別,級(jí)別數(shù)值是在 -10001000 之間 , 值越大 , 優(yōu)先級(jí)越高;

 

2 ,同級(jí)別接收是先后是隨機(jī)的;級(jí)別低的收到廣播;

3 ,在 android 系統(tǒng)中只要監(jiān)聽該廣播的接收者,都能夠收到 sendBroadcast(intent) 發(fā)出的廣播 ;

 

3 ,不能截?cái)鄰V播的繼續(xù)傳播,

 

4 ,實(shí)驗(yàn)現(xiàn)象,在這個(gè)方法發(fā)來的廣播中,代碼注冊(cè)方式中,收到的廣播的先后和注明優(yōu)先級(jí)最高的他們的先后是隨機(jī)。如果都沒有優(yōu)先級(jí),代碼注冊(cè)收到為最先。

有序廣播的發(fā)送和接收:

sendOrderedBroadcast(intent, receiverPermission);

sendOrderedBroadcast(intent, receiverPermission, resultReceiver,

         scheduler, initialCode, initialData, initialExtras)

意圖,廣播,所有匹配的這一意圖將接收機(jī)接收廣播。

receiverPermission 這是權(quán)限,一個(gè)接收器必須持以接收您的廣播。如果為 null ,不經(jīng)許可的要求。
resultReceiver 您自己 BroadcastReceiver 來當(dāng)作最后的廣播接收器。
調(diào)度自定義處理程序,用以安排 resultReceiver 回調(diào) ; 如果為 null 將語(yǔ)境中的主線程舉行。
initialCode 一種結(jié)果代碼的初始值。通常為 Activity.RESULT_OK 。這個(gè)值是 -1 ;為其他 int 型  也可以,如 0,1,2 ;
initialData 一種結(jié)果數(shù)據(jù)的初始值。通常情況下為空 , 是 String 類型 ;
initialExtras 一種結(jié)果額外的初始值。通常情況下為空 , 是 Bundle;

 

intent The Intent to broadcast; all receivers matching this Intent will receive the broadcast.

receiverPermission String naming a permissions that a receiver must hold in order to receive your broadcast. If null, no permission is required.

resultReceiver Your own BroadcastReceiver to treat as the final receiver of the broadcast.

scheduler A custom Handler with which to schedule the resultReceiver callback; if null it will be scheduled in the Context's main thread.

initialCode An initial value for the result code. Often Activity.RESULT_OK.

initialData An initial value for the result data. Often null.

initialExtras An initial value for the result extras. Often null.

1,    該廣播的級(jí)別有級(jí)別之分,級(jí)別數(shù)值是在 -10001000 之間 , 值越大 , 優(yōu)先級(jí)越高;

2,    同級(jí)別接收是先后是隨機(jī)的,再到級(jí)別低的收到廣播;

3,    同級(jí)別接收是先后是隨機(jī)的,如果先接收到的把廣播截?cái)嗔?,同?jí)別的例外的接收者是無法收到該廣播的。( abortBroadcast()

 

4 ,能截?cái)鄰V播的繼續(xù)傳播,高級(jí)別的廣播收到該廣播后,可以決定把該鐘廣播是否截?cái)嗟簟?/p>

5 ,實(shí)驗(yàn)現(xiàn)象,在這個(gè)方法發(fā)來的廣播中,代碼注冊(cè)方式中,收到廣播先后次序?yàn)椋鹤⒚鲀?yōu)先級(jí)的、代碼注冊(cè)的、沒有優(yōu)先級(jí)的;如果都沒有優(yōu)先級(jí),代碼注冊(cè)收到為最先。

 

 

異步廣播的發(fā)送和接收:

sendStickyBroadcast(intent);

當(dāng)處理完之后的Intent ,依然存在,直到你把它去掉。

發(fā)這個(gè)廣播需要權(quán)限<uses-permission android:name="android.permission.BROADCAST_STICKY" />  

去掉是用這個(gè)方法removeStickyBroadcast(intent); 但別忘了在執(zhí)行這個(gè)方法的應(yīng)用里面 AndroidManifest.xml 同樣要加上面的權(quán)限;

 

 

sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

        initialCode, initialData, initialExtras)

這個(gè)方法具有有序廣播的特性也有異步廣播的特性;

 


發(fā)送這個(gè)廣播要: <uses-permission android:name="android.permission.BROADCAST_STICKY"  /> 這個(gè)權(quán)限。才能使用這個(gè)方法。如果您并不擁有該權(quán)限,將拋出 SecurityException 的。

 

實(shí)驗(yàn)現(xiàn)象( sendStickyOrderedBroadcast ()中),在這個(gè)方法發(fā)來的廣播中,代碼注冊(cè)方式中,收到廣播先后次序?yàn)椋鹤⒚鲀?yōu)先級(jí)的、代碼注冊(cè)的、沒有優(yōu)先級(jí)的;如果都沒有優(yōu)先級(jí),代碼注冊(cè)收到為最先。

 

廣播注冊(cè)與注銷

代碼中注冊(cè)廣播:

注 冊(cè)廣播方法一: registerReceiver(BroadcastReceiver receiver, IntentFilter filter) ,第一個(gè)參數(shù)是我們要處理廣播的 BroadcastReceiver (廣播接收者,可以是系統(tǒng)的,也可以是自定義的);第二個(gè)參數(shù)是意圖過濾器。

 

注冊(cè)廣播方法二: registerReceiver(receiver, filter, broadcastPermission, scheduler) ,第一個(gè)參數(shù)是 BroadcastReceiver (廣播接收者,可以是系統(tǒng)的,也可以是自定義的);第二個(gè)參數(shù)是意圖過濾器;第三個(gè)參數(shù)是廣播權(quán)限;第四個(gè)參數(shù)是 Hander ;

 

注意:權(quán)限重復(fù)現(xiàn)象,如果功能清單文件里注冊(cè)了權(quán)限,在該方法再注冊(cè),則 receiver 無法收到廣播,如果 功能清單文件里沒有注冊(cè)了權(quán)限,該方法注冊(cè)也無法收到。當(dāng)該方法沒有注冊(cè)權(quán)限,功能清單里注冊(cè)的時(shí)候, receiver 能收到廣播。

 

 

總結(jié):在 Activity 中代碼注冊(cè)廣播建議在: onResume() 中注冊(cè);

 

思 維拓展: 1 ,如果在代碼調(diào)用 registerReceiver(BroadcastReceiver receiver, IntentFilter filter) 十次( receiver , filter 的參數(shù)是同一參數(shù)),那么是否當(dāng)該廣播發(fā)送來的時(shí)候會(huì)收到十次呢?

 

        2 ,注銷是否也要注銷十次才能把廣播全部注銷呢?

 

系統(tǒng)中注冊(cè)廣播:(在 AndroidManifest.xml 中 )

< receiver android:name = ".MyBroadcastReceiver" >

             < intent-filter android:priority = "900" >

                

                < action android:name = "cn.lenovo.yangguangfu" />

             </ intent-filter >

</ receiver >

 

有時(shí)候還要根據(jù)發(fā)送廣播是否指定權(quán)限,來決定是否要權(quán)限;

 

廣播注銷

 

// 代碼中注銷廣播

/unregisterReceiver(mBatteryInfoReceiver);

?

 

在 Activity 中代碼注銷廣播建議在: onPuase()   中注銷;

不要這這里面注銷 Activity.onSaveInstanceState(), 因?yàn)檫@個(gè)方法是保存 Intent 狀態(tài)的。

 

BroadCastReceiver 的 API

abortBroadcast  ():

這個(gè)方法可以截獲由 sendOrderedBroadcast () 發(fā)送來的 廣播,讓其它廣播接收者無法收到這個(gè)廣播。

clearAbortBroadcast   ()  

這個(gè)方法是針對(duì)上面的 abortBroadcast()  方法的,用于取消截獲廣播。這樣它的下一級(jí)廣播接收者就能夠收到該廣播了。  

getAbortBroadcast   ()  

這 個(gè)方法作用是:判斷是否調(diào)用了 abortBroadcast  (),如果先調(diào)用 abortBroadcast  (),接著再調(diào)用 getAbortBroadcast  (),將返回 true;   如果在調(diào)用 abortBroadcast()  、 clearAbortBroadcast   ()  

getAbortBroadcast  (),將返回 false;  

   

public final boolean   getDebugUnregister   ()  

Since: API Level 1  

Return the last value given to setDebugUnregister(boolean) .  

 

 

getResultCode   ()  

如果用下面四個(gè)方法發(fā)送得廣播,返回碼為: -1 ;

// sendBroadcast(intent);

// sendBroadcast(intent, receiverPermission);

// sendOrderedBroadcast(intent, receiverPermission);

// sendStickyBroadcast(intent);

如果用下面兩個(gè)方法發(fā)送得廣播,返回碼為:根據(jù)你設(shè)置 initialCode 的數(shù)字是多少就是多少;

// sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

// initialCode, initialData, initialExtras)

// sendOrderedBroadcast(intent, receiverPermission, resultReceiver,

// scheduler, initialCode, initialData, initialExtras)

 

 

getResultData   ()  

得到發(fā)送廣播時(shí)設(shè)置的 initialData 的數(shù)據(jù);

 

 

getResultExtras (boolean makeMap)

If true then a new empty Map will be made for you if the current Map is null; if false you should be prepared to receive a null Map.

得到由

sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

// initialCode, initialData, initialExtras) ;

 

// sendOrderedBroadcast(intent, receiverPermission, resultReceiver,

// scheduler, initialCode, initialData, initialExtras)

initialExtras 傳入的參數(shù)。

實(shí)驗(yàn):我用上面兩個(gè)方法發(fā)了 initialExtras (這個(gè)一個(gè) Bundle )傳入的參數(shù)時(shí),只要不為空,那么 makeMap 是否為 true 和 false 都能夠得到數(shù)據(jù)。

 

isInitialStickyBroadcast   ()  

Returns true if the receiver is currently processing the initial value of a sticky broadcast -- that is, the value that was last broadcast and is currently held in the sticky cache, so this is not directly the result of a broadcast right now.

 

如果廣播接收者是目前處理的一個(gè)宿主的廣播的初始值,將返回 true , -  也就是說,這個(gè)值是最后的廣播出的值,目前正在舉行的宿主緩存,所以這并不是直接導(dǎo)致了現(xiàn)在的廣播。

 

實(shí)驗(yàn):在第三個(gè)應(yīng)用中調(diào)用這個(gè)方法,無論你用哪種方式發(fā)送廣播,這個(gè)方法得到的總是 false ;在發(fā)送廣播 的 resultReceiver 廣播接收者里面調(diào)用,得到的也是 false

 

 

isOrderedBroadcast   ()  

sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

  initialCode, initialData, initialExtras)

上面這個(gè)方法發(fā)送時(shí),得到的是 true;

判斷是否是有序廣播;

 

 

onReceive (Context context, Intent intent)

 

public IBinder peekService (Context myContext, Intent service)

Provide a binder to an already-running service. This method is synchronous and will not start the target service if it is not present, so it is safe to call from onReceive.

 

Parameters:

myContext The Context that had been passed to onReceive(Context, Intent)

service The Intent indicating the service you wish to use. See Context.startService(Intent) for more information.

setDebugUnregister (boolean debug)

Control inclusion of debugging help for mismatched calls to {@ Context#registerReceiver(BroadcastReceiver, IntentFilter) Context.registerReceiver()}. If called with true, before given to registerReceiver(), then the callstack of the following  Context.unregisterReceiver()  call is retained, to be printed if a later incorrect unregister call is made. Note that doing this requires retaining information about the BroadcastReceiver for

 

穩(wěn)定

產(chǎn)品高可用性高并發(fā)

貼心

項(xiàng)目群及時(shí)溝通

專業(yè)

產(chǎn)品經(jīng)理1v1支持

快速

MVP模式小步快跑

承諾

我們選擇聲譽(yù)

堅(jiān)持

10年專注高端品質(zhì)開發(fā)
  • 返回頂部