天天看點

【從零到一】Android四大元件(二) | BroadcastReceiver(廣播接收器)1. 廣播接收器是什麼2. 廣播的實作原理3. 廣播的基本用法

目錄

  • 1. 廣播接收器是什麼
    •  1.1 廣播
    •  1.2 廣播接收器
  • 2. 廣播的實作原理
    •  2.1 廣播的設計模式和模型
    •  2.2 廣播的實作流程
  • 3. 廣播的基本用法
    •  3.1 建立BroadcastReceiver
    •  3.2 注冊BroadcastReceiver
      •   3.2.1靜态注冊(7.0之後部分情況已不可用)
      •   3.2.2動态注冊
    •  3.3 BroadcastSender向AMS發送廣播
      •   3.3.1 如何發送廣播
      •   3.3.2 廣播的類型

1. 廣播接收器是什麼

 1.1 廣播

  在認識廣播接收器(

BroadcastReceiver

)之前,先了解一下什麼是廣播(

Broadcast

)。

Broadcast

是一種廣泛應用在應用程式之間傳輸資訊的機制,分為廣播發送器和廣播接收器。Android提供了一套完整的API,允許應用之間自由地發送和接收廣播。

 1.2 廣播接收器

  廣播接收器(即

BroadcastReceiver

)是Android四大元件之一,屬于

消息型元件

,是一個全局的監聽器,用于接收系統和應用發送的廣播,并作出響應。

BroadcastReceiver

不僅可以在

AndroidManifest.xml

靜态注冊

,也可以

動态注冊

(動态注冊的廣播需要在應用啟動後才能進行注冊并接收廣播)。跟

Activity

類似的,

BroadcastReceiver

需要借助

Intent

發送廣播。

  了解完基本概念,接下來讓我們探究一下廣播的實作原理吧。

2. 廣播的實作原理

  探究廣播實作原理,我們先從廣播的

設計模式

出發,再探究它的具體

實作流程

 2.1 廣播的設計模式和模型

  Android中的廣播使用的是

設計模式

中的

觀察者模式

模型

基于消息的釋出/訂閱事件模型

  從

設計模式

來看,廣播的發送器和接收器極大程度的解耦,使得系統友善內建,容易擴充。

  從

模型

來看,模型成員的對應關系如下:

  • 消息發送者(廣播發送器)
  • 消息訂閱者(廣播接收器)
  • 消息中心(Activity服務管理(Activity Manager Service),簡稱AMS)

 2.2 廣播的實作流程

  廣播的實作流程簡圖:

【從零到一】Android四大元件(二) | BroadcastReceiver(廣播接收器)1. 廣播接收器是什麼2. 廣播的實作原理3. 廣播的基本用法

具體流程:

  1. 廣播接收器(

    BroadcastReceiver

    )通過Binder機制在

    AMS

    中注冊
  2. 廣播發送器(

    BroadcastSender

    )通過Binder機制向

    AMS

    發送廣播
  3. AMS

    再講廣播發送到符合條件(

    IntentFilter

    /

    Permission

    等)的

    BroadcastReceiver

    相應的消息循環隊列中
  4. BroadcastReceiver

    通過消息循環執行拿到廣播,回調

    BroadcastReceiver

    中的

    onReceive()

    方法

3. 廣播的基本用法

  通過上面的學習,我們已經對廣播的實作原理有所了解。這一節我們就來具體了解一下如何使用好廣播。

 3.1 建立BroadcastReceiver

  建立一個廣播接收器(

BroadcastReceiver

)其實很簡單,分為兩個步驟:

  1. 建立一個類,并讓它繼承自

    BroadcastReceiver

    類;
  2. 在這個類中重寫父類的抽象方法

    onReceive()

代碼示範:

//1.建立一個類,并讓它繼承自BroadcastReceiver類
public class MyBroadcastReceiver extends BroadcastReceiver {
    
    //2.重寫父類的抽象方法onReceive()
    @Override
    public void onReceive(Context context, Intent intent) {
        //接收廣播後的邏輯(...)
    }
}
           

  原理正如上一節所講到的,

BroadcastReceiver

接收到廣播後會自動回調

onReceive()

方法。我們隻需要在

onReceive()

方法中實作具體的邏輯就好了。預設情況下,

BroadcastReceiver

會在

UI線程

中運作,是以不能執行

耗時操作

  

 3.2 注冊BroadcastReceiver

  

BroadcastReceiver

的注冊方式分為

靜态注冊

動态注冊

  接下來我們分别通過兩種方式,試着注冊

BroadcastReceiver

  3.2.1靜态注冊(7.0之後部分情況已不可用)

  在首次啟動APP時,系統會

自動執行個體化

靜态注冊的類,并注冊到系統中。

  注冊方式:在

AndroidManifest.xml

中通過

receiver

标簽注冊,并根據相應的監聽内容在

intent-filter

中添加相應的

action

<receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"//表示啟用這個廣播接收器
            android:exported="true">//表示允許這個廣播接收器接收本程式以外的廣播
			<intent-filter>
				//用于接收網絡狀态改變時發出的廣播
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
            </intent-filter>
		</receiver>
           

  最後别忘了根據相應的監聽内容,添加相應的

權限

  3.2.2動态注冊

  注冊方式:在代碼中調用

