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

    =

  • 相关阅读:
    92 log4j日志记录
    35 反射封装占位
    34 jdbc工具封装
    33 mysql约束的增删
    32 Dao层和impl层
    31 jdbc查询,javaBean引入
    30 jdbc事务设置
    29 jdbc连接带数据操作 模板(直接复制来用)
    28 jdbc驱动包导入java项目及连接数据库流程
    27 MySQL与Oracle在语法上的一些不同点
  • 原文地址:https://www.cnblogs.com/zhjsll/p/5086240.html
Copyright © 2020-2023  润新知