Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android四大組件之BroadcastReceiver詳細解析

Android四大組件之BroadcastReceiver詳細解析

編輯:關於Android編程

什麼是BroadcastReceiver?

BroadcastReceiver作為Android四大組件之一,在實際開發中也發揮著重要的作用,廣播機制在Android程序通信中至關重要,廣播其實與我們現實生活中的電台很相似,電台在某個頻道上發送它的內容,那麼只要有在收聽這個頻道的人都會收到這些內容。在Android中,廣播也同樣分為兩個角色:廣播發送者廣播接收者


BroadcastReceiver的應用場景

1.在一個應用中,我們的Activity與Service的通信就需要用到廣播來作為中介,比如Service在後台進行著下載任務,當下載成功後,需要通知Activity,這個時候就可以用到廣播了。
2.在Android中,有時候兩個app之間需要進行通信,比如你再一個app裡面點擊某個按鈕時需要通知另外一個app的啟動,這個時候就需要在點擊按鈕時發送一個廣播,而另外那個app就是作為廣播接收者。
3.另外一種應用場景是由系統來發出廣播,你的應用充當廣播接收者的角色,比如你需要在手機斷網時在你的App中馬上做出相應提示,在手機啟動時讓你的app收到系統發來的廣播:“手機啟動了哦!”,然後你的應用就會馬上進行相應的操作,比如開機自啟動等等。


廣播最大的特點就是:發送方與接收方是解耦的,即發送方雖然發送了廣播,但它並不關系接收方到底收到了沒有,或者接受方拿到廣播之後要干嘛,而接收方只需要注冊有這個廣播,就會在收到相同類型的廣播消息時做出相應。而且廣播可以是一個發送者,多個接收者。




如何使用廣播?

前面說過了,廣播是需要注冊的,也就是需要注冊一個廣播接收者,在Android中,廣播注冊分為兩種方式:
1.靜態注冊廣播【在AndroidManifest.xml中注冊BroadcastReceiver】
2.動態注冊廣播【通過代碼注冊BroadcastReceiver】


靜態方式注冊自定義廣播

1.發送廣播,這裡以Activity為例,在Activity的onCreate中發送一個廣播

 

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		Intent intent = new Intent();
		//這條廣播的標志
		intent.setAction("broadcast_test");
		//攜帶數據
		intent.putExtra("msg", "這是自定義靜態廣播消息");
		//發送廣播
		sendBroadcast(intent);
		
	}
}

關鍵在於sendBroadcast這個方法,通過這個方法將廣播的intent發出,可以通過intent攜帶數據
注意:setAction表示為intent設置上一個action,相當於這個廣播的一個標志,只有與這個標志匹配的廣播接收者才會接收到這個消息。

 

 

2.創建廣播接收者,新建一個類繼承於BroadCastReceiver,實現其中的onReceive方法

 

public class MyReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		
		//獲得廣播中的數據
		String msg = intent.getStringExtra("msg");
		//模擬響應
		Toast.makeText(context, msg, 1000).show();
		
	}

}

在onReceive方法中進行接收到廣播後做出的各種響應操作,onReceive方法有兩個參數:context表示發送廣播的那個地方,一個就是廣播所攜帶的intent咯,也就是上一步中的sendBroadcast中發送過來的intent。所以自然而然就能夠從中拿到相應的數據。

 

 

3.在AndroidManifest.xml中注冊我們定義好的廣播

\

注意:action標簽的name一定要與第一步中intent所設置的action一致,才能收到廣播

 

 

運行

\

 

 

 

動態方式注冊自定義廣播

1.發送廣播,這裡以Activity為例,在Activity的onCreate中發送一個廣播

 

 

public class MainActivity extends Activity {
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//動態注冊receiver的Intent過濾器和action
		IntentFilter filter = new IntentFilter();
		filter.addAction("broadcast_test");
		registerReceiver(new MyReceiver(), filter);
		
		Intent intent = new Intent();
		//這條廣播的標志
		intent.setAction("broadcast_test");
		//攜帶數據
		intent.putExtra("msg", "這是自定義動態廣播消息");
		//發送廣播
		sendBroadcast(intent);
		
	}
}


 

可以看到,這裡與靜態的不同就在於多了IntentFileter的生成和receiver的注冊,相當於將在xml中receiver的注冊變成用代碼來進行注冊

 



2.同樣需要有廣播接收者,新建一個類繼承於BroadCastReceiver,實現其中的onReceive方法

 

public class MyReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		
		//獲得廣播中的數據
		String msg = intent.getStringExtra("msg");
		//模擬響應
		Toast.makeText(context, msg, 1000).show();
		
	}

}


 

 

運行

\

 

 

上面演示了如何靜態和動態發送自定義廣播,下面通過手機飛行模式的開關來演示如何靜態和動態接收來自系統的廣播

靜態接收系統廣播

1.新建一個廣播接收者,用來接收特定的系統廣播

 

 

public class MyReceiver extends BroadcastReceiver{
	
	//用來作為標志,判斷是開啟還是關閉
	private static int count = 0;

	//如果是飛行模式狀態變化的廣播,就執行操作
	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		//每改變一次飛行狀態,count就+1
		count++;
		switch (count%2) {
		//如果余數為1,說明count是奇數,也就是操作--->開啟飛行模式
		case 1:
			Toast.makeText(context, "開啟飛行模式", 1000).show();
			break;
		//如果余數為0,說明count是偶數,也就是操作--->關閉飛行模式
		case 0:
			Toast.makeText(context, "關閉飛行模式", 1000).show();
			break;
		}		
	}
}


 

 

 

