Android筆記-四大組件之Broadcast Receiver

簡(jiǎn)介

Broadcast Receiver迎变,即廣播接收器,顧名思義稠屠,通過(guò)廣播的方式進(jìn)行消息傳遞。

分類(lèi)

  • 標(biāo)準(zhǔn)廣播
    這是一種完全異步執(zhí)行的廣播,這種廣播發(fā)出后权埠,所有接收器之間幾乎同時(shí)收到消息榨了,它們之間沒(méi)有任何順序可言,因此這種廣播效率比較高攘蔽,無(wú)法被攔截龙屉。

  • 有序廣播
    這是一種同步執(zhí)行的廣播,這種廣播發(fā)出后满俗,各接收器是按照注冊(cè)的優(yōu)先級(jí)的順序來(lái)進(jìn)行接收的转捕,優(yōu)先級(jí)高的先接收,優(yōu)先級(jí)低的后接收唆垃,并且可以被中斷五芝,一旦被中斷則后續(xù)接收器則無(wú)法接收到此消息了。

使用方式

廣播使用方式基本相同辕万,在BroadcastReceiver類(lèi)中的onReceive()方法中處理接收器邏輯枢步,但是不能進(jìn)行耗時(shí)操作,因?yàn)樵谶@里不允許開(kāi)啟線(xiàn)程的蓄坏;另外廣播是有優(yōu)先級(jí)的价捧,優(yōu)先級(jí)高的先收到廣播丑念。

  • 標(biāo)準(zhǔn)廣播
    • 系統(tǒng)廣播

      • 靜態(tài)注冊(cè)

      第一步涡戳,編寫(xiě)廣播接收器處理代碼,該類(lèi)繼承自BroadcastReceiver類(lèi)

      public class BootCompleteReceiver extends BroadcastReceiver {
      
          @Override
          public void onReceive(Context context, Intent intent) {
              Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
          }
      }
      

      第二步脯倚,在manifest文件中聲明

      <receiver
          android:name=".broadcast.BootCompleteReceiver"
          android:enabled="true"
          android:exported="true">
          <intent-filter>
              <action android:name="android.intent.action.BOOT_COMPLETED" />
          </intent-filter>
      </receiver>
      

      第三步渔彰,添加權(quán)限

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

      靜態(tài)注冊(cè)的方式是通過(guò)xml在manifest文件中進(jìn)行注冊(cè),其特點(diǎn)是:在程序未啟動(dòng)的情況也能接收到廣播消息推正,并且無(wú)法取消注冊(cè)恍涂。

      • 動(dòng)態(tài)注冊(cè)

      第一步,編寫(xiě)廣播接收器處理代碼植榕,該類(lèi)繼承自BroadcastReceiver類(lèi)

      public class NetworkChangeReceiver extends BroadcastReceiver {
          @Override
          public void onReceive(Context context, Intent intent) {
      
              //get the state of network
              ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
              NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
      
              String state;
              if (networkInfo != null && networkInfo.isAvailable()) {
                  state = "available";
              } else {
                  state = "unavailable";
              }
      
              Toast.makeText(context, "Network is " + state, Toast.LENGTH_LONG).show();
          }
      }
      

      第二步再沧,在A(yíng)ctivity 中注冊(cè)及取消

      public class BroadcastDynamicSystemActivity extends AppCompatActivity {
      
          private IntentFilter intentFilter;
          private NetworkChangeReceiver networkChangeReceiver;
      
          public static void startAction(Context context) {
              context.startActivity(new Intent(context, BroadcastDynamicSystemActivity.class));
          }
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_broadcast_dynamic_system);
      
              //register network change broadcast receiver
              this.intentFilter = new IntentFilter();
              this.intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
              this.networkChangeReceiver = new NetworkChangeReceiver();
      
              registerReceiver(this.networkChangeReceiver, this.intentFilter);
          }
      
          @Override
          protected void onDestroy() {
              super.onDestroy();
      
              //unregister network change broadcast receiver
              unregisterReceiver(this.networkChangeReceiver);
          }
      }
      

      第三步,在manifest文件中添加網(wǎng)絡(luò)訪(fǎng)問(wèn)權(quán)限

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

      動(dòng)態(tài)注冊(cè)的流程是:先編寫(xiě)廣播接收器的處理方法(繼承自BroadcastReceiver類(lèi))尊残,然后在應(yīng)用的地方進(jìn)行注冊(cè)和取消注冊(cè)炒瘸。這種方式的特點(diǎn)是:
      1. 只有動(dòng)態(tài)注冊(cè)代碼執(zhí)行了才會(huì)接收廣播,沒(méi)執(zhí)行是不會(huì)收到廣播的寝衫;
      2. 需要實(shí)時(shí)取消注冊(cè)顷扩,以防內(nèi)存泄漏。

    • 自定義廣播

      • 標(biāo)準(zhǔn)廣播

      第一步慰毅,編寫(xiě)廣播接收器處理代碼隘截,該類(lèi)繼承自BroadcastReceiver類(lèi)

      public class MyStandardBroadcastReceiver extends BroadcastReceiver {
          @Override
          public void onReceive(Context context, Intent intent) {
              Toast.makeText(context, "My Standard Broadcast Receiver", Toast.LENGTH_LONG).show();
          }
      }
      

      第二步,在manifest中注冊(cè)(此為靜態(tài)注冊(cè)方式注冊(cè),亦可動(dòng)態(tài)方式注冊(cè))

      <receiver android:name=".broadcast.MyStandardBroadcastReceiver">
          <intent-filter>
              <action android:name="com.example.broadcast.MY_BROADCAST" />
          </intent-filter>
      </receiver>
      

      第三步婶芭,發(fā)送自定義廣播

      sendBroadcast(new Intent("com.example.broadcast.MY_BROADCAST"));
      

      這里需要注意的是廣播的action name必須一致东臀。

      • 有序廣播

      第一步,編寫(xiě)廣播接收器處理代碼雕擂,該類(lèi)繼承自BroadcastReceiver類(lèi)

      public class MyOrderedBroadcastReceiver extends BroadcastReceiver {
          @Override
          public void onReceive(Context context, Intent intent) {
              Toast.makeText(context, "My Ordered Broadcast Receiver", Toast.LENGTH_LONG).show();
              
              //中斷傳播
              abortBroadcast();
          }
      }
      

      第二步啡邑,在manifest中注冊(cè)(此為靜態(tài)方式注冊(cè),亦可動(dòng)態(tài)注冊(cè))

      <receiver android:name=".broadcast.MyOrderedBroadcastReceiver">
          <intent-filter android:priority="100">
              <action android:name="com.example.broadcast.MY_BROADCAST" />
          </intent-filter>
      </receiver>
      

      第三步井赌,發(fā)送自定義廣播

      sendOrderedBroadcast(new Intent("com.example.broadcast.MY_BROADCAST"), null);
      

      有序廣播和標(biāo)準(zhǔn)廣播使用方式上唯一區(qū)別在于發(fā)送方法不同以及有序廣播可以通過(guò)abortBroadcast()方法來(lái)中斷廣播的傳遞谤逼。

  • 本地廣播

    標(biāo)準(zhǔn)廣播都是全局的,即不僅本應(yīng)用會(huì)接收而且其他應(yīng)用也可以接收仇穗,因此如果一直發(fā)送標(biāo)準(zhǔn)廣播不僅會(huì)對(duì)系統(tǒng)造成污染流部,而且也會(huì)帶來(lái)安全隱患,為了解決這些問(wèn)題纹坐,Android系統(tǒng)引入了本地廣播機(jī)制枝冀。

    • 使用方法
      第一步,編寫(xiě)廣播接收器處理代碼耘子,該類(lèi)繼承自BroadcastReceiver類(lèi)

      public class LocalBroadcastReceiver extends BroadcastReceiver {
      
          @Override
          public void onReceive(Context context, Intent intent) {
              Toast.makeText(context, "Local Broadcast Receiver", Toast.LENGTH_LONG).show();
          }
      }
      

      第二步果漾,發(fā)送廣播

      private IntentFilter intentFilter;
      private LocalBroadcastReceiver localBroadcastReceiver;
      private LocalBroadcastManager localBroadcastManager;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          ……
          
          this.intentFilter = new IntentFilter();
          this.intentFilter.addAction("com.example.broadcast.MY_LOCAL_BROADCAST");
          this.localBroadcastManager = LocalBroadcastManager.getInstance(this);
          this.localBroadcastReceiver = new LocalBroadcastReceiver();
          this.localBroadcastManager.registerReceiver(this.localBroadcastReceiver, this.intentFilter);
      }
      
      @Override
      protected void onDestroy() {
          super.onDestroy();
          this.localBroadcastManager.unregisterReceiver(this.localBroadcastReceiver);
      }
      
      //發(fā)送本地廣播
      this.localBroadcastManager.sendBroadcast(new Intent("com.example.broadcast.MY_LOCAL_BROADCAST"));
      
    • 特點(diǎn)

      • 消息只在本應(yīng)用內(nèi)進(jìn)行傳遞;
      • 無(wú)法通過(guò)靜態(tài)注冊(cè)的方式進(jìn)行注冊(cè)谷誓;
      • 比系統(tǒng)全局廣播更高效绒障。

