廣播主要分兩種類型:標(biāo)準(zhǔn)廣播和有序廣播
發(fā)送標(biāo)準(zhǔn)廣播
- 首先定義一個(gè)廣播接收器來接收此廣播蚂四,新建一個(gè)MyBroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_LONG).show();
}
}
- 在AndroidManifest.xml中對(duì)這個(gè)廣播接收器進(jìn)行修改
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.md.bb">
...
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.md.MY_BROADCAST"/>
</intent-filter>
</receiver>
</application>
</manifest>
- 這里讓MyBroadcastReceiver接收一條值為com.example.md.MY_BROADCAST的廣播光戈,所以在一會(huì)發(fā)廣播的時(shí)候得發(fā)一條這樣的廣播
- 修改Activity_main.xml中的代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=" send Broadcast"/>
</LinearLayout>
- 定義一個(gè)按鈕作為發(fā)送廣播的觸發(fā)點(diǎn),
- 修改MainActivity中的代碼
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 我們自定義的廣播
Intent intent = new Intent("com.example.md.MY_BROADCAST");
// 發(fā)送出去
sendBroadcast(intent);
}
});
}
}
- 在按鈕點(diǎn)擊事件中遂赠,首先構(gòu)造出Intent對(duì)象,把要發(fā)送的廣播的值傳入晌杰,然后調(diào)用sendBroadcast()方法將廣播發(fā)送出去跷睦,這個(gè)時(shí)候所有監(jiān)聽
com.example.md.MY_BROADCAST
這條廣播的廣播接收器就會(huì)收到一條消息,此時(shí)發(fā)送的就是標(biāo)準(zhǔn)廣播
發(fā)送有序廣播
廣播是一種可以跨進(jìn)程的通信肋演,此前在我們程序內(nèi)發(fā)出的廣播抑诸,其他的應(yīng)用也是可以接收到的,再新建一個(gè)項(xiàng)目爹殊,用于接收上面的自定義廣播
- 新建AntotherBroadcastReceive
public class AntotherBroadcastReceive extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received in AntotherBroadcastReceive",Toast.LENGTH_SHORT).show();
Log.d("aaaaaaaaaa","aaaaaaaaaaaaaa");
}
}
- 仍然是在廣播接收器的onReceive()方法中彈出一段文本
- 在AndroidManifest.xml中對(duì)這個(gè)廣播進(jìn)行修改
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.md.b2">
<application
...
<receiver
android:name=".AntotherBroadcastReceive"
android:enabled="true"
android:exported="true">
<intent-filter>
<!--這里是我們自定義的廣播-->
<action android:name="com.example.md.MY_BROADCAST"/>
</intent-filter>
</receiver>
</application>
</manifest>
- 在這個(gè)里面接收的仍然是這個(gè)廣播蜕乡,現(xiàn)在運(yùn)行第二個(gè)項(xiàng)目,把這個(gè)程序安裝到模擬器上梗夸,然后回到第一個(gè)項(xiàng)目的頁面层玲,點(diǎn)擊按鈕,這個(gè)時(shí)候就會(huì)彈出兩個(gè)提示信息(此時(shí)第二項(xiàng)目別關(guān))
足以說明應(yīng)用發(fā)出的廣播是可以被其他程序接收到的
- 發(fā)送有序廣播反症,還是在第一個(gè)項(xiàng)目中辛块,在MainActivity中
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
Button button_1 = (Button)findViewById(R.id.button_1);
button_1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 我們自定義的廣播
Intent intent = new Intent("com.example.md.MY_BROADCAST");
// 添加進(jìn)來
//sendBroadcast(intent);
sendOrderedBroadcast(intent,null);
}
});
}
- 可以看到,這里只改了一行的代碼將
sendBroadcast(intent)
改成了sendOrderedBroadcast(intent,null)
,這個(gè)方法接收兩個(gè)參數(shù)铅碍,第一個(gè)參數(shù)是Intent,第二個(gè)參數(shù)是一個(gè)與權(quán)限相關(guān)的字符串润绵,這里傳入null就可以了,現(xiàn)在重啟程序胞谈,點(diǎn)擊按鈕尘盼,這兩個(gè)應(yīng)用仍然都可以接收到這兩個(gè)廣播 - 此時(shí)和標(biāo)準(zhǔn)廣播好像沒什么區(qū)別,但是烦绳,這個(gè)時(shí)候廣播接收器是有先后順序的卿捎,而且前面的廣播接收器還可以將這個(gè)廣播進(jìn)行截?cái)啵柚箓鞑?/li>
- 該怎么定義廣播接收器的先后順序呢爵嗅,是在注冊(cè)的時(shí)候進(jìn)行設(shè)定娇澎,還是在第一個(gè)項(xiàng)目中修改AndroidManifest.xml中的文件
...
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="com.example.md.MY_BROADCAST"/>
</intent-filter>
</receiver>
- 在這里通過
android:priority="100"
屬性設(shè)置了廣播接收器的優(yōu)先級(jí),優(yōu)先級(jí)越高就可以先接受到廣播睹晒,這里設(shè)置為100 - 設(shè)置完優(yōu)先級(jí)趟庄,那么就可以在MyBroadcastReceiver中選擇是否允許攔截這個(gè)廣播的傳遞
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}
- 若在onReceive()方法中調(diào)用了abortBroadcast()方法括细,就表示將這個(gè)廣播進(jìn)行攔截,后面的廣播接收器就無法再接收到這條廣播了戚啥,運(yùn)行程序奋单,這個(gè)時(shí)候就只會(huì)彈出一個(gè)信息了
本地廣播
前面使用的發(fā)送和接收的廣播都是系統(tǒng)的全局廣播,就是發(fā)出的和接收的廣播都可以被其他程序接收猫十,這個(gè)時(shí)候安全性就下降了览濒,這個(gè)時(shí)候,我們使用本地廣播拖云,就是
發(fā)出的廣播只能夠在應(yīng)用程序的內(nèi)部使用贷笛,并且廣播接收器也只能接收來自本應(yīng)用內(nèi)部的廣播
- 在MainActivity中修改代碼,只要就是使用了LocalBroadcastManager來對(duì)廣播進(jìn)行管理
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.main_activity);
// 獲取實(shí)例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
Button button_1 = (Button)findViewById(R.id.button_1);
button_1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 我們自定義的廣播
Intent intent = new Intent("com.example.md.LOCAL_BROADCAST");
//發(fā)送自定義廣播
localBroadcastManager.sendBroadcast(intent);
}
});
// // 創(chuàng)建一個(gè)實(shí)例
intentFilter = new IntentFilter();
// // 添加一個(gè)action宙项,
intentFilter.addAction("com.example.md.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
//注冊(cè)的是本地的廣播接收器
localBroadcastManager.registerReceiver(localReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 動(dòng)態(tài)注冊(cè)的廣播需要注冊(cè)
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();
}
}
}
- 這個(gè)和前面所學(xué)的動(dòng)態(tài)注冊(cè)廣播接收器以及發(fā)送廣播的代碼基本相同
- 首先是通過
LocalBroadcastManager.getInstance(this)
獲取到它的實(shí)例 - 注冊(cè)廣播接收器的時(shí)候用的是
localBroadcastManager.registerReceiver()
- 發(fā)送廣播的時(shí)候調(diào)用的是
localBroadcastManager.sendBroadcast()
點(diǎn)擊按鈕的時(shí)候就會(huì)發(fā)出com.example.md.LOCAL_BROADCAST廣播乏苦,然后在LocalReceiver里接收這條廣播,點(diǎn)擊程序
- 本地廣播是無法通過靜態(tài)注冊(cè)的方式來接收的尤筐,這是因?yàn)殪o態(tài)的注冊(cè)主要就是為了讓程序在沒有啟動(dòng)的情況下也能接收到廣播汇荐,而發(fā)送本地廣播是在程序啟動(dòng)的情況下
- 本地廣播的優(yōu)勢(shì)
- 可以明確的知道正在發(fā)送的廣播是什么,不用擔(dān)心機(jī)密數(shù)據(jù)的泄漏
- 其他程序的廣播也無法將廣播發(fā)送到我們的程序內(nèi)部盆繁,不用擔(dān)心安全漏洞問題
- 發(fā)送本地廣播比發(fā)系統(tǒng)廣播效率高