2.在AndroidManifest中注冊該廣播接收者

 


	
                
        


 

注意這裡用的action是android.intent.action.AIRPLANE_MODE,這是由系統提供的當手機飛行狀態改變時發出的廣播,正是因為此處將MyReceiver注冊為接收指定的系統廣播,才會在onReceive中接收到這個廣播

 

 

 

動態接收系統廣播

1.新建一個廣播接收者,與靜態的基本一致

 

 

public class MyReceiver extends BroadcastReceiver{
	
	//用來作為標志,判斷是開啟還是關閉
	private static int count = 0;

	//如果是飛行模式狀態變化的廣播,就執行操作
	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		//每改變一次飛行狀態,count就+1
		count++;
		switch (count%2) {
		//如果余數為1,說明count是奇數,也就是操作--->開啟飛行模式
		case 1:
			Toast.makeText(context, "開啟飛行模式", 1000).show();
			break;
		//如果余數為0,說明count是偶數,也就是操作--->關閉飛行模式
		case 0:
			Toast.makeText(context, "關閉飛行模式", 1000).show();
			break;
		}		
	}
}

 

2.在Activity中對它進行注冊

 

public class MainActivity extends Activity {
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		IntentFilter filter = new IntentFilter();
		//這裡將飛行模式改變的Action添加到過濾器中
		filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
		registerReceiver(new MyReceiver(), filter);
	}
}


 

 

運行

\

 

 

如何取消注冊廣播?

在上面的動態注冊自定義廣播的例子中,如果你嘗試將當前應用程序kill掉,就會發現Logcat報出如下錯誤:

\


從報錯信息中可以看出,是由於我們是動態注冊的自定義廣播,所以在Activity被銷毀時,廣播接收者將不再接收相應的廣播,系統要求必須注銷該廣播
解決方法很簡單,只需要在Activity的onDestroy方法中,調用unregisterReceiver(myreceiver);就可以在Activity退出時注銷廣播:

 

@Override
protected void onDestroy() {
	// TODO Auto-generated method stub
	super.onDestroy();
	unregisterReceiver(myreceiver);
}


 

 

 

有序廣播

上面所演示的廣播都是通過sendBroadcast發送出去的,是無序的廣播,有時候廣播接收者是有多個的,如果我們需要將它們設定一定的優先級,就需要通過sendOrderedBroadcast()來發送有序廣播


下面通過自定義三個廣播接收者和一個廣播發送者,演示如何使用有序廣播:
1.創建三個廣播接收者

 

有序廣播
上面所演示的廣播都是通過sendBroadcast發送出去的,是無序的廣播,有時候廣播接收者是有多個的,如果我們需要將它們設定一定的優先級,就需要通過sendOrderedBroadcast()來發送有序廣播


下面通過自定義三個廣播接收者和一個廣播發送者,演示如何使用有序廣播:
1.創建三個廣播接收者

MyFirstReceiver.java:

 

public class MyFirstReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		String msg = intent.getStringExtra("msg");
		Log.d("MyFirstReceiver", msg);
		//將數據傳輸給下一個廣播接收者
		setResultData("This is the Second Msg From MyFirstReceiver");
	}

}


 

 

MySecondReceiver.java:

 

public class MySecondReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		//獲得上一個廣播接收者傳過來的數據
		String msg = getResultData();
		Log.d("MySecondReceiver", msg);
		//將數據傳輸給下一個廣播接收者
		setResultData("This is the Third Msg From MySecondReceiver");
	}

}


 

 

MyThirdReceiver.java:

 

public class MyThirdReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		//獲得上一個廣播接收者傳過來的數據
		String msg = getResultData();
		Log.d("MyThirdReceiver", msg);
	}

}


 

2.在AndroidManifest.xml中注冊三個廣播接收者:

 


           
                
           

        

           
                
           

        

           
                
           


 

注意到這裡每個接收者都多加了一個屬性:priority,這個屬性表示有序廣播中的優先級,值越高表示優先級越高,那麼當廣播發出時,優先級最高的便會第一個接收到廣播並攔截下來。然後才會繼續往優先級低的傳遞下去。

 

3.發送有序廣播

 

public class MainActivity extends Activity {
		
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		Intent intent = new Intent("OrderBroadcast");
		intent.putExtra("msg", "This is the First Msg From Activity");
		sendOrderedBroadcast(intent, null);
	}
	
}


 

 

運行,查看Logcat打印結果:

\

 

 

 

局部廣播

上面的有序廣播和無序廣播都是屬於全局廣播,也就是當發出這個廣播,整個系統都有機會接收到該廣播,但有時候出於安全性問題的考慮,Android還提供了局部廣播,這種廣播只有在同一個App內的廣播接收器才能收到,其它應用不會接收到。


局部廣播的使用:

 

 

public class MainActivity extends Activity {
	
	private MyReceiver receiver = new MyReceiver();
		
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
		
		IntentFilter filter = new IntentFilter();
		filter.addAction("broadcasttest");
		//注冊局部廣播
		manager.registerReceiver(receiver , filter);
		
		Intent intent = new Intent();
		intent.setAction("broadcasttest");
		//發送廣播
		manager.sendBroadcast(intent);
		
	}
	
}


 

 

 

BroadcastReceiver的生命周期

【三部曲】調用廣播--->執行onReceive()--->onReceive方法return之後即結束該廣播






該注意的點

Android中規定了BroadCastReceiver不能處理復雜長時間的邏輯操作,如果在onReceive方法在10s內沒法執行完畢,則系統會視之為未響應狀態,可能會報ANR錯誤。可以將這些耗時操作放在Service中開辟子線程去執行。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved