1.什麼是廣播
- 廣播,是一個全局的監聽器,屬於Android四大組件之一
- 廣播分爲兩個角色:廣告接收者和廣告傳遞者
- 廣播的作用是監聽或者接收應用App 發出的廣播消息,並做出響應
2.廣播的分類及區別–有序廣播與無序廣播
無序廣播
- 無序廣播即爲我們平時經常使用的廣播,其主要是通過public abstract void sendBroadcast (Intentintent)方法進行發送,並通過intent傳遞數據
Intent nonOrderIntent = new Intent();
nonOrderIntent.setAction(ACTION);
sendBroadcast(nonOrderIntent);
- 無序廣播不可以被攔截,不可以被終止,不可以被修改,無序廣播任何接收者只要匹配條件都可以接收到,無優先級問題。
- 如果想通過無序廣播傳遞數據,則可以調用intent.putExtra方法傳遞,
接收者可通過intent.get…接收,不可通過getResultData接收。
有序廣播
有序廣播主要是通過public abstract void sendOrderedBroadcast (Intent intent,
String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle
initialExtras)方法進行發送。
Intent intent = new Intent();
intent.setAction(ACTION);
sendOrderedBroadcast(intent, null, new Priority2BroadcastReceiver(), null, Activity.RESULT_OK, "MainActivity發送了一個有序廣播", null);
- 有序廣播可以被攔截,可以在較高優先級的接收器中通過abortBroadcast()攔截廣播,這樣就會導致較低優先級的接收器無法收到廣播了,但是sendOrderedBroadcast第三個參數指定的BroadcastReceiver還是會收到廣播的,而且能獲得數據。
- 有序廣播可以通過原始intent.putExtra這種方式傳遞數據給BroadcastReceiver,也能通過sendOrderedBroadcast方法的最後2個參數傳遞數據,但是通過第一種方式傳遞的數據無法中途修改,通過第二種方式傳遞的可以通過上面參數說明中的方式進行修改。
3.廣播的註冊方式及區別–靜態註冊和動態註冊
靜態註冊
註冊方式:在AndroidManifest.xml裏通過標籤聲明
<receiver
android:enabled=["true" | "false"]
//此broadcastReceiver能否接收其他App的發出的廣播
//默認值是由receiver中有無intent-filter決定的:如果有intent-filter,默認值爲true,否則爲false
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
//繼承BroadcastReceiver子類的類名
android:name=".mBroadcastReceiver"
//具有相應權限的廣播發送者發送的廣播才能被此BroadcastReceiver所接收;
android:permission="string"
//BroadcastReceiver運行所處的進程
//默認爲app的進程,可以指定獨立的進程
//注:Android四大基本組件都可以通過此屬性指定自己的獨立進程
android:process="string" >
//用於指定此廣播接收器將接收的廣播類型
//本示例中給出的是用於接收網絡狀態改變時發出的廣播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<receiver
//此廣播接收者類是mBroadcastReceiver
android:name=".mBroadcastReceiver" >
//用於接收網絡狀態改變時發出的廣播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
動態註冊
註冊方式:在代碼中調用Context.registerReceiver()方法
// 選擇在Activity生命週期方法中的onResume()中註冊
@Override
protected void onResume(){
super.onResume();
// 1. 實例化BroadcastReceiver子類 & IntentFilter
mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
// 2. 設置接收廣播的類型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
// 3. 動態註冊:調用Context的registerReceiver()方法
registerReceiver(mBroadcastReceiver, intentFilter);
}
// 註冊廣播後,要在相應位置記得銷燬廣播
// 即在onPause() 中unregisterReceiver(mBroadcastReceiver)
// 當此Activity實例化時,會動態將MyBroadcastReceiver註冊到系統中
// 當此Activity銷燬時,動態註冊的MyBroadcastReceiver將不再接收到相應的廣播。
@Override
protected void onPause() {
super.onPause();
//銷燬在onResume()方法中的廣播
unregisterReceiver(mBroadcastReceiver);
}
}
4.無序廣播
Intent intent = new Intent();
//對應BroadcastReceiver中intentFilter的action
intent.setAction(BROADCAST_ACTION);
//發送廣播
sendBroadcast(intent);
<receiver
//此廣播接收者類是mBroadcastReceiver
android:name=".mBroadcastReceiver" >
//用於接收網絡狀態改變時發出的廣播
<intent-filter>
<action android:name="BROADCAST_ACTION" />
</intent-filter>
</receiver>
5.有序廣播
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="edu.jju.broadcastreceiver" />
</intent-filter>
</receiver>
<receiver android:name=".MyReceiverA">
<intent-filter>
<action android:name="edu.jju.broadcastreceiver" />
</intent-filter>
</receiver>
<receiver android:name=".MyReceiverB">
<intent-filter>
<action android:name="edu.jju.broadcastreceiver" />
</intent-filter>
</receiver>
<receiver android:name=".MyReceiverC">
<intent-filter>
<action android:name="edu.jju.broadcastreceiver" />
</intent-filter>
</receiver>
6.Service中發送廣播示例
- Android中,service的開啓,默認是綁定activity的,是activity級的。如果要實現當退出程序後,保持Service的運行,那麼需要把service設置成爲system級的,首先聲明權限
複製代碼
<service
android:name="com.androidnodesocket.PushNotificationService"
android:enabled="true"
android:process="system"
/>
- 然後定義一個推送消息的服務類
package com.androidnodesocket;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
/**
* Created by Administrator on 2017-10-14.
*/
public class PushNotificationService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onCreate() {
super.onCreate();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
最後在啓動的activity中啓動服務
//啓動服務
Intent i = new Intent(this, PushNotificationService .class);
//下面寫自己的路徑
i.setAction("com.androidnodesocket.PushNotificationService");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startService(i);
首先在mainActivity中定義一個內部廣播的類(廣播接收器)用來接收到數據後更新到 textViewJishu 這個TextView的文本中
/**
* 定義廣播接收器(內部類)
*
* @author lenovo
*
*/
private class UpdateUIBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
textView.setText(String.valueOf(intent.getExtras().getInt("count")));
}
}
在MainActivity中聲明兩個變量並且在初始化的時候註冊這個接收器的實例(下面是部分代碼,請放到對應的位置)
//聲明一個操作常量字符串
public static final String ACTION_UPDATEUI = "action.updateUI";
//聲明一個廣播實例
public UpdateUIBroadcastReceiver broadcastReceiver;
//在初始化的時候註冊實例
// 動態註冊廣播
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_UPDATEUI);
broadcastReceiver = new UpdateUIBroadcastReceiver();
registerReceiver(broadcastReceiver, filter);
在推送消息的服務類中發送廣播消息給界面