Context.registerReceiver()

方法:

public class MainActivity extends AppCompatActivity {

    private MyBroadcastReceiver myBroadcastReceiver;
    private IntentFilter intentFilter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //1.執行個體化 MyBroadcastReceiver、IntentFilter
        myBroadcastReceiver = new MyBroadcastReceiver();
        intentFilter = new IntentFilter();

        //2.設定myBroadcastReceiver監聽的廣播内容
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");

        //3.動态注冊myBroadcastReceiver
        registerReceiver(myBroadcastReceiver,intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //4.銷毀myBroadcastReceiver
        unregisterReceiver(myBroadcastReceiver);
    }
}
           

 3.3 BroadcastSender向AMS發送廣播

  介紹完怎麼建立、注冊

BroadcastReceiver

,是不是感覺還缺點什麼呢?沒錯,上面執行個體裡

BroadcastReceiver

接收的是系統廣播,那麼怎麼樣讓

BroadcastReceiver

接收我們自定義的廣播呢?那就涉及到怎樣發送自定義的廣播了。

  3.3.1 如何發送廣播

  廣播是使用

Intent

來辨別的,是以發送廣播隻需兩步:

  1. 把廣播的值傳入到

    Intent

  2. BroadcastSender将此廣播的

    Intent

    通過

    sendBroadcast()

    方法發送出去

代碼示範:

Intent intent =new Intent("com.macardo.broadcastreceiver.MyBroadcast");
	sendBroadcast(intent);
           

  3.3.2 廣播的類型

  1. 系統廣播(

    System Broadcast

  • System Broadcast

    是Android中内置的廣播,手機的基本操作都擁有一個廣播。每個系統廣播都擁有指定的

    intent-filter

    action

  • 使用

    System Broadcast

    時,隻需要在注冊廣播接收器時指定相關操作的

    action

    即可,不需要手動發送廣播,當執行相關操作時會自動執行

    System Broadcast

  1. 普通廣播(

    Normal Broadcast

  • 開發者自己定義Intent的廣播,發送廣播:
Intent intent =new Intent("com.macardo.broadcastreceiver.MyBroadcast");
		sendBroadcast(intent);
           
  • 當注冊的

    BroadcastReceiver

    中的

    action

    與發送的廣播中的

    action

    相同時就接收上述廣播
  1. 有序廣播(

    Ordered Broadcast

  • 發送有序廣播:
//發送有序廣播
		//參數1:intent 
		//參數2:與權限相關的字元串
		sendOrderedBroadcast(intent,null);
           
  • 發送的廣播按照

    BroadcastReceiver

    的優先級接收
//方式1.在AndroidManifest.xml檔案中設定優先級
		<intent-filter android:priority="1000">
			<action android:name="..."/>
		</intent-filter>
	
		//方式2.代碼中設定優先級
		intentFilter.setPriority(1000);
           
  • 先接收廣播的

    BroadcastReceiver

    可以對廣播進行截斷或修改,之後接收該廣播的

    BroadcastReceiver

    不再接收到次廣播或接收到被修改的廣播
//截斷廣播,在onReceive()方法中調用
		abortBroadcast();
           
  1. App應用内廣播(

    Local Broadcast

  • 使用

    Local Broadcast

    的情況:因為

    exported

    對于有

    intent-filter

    情況下預設值為

    true

    ,是以Android中的廣播可以跨應用進行通訊。那麼如果其他App發送的廣播與目前App中的廣播接收器的

    action

    相同時,目前App将接受廣播并處理;如果其他App注冊與目前App一緻的

    intent-filter

    用于接收廣播,擷取廣播具體資訊,會出現安全性、效率性的問題。
  • 使用方法:通過

    LocalBroadcastManager.getInstance(this)

    方法擷取一個

    LocalBroadcastManager

    執行個體,然後用

    LocalBroadcastManager

    提供的

    registerReceiver()

    unregisterReceiver()

    方法來動态注冊和取消接收器以及

    sendBroadcast()

    方法發送本地廣播

代碼示範:

public class MainActivity extends AppCompatActivity {

    private MyBroadcastReceiver myBroadcastReceiver;
    private IntentFilter intentFilter;
    private LocalBroadcastManager localBroadcastManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //1.執行個體化 MyBroadcastReceiver、IntentFilter
        myBroadcastReceiver = new MyBroadcastReceiver();
        intentFilter = new IntentFilter();
        //2.執行個體化LocalBroadcastManager
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        //3.設定myBroadcastReceiver監聽的廣播内容
        intentFilter.addAction("com.macardo.broadcastreceiver.MyBroadcast");
        //4.調用LocalBroadcastManager單一執行個體的registerReceiver()方法進行動态注冊
        localBroadcastManager.registerReceiver(myBroadcastReceiver,intentFilter);
        
        Button button =findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent =new Intent("com.macardo.broadcastreceiver.MyBroadcast");
                //發送App應用内廣播
                localBroadcastManager.sendBroadcast(intent);
            }
        });

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //5.銷毀myBroadcastReceiver
        localBroadcastManager.unregisterReceiver(myBroadcastReceiver);
    }
}
           

  至此,

BroadcastReceiver(廣播接收器)

的基礎知識就講完了,謝謝觀看。

Github項目位址:BroadcastReceiverDemo