Broadcast詳解

今天閒來無事,研究了下Android的Broadcast,發現Broadcast在Android系統中擔任着很艱鉅的角色。android

Broadcast是Android的四大組件之一;Broadcast分爲普通廣播和無序廣播。app

有序廣播能夠設置優先級,優先級高的接收者能夠終止廣播的傳播。可是在普通廣播中,優先級高的就不能終止廣播的傳播。ide

 1     /**
 2      * 發送一個普通廣播
 3      */
 4     private void sendBroadcasts() {
 5         // TODO Auto-generated method stub
 6         Intent intent = new Intent();
 7         intent.setAction("com.zhj.test");
 8         intent.putExtra("msg", "hello world!");//參數
 9         sendBroadcast(intent);
10     }
11 
12     /**
13      * 發送一個有序廣播
14      */
15     private void sendSortBroadcasts() {
16         // TODO Auto-generated method stub
17         Intent intent = new Intent();
18         intent.setAction("com.zhj.test");
19         intent.putExtra("msg", "hello world!");//參數
20         sendOrderedBroadcast(intent, null);
21     }

 廣播按註冊方式分爲動態註冊和靜態註冊;函數

(1)靜態註冊:this

靜態註冊是直接在AndroidManifest.xml中配置,規則以下:spa

<receiver android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:permission="string"
android:process="string" >
. . .
</receiver>

其中,須要注意的屬性
android:exported  ——此broadcastReceiver可否接收其餘App的發出的廣播,這個屬性默認值有點意思,其默認值是由receiver中有無intent-filter決定的,若是有intent-filter,默認值爲true,不然爲false。(一樣的,activity/service中的此屬性默認值同樣遵循此規則)同時,須要注意的是,這個值的設定是以application或者application user id爲界的,而非進程爲界(一個應用中可能含有多個進程);
android:name  —— 此broadcastReceiver類名;
android:permission  ——若是設置,具備相應權限的廣播發送方發送的廣播才能被此broadcastReceiver所接收;
android:process  ——broadcastReceiver運行所處的進程。默認爲app的進程。能夠指定獨立的進程(Android四大基本組件均可以經過此屬性指定本身的獨立進程).net

常見的註冊方式爲:code

<receiver android:name=".MyBroadcastReceiver" >
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

 

(2)動態註冊:xml

動態註冊時,無須在AndroidManifest中註冊<receiver/>組件。直接在代碼中經過調用Context的registerReceiver函數,能夠在程序中動態註冊BroadcastReceiver。registerReceiver的定義形式以下:blog

registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)

 

下面是一個動態註冊廣播的例子:

 1     private static SortedBroadcast mSortedBroadcast = null;
 2     //註冊廣播
 3     private void registerHomeKeyReceiver(Context context) {
 4         mSortedBroadcast = new SortedBroadcast();
 5         final IntentFilter homeFilter = new IntentFilter(
 6                 Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
 7         homeFilter.setPriority(1000);
 8         context.registerReceiver(mSortedBroadcast, homeFilter);
 9     }
10     //銷燬廣播
11     private void unregisterHomeKeyReceiver(Context context) {
12         if (null != mSortedBroadcast) {
13             context.unregisterReceiver(mSortedBroadcast);
14         }
15     }
16 
17     @Override
18     protected void onResume() {
19         // TODO Auto-generated method stub
20         super.onResume();
21         registerHomeKeyReceiver(this);//能夠再也不此處註冊
22     }
23 
24     @Override
25     protected void onPause() {
26         // TODO Auto-generated method stub
27         super.onPause();
28         unregisterHomeKeyReceiver(this);//能夠再也不此處銷燬
29     }

 下面的一個廣播接受器實現了接收點擊Home鍵發出的廣播(點擊Home鍵發出的廣播必須使用靜態註冊才能夠監聽到)

 1 /**
 2  * 本篇主要實現了對Home鍵的監聽
 3  * 
 4  * @author Administrator
 5  * 
 6  */
 7 public class SortedBroadcast extends BroadcastReceiver {
 8 
 9     @Override
10     public void onReceive(Context context, Intent intent) {
11         // 接收自定義的廣播
12         if (intent.getAction().equals("com.zhj.test")) {
13             String str = intent.getStringExtra("msg");// 接收發送廣播的時候傳遞的參數
14             Toast.makeText(context, "receiver2:" + str, Toast.LENGTH_SHORT)
15                     .show();
16             abortBroadcast();
17         }
18 
19         // 對Home鍵的監聽
20         if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
21             String reason = intent.getStringExtra("reason");
22             if (reason.equals("homekey")) {
23                 Toast.makeText(context, "短按Home鍵", Toast.LENGTH_SHORT).show();
24             } else if (reason.equals("recentapps")) {
25                 Toast.makeText(context, "長按/雙擊 Home鍵", Toast.LENGTH_SHORT)
26                         .show();
27             } else if (reason.equals("lock")) {
28                 Toast.makeText(context, "鎖屏", Toast.LENGTH_SHORT).show();
29             } else if (reason.equals("assist")) {
30                 Toast.makeText(context, "未知" + reason, Toast.LENGTH_SHORT)
31                         .show();
32             } else {
33                 Toast.makeText(context, "event:" + reason, Toast.LENGTH_SHORT)
34                         .show();
35             }
36             abortBroadcast();//終止廣播的傳遞(僅在接收有序廣播的時候有效)
37         }
38     }
39 }

 經過廣播啓動一個activity,當咱們經過一個廣播啓動activity的時候,程序強行中止,報錯

通過一番查找,發現經過如下的方式能夠啓動:

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        Intent intent2 = new Intent(context, StartActivity.class);
        intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent2);
    }

 

 

=

相關文章
相關標籤/搜索