簡述:
廣播接收器,也被稱爲全局事件,或系統事件。在Android中,有一些操作完成以後,會發送廣播,比如說發出一條短信,或打出一個電話,如果某個程序接收了這個廣播,就會做相應的處理。這個廣播跟我們傳統意義中的電臺廣播有些相似之處。之所以叫做廣播,就是因爲它只負責“說”而不管你“聽不聽“,也就是不管你接收方如何處理。另外,廣播可以被不只一個應用程序所接收,當然也可能不被任何應用程序所接收。廣播機制最大的特點就是發送方並不關心接收方是否接到數據,也不關心接收方是如何處理數據的。Android中廣播的是操作系統中產生的各種各樣的事件。例如,收到一條短信就會產生一個收到短信息的事件。而Android操作系統一旦內部產生了這些事件,就會向所有的廣播接收器對象來廣播這些事件。
理論部分:
廣播機制的三要素:
Android廣播機制包含三個基本要素:1、廣播(Broadcast) - 用於發送廣播(並不是說Android中存在Broadcast實體類,其本質就是一個Intent意圖);
2、廣播接收器(BroadcastReceiver) - 用於接收廣播;
3、意圖內容(Intent)-用於保存廣播相關信息的媒介。
Broadcast是一種廣泛運用的在應用程序之間傳輸信息的機制。而BroadcastReceiver是對發送出來的Broadcast進行過濾接受並響應的一類組件。
廣播的生命週期:
1、廣播接收器僅在它執行這個方法時處於活躍狀態。當onReceive()返回後,它即爲失活狀態。2、擁有一個活躍狀態的廣播接收器的進程被保護起來而不會被殺死,但僅擁有失活狀態組件的進程則會在其它進程需要它所佔有的內存的時候隨時被殺掉。
3、如果響應一個廣播信息需要很長的一段時間,一般會將其納入一個衍生的線程中去完成,而不是在主線程內完成它,從而保證用戶交互過程的流暢。
廣播的分類:
根據是否跨進程,可分爲全局廣播和本地廣播。全局廣播:廣播可以發送給不同進程,可以接收不同進程廣播消息;
本地廣播:使用LocalBroadcastManager.getInstance(context).sendBroadcast發送本地廣播
使用本地廣播相比全局廣播有如下優勢:
1.保護隱私: 廣播的數據不會離開當前進程,不用擔心數據會泄露;
2.安全: 其他應用不可能發送該廣播給當前進程, 因此不用擔心安全漏洞;
3.效率: 與全局廣播在整個系統傳播相比,本地廣播效率更高。
簡單使用:
全局廣播
現在簡單的使用接收一個網絡狀態變化的廣播。
1、註冊廣播接收器:
廣播接收器的註冊有兩種形式:隱式註冊和顯式註冊,又或者叫靜態註冊和動態註冊。注意一般的廣播基本上兩種都可以,但是有些是不行的,比如監聽屏幕亮和熄屏的只能動態註冊,Android N 以後網絡狀態的變化也只能動態註冊。
隱式註冊(靜態註冊):
<receiver
android:name=".NetChangeBroadcastReceiver"
android:exported="true"
android:permission="android.permission.ACCESS_NETWORK_STATE"
android:process=":remote">
<intent-filter android:priority="1000">
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
xml屬性:android:name:此broadcastReceiver類名;
android:exported:此broadcastReceiver能否接收其他App的發出的廣播,這個屬性默認值有點意思,其默認值是由receiver中有無intent-filter決定的,如果有intent-filter,默認值爲true,否則爲false。(同樣的,activity/service中的此屬性默認值一樣遵循此規則)同時,需要注意的是,這個值的設定是以application或者application user id爲界的,而非進程爲界(一個應用中可能含有多個進程);
android:permission :如果設置,具有相應權限的廣播發送方發送的廣播才能被此broadcastReceiver所接收;
android:process :broadcastReceiver運行所處的進程。默認爲app的進程。可以指定獨立的進程(Android四大基本組件都可以通過此屬性指定自己的獨立進程)。
android:priority :在<intent-filter/>標籤中可以設置該廣播接收器的優先級,範圍“-1000~1000”;
顯式註冊(動態註冊):
@Override
protected void onResume() {
super.onResume();
NetChangeBroadcastReceiver netChangeBroadcastReceiver = new NetChangeBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
filter.setPriority(1000);
MainActivity.this.registerReceiver(netChangeBroadcastReceiver,filter);
}
2、擴展BroadcastReceiverpublic class NetChangeBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "網絡狀態發生改變", Toast.LENGTH_SHORT).show();
if ("android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction())){
ConnectivityManager connectivityManager=(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mobNetInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
NetworkInfo wifiNetInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
Toast.makeText(context, "網絡變化了", Toast.LENGTH_SHORT).show();
if (!mobNetInfo.isConnected() && !wifiNetInfo.isConnected()) {
Toast.makeText(context, "網絡不可以用", Toast.LENGTH_SHORT).show();
//改變背景或者 處理網絡的全局變量
}else {
//改變背景或者 處理網絡的全局變量
}
}
}
}
ok,這樣一個全局廣播接收就算寫完了。本地廣播:
本地廣播的使用採用動態的註冊方式,使用上面基本上遵循上述的步驟。具體的使用如下:1、發送本地廣播:
首先在Oncreate()方法中實例化一個LocalBroadcastManager 。
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
然後在來看發送本地廣播的代碼:LocalBroadcastManager.getInstance(this);
private void sendLocalBroadcastReceiver (){
Intent intent = new Intent();
intent.setAction("mylocalbroadcastReceiver");
intent.putExtra("local","這是一個本地廣播!");
localBroadcastManager.sendBroadcast(intent);
}
2、註冊本地廣播:private void registerLocalBroadcast(){
receiver = new InnerBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("mylocalbroadcastReceiver");
localBroadcastManager.registerReceiver(receiver,filter);
}
3、擴展BrocastReceiver:public class LocalBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if ("mylocalbroadcastReceiver".equals(intent.getAction())){
String local = intent.getStringExtra("local");
Toast.makeText(context, local, Toast.LENGTH_SHORT).show();
}
}
}
本地廣播的使用就此完畢!!!