四大組件之廣播接收器BroadcastReceiver

概念引入:

 廣播(Broadcast)是一種廣泛運用的在應用程序之間傳輸信息的機制,在 Android 裏面有各種各樣的廣播,比如電池的使用狀態,類似於當手機鎖屏解鎖、收到短信電話、電量過低提示,應用程序也可以接受廣播並做出程序邏輯上的處理, 去實現我們給用戶的一些提示或者其他的一些操作,這都是通過廣播監聽系統動作鎖實現的

(1)你的應用可以使用它對外部事件進行過濾,只對感興趣的外部事件(如當電話呼入時,或者數據網絡可用時)進行接收並做出響應。廣播接收器沒有用戶界面。然而,它們可以啓動一個activity或serice來響應它們收到的信息,或者用NotificationManager來通知用戶。通知可以用很多種方式來吸引用戶的注意力,例如閃動背燈、震動、播放聲音等。一般來說是在狀態欄上放一個持久的圖標,用戶可以打開它並獲取消息。
(2)廣播接收者的註冊有兩種方法,分別是程序動態註冊和AndroidManifest文件中進行靜態註冊。
(3)動態註冊廣播接收器特點是當用來註冊的Activity關掉後,廣播也就失效了。靜態註冊無需擔憂廣播接收器是否被關閉,只要設備是開啓狀態,廣播接收器也是打開着的。


Android中的廣播接收器分爲兩種類型:標準廣播、有序廣播

標準廣播(Normal broadcasts):是一種完全異步執行的廣播,在廣播發出以後,所有的廣播接收器幾乎都會在同一時刻收到這一條廣播消息,因此它們之間沒有任何先後順序可言。這種廣播效率比較高,但通知也意味着它時無法被截斷的。

工作流程
這裏寫圖片描述

有序廣播(Ordered broadcasts):則是一種同步執行的廣播,在廣播發出之後,同一時刻只會有一個廣播接收器能夠收到這條廣播消息,當這個廣播接收器中的邏輯執行完畢後,廣播纔會繼續傳遞。所以此時的廣播接收器是有先後順序的,優先級高的廣播接收器就可以先收到這條廣播,並且前面的廣播接收器還可以階段正在傳遞的廣播,這樣後面的廣播接收器就無法收到這條廣播消息了。
這裏寫圖片描述

廣播的註冊方式:

廣播接收器的(構建)註冊廣播方式有兩種:在代碼中註冊(動態註冊)、在AndroidManifest.xml中註冊(靜態註冊)

動態註冊:廣播的接收者需要通過調用registerReceiver函數告訴系統,它對什麼樣的廣播有興趣,即指定IntentFilter,並且向系統註冊廣播接收器,即指定BroadcastReceiver:

IntentFilter counterActionFilter = new IntentFilter(CounterService.BROADCAST_COUNTER_ACTION);
registerReceiver(counterActionReceiver, counterActionFilter); 

第一個參數是繼承了BroadcastReceiver的類的實例對象
第二個參數是指定想要實現的動作(廣播接收器想要監聽什麼廣播,就在第二個參數中實現相應的action就可以了)

靜態註冊:

<receiver  android:name = ".接收廣播的類名">
    //並且在裏面添加
    <intent-filter>
          <action android:name="要接收的廣播"/>
    </intent-filter>
</receiver>

切記:動態註冊的廣播接收器一定都要取消註冊纔可以,可以在onDestroy()方法中通過調用unregisterReceiver()方法來實現

//解除註冊
public void onDestory(){
    unregisterReceiver(counterActionReceiver);
}

廣播的發送

發送標準廣播:用sendBroadcast(intent)方法
因爲已經確定了要接收的廣播,所以一個類中需要實現廣播的發送,並且要發送的廣播爲之前所接收的廣播
發送有序廣播:有序廣播類似於中央發紅頭文件,一級一級的傳播,中間可以被截斷,截斷以後,後面的廣播接收器將收不到這條廣播
發送有序廣播和之前發送標準廣播的區別不是很大,只需要將最後sendBroadcast(intent);方法改變成sendOrderedBroadcast(intent,null);

button.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                //標準廣播
                Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
                sendBroadcast(intent);


                //有序廣播
                Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
                 sendOrderedBroadcast(intent, null); 

                 //發送本地廣播
                Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent);
            }
        });

###本地廣播的使用
前面所介紹的發送和接收的廣播全部是屬於系統全局廣播,即發出的廣播可以被其他任何的任何應用程序收到,並且也可以接受到來自其他應用程序的廣播。這樣容易有安全問題,所以引入本地廣播

使用本地廣播只需要在代碼中動態註冊,通過本地廣播管理器(LocalBroadcastManager)的對象調用registerReceiver()方法動態的去註冊,然後記得必須在onDestroy()方法中取消註冊

package com.example.boradcasttest;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //獲取實例
        localBroadcastManager = LocalBroadcastManager.getInstance(this);

        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                 //發送本地廣播
                Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent);
            }
        });
        //動態註冊廣播接收器,切記要解除註冊
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
        localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);
    }
    @Override
        /*
        因爲在前面通過LocalBroadcastManager對象調用registerReceiver()方法
         進行了動態的註冊,所以在覆寫onDestroty()方法中需要取消註冊
         */

    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }

    //自定義的本地廣播接收器
    class LocalReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "本地接收到廣播", Toast.LENGTH_SHORT).show();
        }

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章