BroadCastReceiver為廣播接收器益愈,它用于接收廣播intent夏醉。
廣播是一種廣泛運用在應用程序之間傳輸信息的機制存和。而 BroadcastReceiver 是對發(fā)送出來的廣播進行過濾接收并響應的一類組件逸邦;
BroadcastReceiver 自身并不實現(xiàn)圖形用戶界面嫌褪,但是當它收到某個通知后旦部,BroadcastReceiver可以啟動Activity作為響應, 或者通過 NotificationMananger提醒用戶祈搜,或者啟動 Service 等等。
在android系統(tǒng)里有各種各樣的廣播士八,例如:
- 電池電量使用狀態(tài)
- 電話和短信的接收
- 改變了語言
廣播作為Android組件間的通信方式容燕,可以使用的場景如下:
1.同一app內(nèi)部的同一組件內(nèi)的消息通信(單個或多個線程之間);
2.同一app內(nèi)部的不同組件之間的消息通信(單個進程)婚度;
3.同一app具有多個進程的不同組件之間的消息通信蘸秘;
4.不同app之間的組件之間消息通信;
5.Android系統(tǒng)在特定情況下與App之間的消息通信。
自定義BroadCastReceiver
自定義廣播接收器需要繼承基類BroadcastReceivre醋虏,并實現(xiàn)抽象方法onReceive(context, intent)方法寻咒。廣播接收器接收到相應廣播后,會自動回到onReceive(..)方法颈嚼。
默認情況下毛秘,廣播接收器也是運行在UI線程,因此阻课,onReceive方法中不能執(zhí)行太耗時的操作叫挟。否則將因此ANR。
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if ( intent != null ) {
if (TextUtils.equals(intent.getAction(), MainActivity.BROADCAST_ACTION)) {
String toast = intent.getStringExtra("toast");
Toast.makeText(context, toast, Toast.LENGTH_SHORT).show();
}
}
}
}
注冊BroadCastReceiver
- 靜態(tài)注冊
<receiver android:name="com.example.broadcasttest.MyBroadcastReceiver" >
<intent-filter >
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
在AndroidManifest.xml里面注冊限煞。intent-filter用于指定此廣播接收器將用于接收的特定的廣播類型抹恳。
- 動態(tài)注冊
動態(tài)注冊時,無須在AndroidManifest中注冊<receiver />組件晰骑。
官方建議在onStart方法中注冊适秩,在onstop方法中解除注冊
public class MainActivity extends Activity {
public static final String BROADCAST_ACTION =
"com.example.broadcasttest.MY_BROADCAST";
private MyBroadcastReceiver mBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BROADCAST_ACTION);
//為BroadcastReceiver指定action,使之用于接收同action的廣播
registerReceiver(mBroadcastReceiver, intentFilter);
//注冊BroadcastReceiver
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mBroadcastReceiver);
//解除注冊
}
}
發(fā)送廣播
利用sendBroadcast方法發(fā)送廣播
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
intent.putExtra("toast", "MyBroadcastReceiver");
sendBroadcast(intent);
其中setAction(..)對應于注冊BroadcastReceiver時在intentFilter中定添加的action硕舆。
廣播的類型
根據(jù)廣播的發(fā)送方式秽荞,可以將其分為以下幾種類型:
- Normal Broadcast:普通廣播
- System Broadcast: 系統(tǒng)廣播
- Ordered broadcast:有序廣播
- Local Broadcast:App應用內(nèi)廣播
Android中的廣播可以跨進程甚至跨App直接通信,且注冊是exported對于有intent-filter的情況下默認值是true抚官,由此將可能出現(xiàn)安全隱患如下:
1.其他App可能會針對性的發(fā)出與當前App intent-filter相匹配的廣播扬跋,由此導致當前App不斷接收到廣播并處理;
2.其他App可以注冊與當前App一致的intent-filter用于接收廣播凌节,獲取廣播具體信息钦听。
無論哪種情形,這些安全隱患都確實是存在的倍奢。由此朴上,最常見的增加安全性的方案是:
1.對于同一App內(nèi)部發(fā)送和接收廣播,將exported屬性人為設置成false卒煞,使得非本App內(nèi)部發(fā)出的此廣播不被接收痪宰;
2.在廣播發(fā)送和接收時,都增加上相應的permission畔裕,用于權限驗證衣撬;
3.發(fā)送廣播時,指定特定廣播接收器所在的包名扮饶,具體是通過intent.setPackage(packageName)指定在具练,這樣此廣播將只會發(fā)送到此包中的App內(nèi)與之相匹配的有效廣播接收器中。
App應用內(nèi)廣播可以理解成一種局部廣播的形式甜无,廣播的發(fā)送者和接收者都同屬于一個App扛点。
相比于全局廣播哥遮,App應用內(nèi)廣播優(yōu)勢體現(xiàn)在:1.安全性更高; 2.更加高效占键。
為此昔善,Android v4兼容包中給出了封裝好的LocalBroadcastManager類,用于統(tǒng)一處理App應用內(nèi)的廣播問題畔乙,使用方式上與通常的全局廣播幾乎相同君仆,只是注冊/取消注冊廣播接收器和發(fā)送廣播時將主調(diào)context變成了LocalBroadcastManager的單一實例。
//registerReceiver(mBroadcastReceiver, intentFilter);
//注冊應用內(nèi)廣播接收器
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
//獲取LocalBroadcastManager的實例
localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);
//unregisterReceiver(mBroadcastReceiver);
//取消注冊應用內(nèi)廣播接收器
localBroadcastManager.unregisterReceiver(mBroadcastReceiver);
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
intent.putExtra("toast", "MyBroadcastReceiver");
//sendBroadcast(intent);
//發(fā)送應用內(nèi)廣播
localBroadcastManager.sendBroadcast(intent);