四大組件之BroadcastReceiver

廣播接收者

概念

Android中的廣播機制比我們日常生活中接觸的廣播更加靈活,Android中的每個應用程序都可以對自己感興趣的廣播進行註冊,這樣做的好處是我只接收我需要的廣播,其他廣播直接忽略。這些廣播可以是來自於系統也可以是用戶自定義的廣播。

廣播的類型:

標準廣播:一套完全異步執行的廣播,在廣播發出去之後,所有的廣播接收者幾乎同時收到廣播,接收者之間沒有先後順序的優先級之分。特點的效率高。

有序廣播:同步執行的廣播,同一時刻只能有一個廣播接收者收到廣播,噹噹前廣播接收者執行完自己的邏輯之後,廣播纔會繼續向下傳遞。優先級越高的廣播接受者越先收到廣播,同時先收到的廣播接受者可以截斷廣播,阻止廣播繼續向下傳遞。
廣播的優先級設定:-1000-1000
有些情況下,某些廣播接受者必須要接收到廣播(防止其他優先級高的接收者阻攔),可以設置爲結果接收者(resultReceive):表示所有廣播接收者都接收到廣播之後,它才接收,並且一定會接收

定義方式:

定義一個類繼承BroadcastReceiver,重寫onReceive()方法即可,在該方法內部不要實現過多的邏輯或耗時操作,因爲廣播不能開啓子線程。在清單文件中配置該類,指定接收的廣播種類
廣播是通過intent發送的,intent中會攜帶一個action,系統會在所有清單文件中尋找,看哪一個廣播接收者的intent-filter和廣播中的intent是匹配的,那麼這個廣播接收者就會收到這條廣播
廣播接收者所在進程即便沒有啓動,廣播發送出來時,系統也會啓動這個進程,然後把廣播交給廣播接收者
一個廣播接收者可以接受多種廣播,定義多個action即可

廣播接收者註冊:

清單文件註冊:廣播接收者永遠生效,除非卸載應用,或者手動停止進程。
設置接收開啓啓動的廣播

<receiver
	android:name=".MyReceiver"
	android:enabled="true"
	android:exported="true">
	<intent-filter>
		<action android:name="android.intent.action.BOOT_COMPLETED"/>
	</intent-filter>
</receiver>
權限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
使用代碼註冊:需要廣播接收者生效時,註冊它,不需要時,一定要反註冊它,反註冊之後,廣播接收者就失效了。
private IntentFilter mIntentFilter;
private MyReceiver mReceiver;

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

	mIntentFilter = new IntentFilter();
	mIntentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
	mReceiver = new MyReceiver();
	registerReceiver(mReceiver, mIntentFilter);
}

class myReceive extends BroadcastReceiver{
	@Override
	public void onReceive(Context context, Intent intent) {
		//實現邏輯
	}
}

@Override
protected void onDestroy() {
	super.onDestroy();
	unregisterReceiver(mReceiver);
}
特殊廣播接收者,必須代碼註冊:屏幕開關、電量改變等
在程序中動態註冊廣播必須要在代碼中取消註冊,一般情況下在Activity的onDestory()方法中取消註冊
靜態註冊廣播需要在Mainfest中進行配置,可以收到程序在沒有啓動狀態下的廣播接收
當一條廣播被髮送出來時,系統是在所有清單文件中遍歷,通過匹配意圖過濾器找到能接收這條廣播的廣播接收者
發送自定義廣播
public class MyReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		//處理收到廣播的邏輯
	}
}

<receiver
	android:name=".MyReceiver"
	android:enabled="true"
	android:exported="true">
	<intent-filter>
		<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
	</intent-filter>
</receiver>

protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	Button button = (Button) findViewById(R.id.button);
	button.setOnClickListener(new View.OnClickListener() {
		@Override
		public void onClick(View v) {
			Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
			sendBroadcast(intent);
		}
	});
}

本地廣播

使用LocalBroadcastManager對廣播進行管理,並提供發送和註冊廣播接收器的方法。
本地廣播無法通過靜態方式註冊,因爲靜態註冊就是爲了讓程序在未啓動的時候也能收到廣播,而發生本地廣播時,我們的程序是肯定啓動了。
本地廣播的優點:
可以明確地知道正在發送的廣播不會離開我們的程序,因此不必擔心機密數據泄露
其他的程序無法將廣播發送到我們程序的內部,因此不需要擔心會有安全問題
發送本地廣播比發送系統全局廣播將會更加高效
public class MainActivity extends AppCompatActivity {
    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 View.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
    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }

    class LocalReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
        }
    }
}







發佈了39 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章