Broadcast详解

今天闲来无事,研究了下Android的Broadcast,发现Broadcast在Android系统中担任着很艰巨的角色。

Broadcast是Android的四大组件之一;Broadcast分为普通广播和无序广播。

有序广播可以设置优先级,优先级高的接收者可以终止广播的传播。但是在普通广播中,优先级高的就不能终止广播的传播。

 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)静态注册:

静态注册是直接在AndroidManifest.xml中配置,规则如下:

<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四大基本组件都可以通过此属性指定自己的独立进程)

常见的注册方式为:

<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)动态注册:

动态注册时,无须在AndroidManifest中注册<receiver/>组件。直接在代码中通过调用Context的registerReceiver函数,可以在程序中动态注册BroadcastReceiver。registerReceiver的定义形式如下:

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);
    }

 

 

=

 

posted @ 2015-12-29 16:39  HuijunZhang  阅读(2786)  评论(0编辑  收藏
中国