在Android中,有一些操作完成以后,會發送廣播,比如說發出一條短信,或打出一個電話,如果某個程序接收了這個廣播,就會做相應的處理。這個廣播跟我們傳統意義中的電台廣播有些相似之處。之所以叫做廣播,就是因為它只負責“說”而不管你“聽不聽”,也就是不管你接收方如何處理。另外,廣播可以被不只一個應用程序所接收,當然也可能不被任何應用程序所接收。
一、Android廣播機制三要素:
1、廣播(Broadcast):用於發送廣播。是一種廣泛應用的在應用間傳輸信息的機制
2、廣播接收器(BroadcastReceiver):用於接收廣播。是對發出來的Broadcast進行過濾接受並響應的組件。
3、意圖內容(Intent):用於保存廣播相關信息的媒介
二、廣播的功能和特征:
1、廣播的生命周期很短,經過 調用對象—實現onReceive—結束 整個過程就結束了。從實現的復雜度和代碼量來看,廣播無疑是最迷你的Android 組件,實現往往只需幾行代碼。廣播對象被構造出來后通常只執行BroadcastReceiver.onReceive方法,便結束了其生命周期。所以有的時候我們可以把它當做函數看也未必不可。
2、和所有組件一樣,廣播對象也是在應用進程的主線程中被構造,所以廣播對象的執行必須是要同步且快速的。也不推薦在里面開子線程,因為往往線程還未結束,廣播對象就已經執行完畢被系統銷毀。如果需要完成一項比較耗時的工作 , 應該通過發送 Intent 給 Service, 由 Service 來完成。
3、每次廣播到來時 , 會重新創建 BroadcastReceiver 對象 , 並且調用 onReceive() 方法 , 執行完以后 , 該對象即被銷毀 . 當 onReceive() 方法在 10 秒內沒有執行完畢, Android 會認為該程序無響應。
三、廣播的兩種注冊方式:
1、常駐型廣播:常駐型廣播,當你的應用程序關閉了,如果有廣播信息來,你寫的廣播接收器同樣的能接收到,它的注冊方式就是在你應用程序的AndroidManifast.xml 中進行注冊,這種注冊方式通常又被稱作靜態注冊。這種方式可以理解為通過清單文件注冊的廣播是交給操作系統去處理的。示例代碼如下:
<receiver android:name=".AlarmReceiver" ><!-- Reveiver名稱,如果是內部類靜態注冊廣播,請在內部類前加$ --> <intent-filter> <action android:name="android.intent.action.ALARM_RECEIVER" /><!-- 廣播接收的Intent --> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>
新建一個AlarmReceiver,繼承BroadcastReceiver
public class AlarmReceiver extends BroadcastReceiver{ @Override public void onReceive(Context arg0, Intent arg1) { Toast.makeText(arg0, "我是鬧鍾,我要叫醒你...", Toast.LENGTH_SHORT).show(); }
}
最后創建一個簡單的Activity就可以了,在里面發送一個靜態廣播就行了
1 package com.example.alarmmanager; 2 3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 7 public class MainActivity extends Activity { 8 9 @Override 10 protected void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 setContentView(R.layout.activity_main); 13 14 // 發送一個靜態廣播 15 Intent intent = new Intent("android.intent.action.ALARM_RECEIVER"); 16 sendBroadcast(intent); 17 } 18 19 }
2、非常駐型廣播:非常駐型廣播,當應用程序結束了,廣播自然就沒有了,比如在 Activity 中的 onCreate 或者 onResume 中注冊廣播接收者,在 onDestory 中注銷廣播接收者。這樣你的廣播接收者就一個非常駐型的了,這種注冊方式也叫動態注冊。這種方式可以理解為通過代碼注冊的廣播是和注冊者關聯在一起的。比如寫一個監聽 SDcard 狀態的廣播接收者:
1 package com.example.alarmmanager; 2 3 import android.app.Activity; 4 import android.content.BroadcastReceiver; 5 import android.content.Context; 6 import android.content.Intent; 7 import android.content.IntentFilter; 8 import android.os.Bundle; 9 import android.os.Environment; 10 11 public class MainActivity extends Activity { 12 SdcardStateChanageReceiver sdcardStateReceiver; 13 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 17 // 新建一個BroadcastReceiver 18 sdcardStateReceiver = new SdcardStateChanageReceiver(); 19 // 添加意圖過濾器 20 IntentFilter filter = new IntentFilter(); 21 // 給filter添加Action,表示只接收這幾個Action的廣播 22 filter.addAction(Intent.ACTION_MEDIA_REMOVED); 23 filter.addAction(Intent.ACTION_MEDIA_EJECT); 24 filter.addAction(Intent.ACTION_MEDIA_MOUNTED); 25 // 設置SDCard插拔接收 26 filter.addDataScheme("file"); 27 // 注冊一個動態廣播 28 registerReceiver(sdcardStateReceiver, filter); 29 } 30 31 protected void onDestroy() { 32 // 在摧毀Activity的時候,一定要記得注銷廣播,不然會報錯 33 unregisterReceiver(sdcardStateReceiver); 34 } 35 36 // BroadcastReceiver 37 class SdcardStateChanageReceiver extends BroadcastReceiver { 38 public void onReceive(Context context, Intent intent) { 39 String state = Environment.getExternalStorageState(); 40 System.out.println(state); 41 if (state.equals(Environment.MEDIA_REMOVED) 42 || state.equals(Environment.MEDIA_UNMOUNTED)) { 43 System.out.println("SDCard 已卸載!"); 44 } 45 } 46 } 47 }
作者:登天路