Broadcast Receiver翻譯成中文叫“廣播接收器”,所以它的作用是用來接收發送過來的廣播的。
Android應用程序可以發送或接收來自Android系統和其他Android應用程序的廣播消息,類似于發布訂閱設計模式。當有興趣的事件發生時發送這些廣播。例如,Android系統在各種系統事件發生時發送廣播,例如當系統啟動或設備開始充電時。應用程序也可以發送自定義廣播,例如,通知其他應用程序的東西,他們可能感興趣(例如,一些新的數據已被下載)。應用程序可以注冊接收特定的廣播。當發送廣播時,系統自動將廣播路由到訂閱該特定類型廣播的應用程序。 一般來說,廣播可以作為跨應用程序和正常用戶流之外的消息傳遞系統。
動態注冊廣播是一種靈活的注冊方式,通過代碼來注冊廣播,銷毀廣播。
首先我們新建DynamicBroadcast類,繼承自BroadcastReceiver,用來接收廣播,重寫onReceive方法,通過intent可以獲取發送廣播時傳入的參數。
public class DynamicBroadcast extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent){ String data = intent.getStringExtra("data"); Log.i("data",data); }}在activity_main.xml文件中增加一個按鈕
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btn_dynamic_broadcast_send_message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="給動態注冊的廣播發送消息"/></LinearLayout>最后我們下來看MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ public static final String ACTION_DYNAMIC_BROADCAST="android.intent.action.DYNAMIC_BROADCAST"; PRivate DynamicBroadcast dynamicBroadcast; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btn_dynamic_broadcast_send_message).setOnClickListener(this); //動態注冊廣播 dynamicBroadcast=new DynamicBroadcast(); IntentFilter intentFilter=new IntentFilter(ACTION_DYNAMIC_BROADCAST); registerReceiver(dynamicBroadcast,intentFilter); } @Override public void onClick(View v){ switch (v.getId()){ case R.id.btn_dynamic_broadcast_send_message: Intent intent = new Intent(ACTION_DYNAMIC_BROADCAST); intent.putExtra("data","Dynamic Broadcast Parameter");//通過intent傳參 sendBroadcast(intent);//發送廣播消息 break; } } @Override protected void onDestroy() { super.onDestroy(); Log.i("MainActivity onDestroy","銷毀廣播"); unregisterReceiver(dynamicBroadcast); }}我們在onCreate中通過registerReceiver方法注冊一個廣播,需要兩個參數(BroadcastReceiver跟IntentFilter對象)。同時給”發送廣播”按鈕設置點擊監聽,點擊之后通過sendBroadcast方法發送廣播,這里需要一個Intent對象,構造Intent對象的時候傳入Action,這個Action跟我們注冊廣播的時候Action要一致。
我們還重寫了onDestroy方法,當Activity銷毀的時候同時銷毀廣播,所以,在本例中,廣播的生命周期跟Activity一樣。
我們運行代碼,點擊”給動態注冊的廣播發送消息”按鈕,Log打印如下:
02-03 16:32:11.194 7095-7095/com.ansen.broadcastreceiver I/data: Dynamic Broadcast Parameter靜態注冊廣播是在AndroidManifest.xml文件中注冊的,無論這個程序是否啟動,當收到廣播時,都會接收的到。
我們在動態注冊廣播的Demo上增加代碼,新建StaticBroadcast類,繼承BroadcastReceiver,實現onReceive方法,跟動態廣播的接收器代碼幾乎一樣。
public class StaticBroadcast extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent){ String data = intent.getStringExtra("data"); Log.i("data",data); }}接下來我們需要在AndroidManifest.xml文件中注冊這個廣播,通過receiver標簽的name屬性指定這個類,再增加intent-filter標簽,給action標簽設置name屬性值,我們發送廣播的時候需要用到這個值。
<receiver android:name=".StaticBroadcast" android:exported="true"> <intent-filter> <action android:name="android.intent.action.STATIC_BROADCAST"/> </intent-filter></receiver>在activity_main.xml文件中增加一個按鈕,”給靜態注冊的廣播發送消息”。
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btn_dynamic_broadcast_send_message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="給動態注冊的廣播發送消息"/> <Button android:id="@+id/btn_static_broadcast_send_message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="給靜態注冊的廣播發送消息"/></LinearLayout>給按鈕設置點擊監聽事件,在對應的onClick回掉方法中發送廣播,我們看到Intent的構造方法有傳入一個字符串,這個值跟我們在xml中receiver標簽->intent-filter->action的name屬性的值必須要一致。在廣播底層源碼中就是通過action來區分不同的廣播接收者。
Intent staticIntent = new Intent("android.intent.action.STATIC_BROADCAST");staticIntent.putExtra("data","Static Broadcast Parameter");//通過intent傳參sendBroadcast(staticIntent);//發送廣播消息因為沒有增加很多代碼,MainActivity的代碼就不全部貼出來了,重新運行代碼,點擊“給靜態注冊的廣播發送消息”按鈕,打印的log如下:
02-06 14:02:38.735 10749-10749/com.ansen.broadcastreceiver I/data: Static Broadcast Parameter前面我們寫了Demo,也介紹了動態注冊廣播跟靜態注冊廣播,這里我再來總結一下: - 動態注冊 廣播的生命周期自己靈活控制,消耗資源少。 - 靜態注冊 廣播一直存在,除非軟件卸載。消耗資源稍微大一些。當然現在的手機硬件都跟的上了,這點資源可以忽略不計。
我們都知道收到了廣播就會執行onReceive方法,但是在這個方法里面不能做耗時超過10秒的事情,否則會彈出ANR(application NoResponse)的對話框。如果有需要就另外啟動一個Thread處理耗時操作。
LocalBroadcastManager是Android Support包提供了一個工具,是用來在同一個應用內的不同組件間發送Broadcast的 。可以解決BroadcastReceiver的安全問題(惡意程序腳本不斷的去發送你所接收的廣播)。
使用LocalBroadcastManager有以下好處: - 發送的廣播只會在自己App內傳播,不會泄露給其他App,確保隱私數據不會泄露 - 其他App也無法向你的App發送該廣播,不用擔心其他App會來搞破壞 - 比系統全局廣播更加高效
使用方法跟動態注冊廣播類似。首先需要獲取LocalBroadcastManager對象,單例模式獲取,然后調用registerReceiver方法。
broadcastManager = LocalBroadcastManager.getInstance(this);localReceiver=new LocalBroadcastReceiver();broadcastManager.registerReceiver(localReceiver,new IntentFilter(ACTION_LOCAL_BROADCAST));發送廣播也類似。這里一定需要調用LocalBroadcastManager對象的sendBroadcast方法發送廣播哦,不然接收不到廣播
Intent localIntent=new Intent(ACTION_LOCAL_BROADCAST);localIntent.putExtra("data","Local Broadcast Parameter");//通過intent傳參LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);順便在onDestroy方法中取消注冊。
@Overrideprotected void onDestroy(){ super.onDestroy(); Log.i("MainActivity onDestroy","銷毀廣播"); unregisterReceiver(dynamicBroadcast); broadcastManager.unregisterReceiver(localReceiver);}因為跟動態注冊廣播類似,所以只貼出了關鍵代碼。
新聞熱點
疑難解答