總結(jié)

  • 當(dāng)需要在程序未啟動(dòng)就接收廣播消息時(shí),使用靜態(tài)注冊(cè)方式注冊(cè)廣播捍歪;
  • 當(dāng)需要靈活控制接收或者不接受廣播消息時(shí)户辱,使用動(dòng)態(tài)注冊(cè)方式注冊(cè)廣播;
  • 當(dāng)廣播消息僅在本應(yīng)用內(nèi)部進(jìn)行傳遞糙臼,使用本地廣播更高效更安全庐镐;
  • 當(dāng)需要對(duì)廣播消息對(duì)傳遞進(jìn)行順序控制時(shí),使用有序廣播廣播变逃。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末必逆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子揽乱,更是在濱河造成了極大的恐慌名眉,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锤窑,死亡現(xiàn)場(chǎng)離奇詭異璧针,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)渊啰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)探橱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)申屹,“玉大人,你說(shuō)我怎么就攤上這事隧膏』┘ィ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵胞枕,是天一觀(guān)的道長(zhǎng)杆煞。 經(jīng)常有香客問(wèn)我,道長(zhǎng)腐泻,這世上最難降的妖魔是什么决乎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮派桩,結(jié)果婚禮上构诚,老公的妹妹穿的比我還像新娘。我一直安慰自己铆惑,他們只是感情好范嘱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著员魏,像睡著了一般丑蛤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上撕阎,一...
    開(kāi)封第一講書(shū)人閱讀 51,215評(píng)論 1 299
  • 那天受裹,我揣著相機(jī)與錄音,去河邊找鬼闻书。 笑死名斟,一個(gè)胖子當(dāng)著我的面吹牛脑慧,可吹牛的內(nèi)容都是我干的魄眉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼闷袒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼坑律!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起囊骤,我...
    開(kāi)封第一講書(shū)人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤晃择,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后也物,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體宫屠,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年滑蚯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浪蹂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抵栈。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖坤次,靈堂內(nèi)的尸體忽然破棺而出古劲,到底是詐尸還是另有隱情,我是刑警寧澤缰猴,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布产艾,位于F島的核電站,受9級(jí)特大地震影響滑绒,放射性物質(zhì)發(fā)生泄漏闷堡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一疑故、第九天 我趴在偏房一處隱蔽的房頂上張望缚窿。 院中可真熱鬧,春花似錦焰扳、人聲如沸倦零。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)扫茅。三九已至,卻和暖如春育瓜,著一層夾襖步出監(jiān)牢的瞬間葫隙,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工躏仇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恋脚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓焰手,卻偏偏與公主長(zhǎng)得像糟描,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子书妻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容