zoukankan      html  css  js  c++  java
  • Android 四大组件之 BroadCastReceiver

    BroadCastReceiver是一种全局的监听器。用于监听系统全局的广播消息。由于他是一种全局的监听器,所以他可以轻松实现,系统中不同组件之间的通信。

    1.创建BroadCastReceiver

    public class MyReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            
            // 当监听到广播消息时,执行这个方法。
            String content=intent.getStringExtra("content");
            Toast.makeText(context, "你发送的是:"+content, Toast.LENGTH_SHORT).show();
    
        }
    
    }
    View Code

    BroadCastReceiver接收到广播,就会执行onReceive方法。可以使用Intent接收数据信息。

    2.注册BroadCastReceiver

    (1)静态注册

    静态注册,就是在AndroidManifest.xml文件中,注册BroadCastReceiver。

    <receiver android:name=".MyReceiver">
       <intent-filter>
           <action android:name="com.example.MY_LISTENER"></action>
       </intent-filter>
    </receiver>

    (2)动态注册

    动态注册,就是在代码中注册BroadCastReceiver, 如果使用动态注册,可以在Activity的onResume()中注册,onPause中注销,或者在onCreate()中注册,onDestory注销。

    //实例化广播接收器
        MyReceiver myReceiver = new MyReceiver();
        //过滤广播,这里“com.example.MY_LISTENER”是我自定义的,可以随便写,广播时候保持一致就可以
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.MY_LISTENER");
        //注册广播
        registerReceiver(myReceiver, intentFilter);
      //注销广播
      //unregisterReceiver(myReceiver)
    View Code

    关于registerReceiver方法有两种重载。

    第一种:registerReceiver(BroadcastReceiver receiver, IntentFilter filter)

    第一个参数:负责接收广播的BroadcastReceiver(广播接收器);

    第二个参数:是意图过滤器;

    第二种:registerReceiver(receiver, filter, broadcastPermission, scheduler)

    第一个参数:负责接收广播的BroadcastReceiver(广播接收器);

    第二个参数:意图过滤器(哪些广播可以被这个接收器接收);

    第三个参数:广播权限;

    第四个参数:Hander;

    (3)关于“静态注册”和“动态注册”的区别!

    当静态注册一个BroadcastReceiver时,不论应用程序启动与否,都可以接收对应的的广播。 
    动态注册的时候,如果不执行unregisterReceiver();方法取消注册,跟静态是一样的。但是如果执行该方法,当执行过以后,就不能接受广播了。

    (4)注意:权限重复现象

    如果AndroidManifest.xml(功能清单文件)里注册了权限,在该方法再注册,则 receiver 无法收到广播;

    如果AndroidManifest.xml(功能清单文件)里没有注册了权限,该方法注册也无法收到。当该方法没有注册权限,功能清单里注册的时候, receiver能收到广播。

    3.广播的类型与发送

    普通广播:对于Receiver(接收者)来说,普通广播是完全异步的,可以在同一时刻被所有Receiver(接收者)接收到,消息传递速度表较快。

    发送广播:

    button_start.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    //发送广播依然需要使用Intent
                    Intent intent = new Intent();
                    //这个Action是我们在AndroidManifest.xml中为Receiver配置的
                    intent.setAction("com.example.MY_LISTENER");
                    //给Receiver传入参数
                    intent.putExtra("content", "Hello Receiver");
                    //发送广播
                    sendBroadcast(intent);
                }
            });
    View Code

    接收广播:

    public class MyReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            
            // 当监听到广播消息时,执行这个方法。
            String content=intent.getStringExtra("content");
            Toast.makeText(context, "你发送的是:"+content, Toast.LENGTH_SHORT).show();
    
        }
    
    }
    View Code

    有序广播:通过给Receiver(接收者)指定优先级,系统会安排优先级高的Receiver接收广播,然后优先级高的Receiver再把广播传播到优先级较低的Receiver中。可以在优先级高的Receiver中使用abortBroadcast(),终止广播的传递,这样就不会被优先级较低Receiver接收到。

    不仅如此,也可以在优先级高的Receiver中,把处理的结果及相关信息,通过setResultExtras(Bundle)方法,传递到下一个Receiver中(使用getResultExtras(true)接收上一个接收者存入的数据)。

    注意:当具有相同优先级的Receiver,系统执行哪个Receiver是随机的。如果都没有指定优先级,动态注册(代码注册)的最先收到广播。

    指定Receiver的优先级

    (1)在AndroidManifest.xml文件中,通过 android:priority=""来指定优先级。

      <receiver android:name=".MyReceiver">
          <intent-filter android:priority="10">
               <action android:name="com.example.MY_LISTENER"></action>
          </intent-filter>
      </receiver>

    (2)通过 IntentFilter 的setPriority() 指定。

    注意:优先级的范围 -1000~1000

    例:

    定义三个接收者

    MyReceiver1

    public class MyReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
            // 把接收到的num,乘以10。
            int num = intent.getIntExtra("num", 0);
            num = num * 10;
    
            Bundle b = new Bundle();
            b.putInt("num", num);
            //把处理结果传递给下一个接收者
            setResultExtras(b);
    
            Toast.makeText(context, "1,接收到的是:" + String.valueOf(num),
                    Toast.LENGTH_SHORT).show();
        }
    
    }
    View Code

    MyReceiver2

    public class MyReceiver2 extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            // 把接收到的num,乘以10。
            int num = getResultExtras(true).getInt("num");
            num = num * 10;
    
            Bundle b = new Bundle();
            b.putInt("num", num);
            //把处理结果传递给下一个接收者
            setResultExtras(b);
    
            Toast.makeText(context, "2,接收到的是:" + String.valueOf(num),
                    Toast.LENGTH_SHORT).show();
            
            //终止广播向下一个接收者传递。
            //abortBroadcast();
    
        }
    
    }
    View Code

    MyReceiver3 

    public class MyReceiver3 extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            
            // 把接收到的num,乘以10。
            int num = getResultExtras(true).getInt("num");
            num = num * 10;
    
            Toast.makeText(context, "3,接收到的是:" + String.valueOf(num),
                    Toast.LENGTH_SHORT).show();
        }
    
    }
    View Code

    发送有序广播:

    button_start = (Button) findViewById(R.id.button1);
            button_start.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    Intent intent = new Intent();
                    intent.setAction("com.example.MY_LISTENER");
                    //给第一个Receiver传入参数
                    intent.putExtra("num",1);
                    //发送广播,注意:这里使用的是sendOrderedBroadcast
                    sendOrderedBroadcast(intent, null);
                }
            });
    View Code

    这里使用了sendOrderedBroadcast()发送有序广播,该方法有两个参数,第一个参数是Intent。第二个参数是权限,如果给广播指定权限,那么只有具备该权限的Receiver,才能接收到。

    4生命周期

    BroadCastReceiver的生命周期非常简短:接收到广播→onReceive()→结束;

    所以在onReceive方法中,不要执行耗时的任务,如果该方法执行时间超过10秒,Android就会认为该程序无响应,并弹出ANR的对话框。如果必须执行耗时任务可以考虑,在onReceive中开启服务来执行,但不要使用线程,因为BroadCastReceiver的生命周期很短,可能出现子线程还没有结束,BroadCastReceiver就已经退出了。

    如果当BroadCastReceiver所在的进程结束,虽然该进程中可能有用户启动的新线程,但是由于该进程内没有活动的组件,系统会在内存紧张的时候,优先结束掉该进程,这就会导致BroadCastReceiver启动的子线程不能执行完。

    提示:我们还可以监听系统广播。例如系统的“启动完成”广播,我可以实现开机启动项。网络变化等等。

    特殊的BroadcastReceiver

    LocalBroadcastManager本地广播

    Sticky Broadcast粘性广播

    OrderedBroadcastReceiver有序广播

    StickyOrderedBroadcast粘性有序广播

    相关资料:

    http://www.cnblogs.com/trinea/archive/2012/11/09/2763182.html

    http://yangguangfu.iteye.com/blog/1063732

  • 相关阅读:
    Chrome浏览器另存为时浏览器假死问题
    excel的新增日期快捷键Ctrl+;失效解决办法
    制作Visual Studio 2019 (VS 2019) 离线安装包
    Sysinternals Suite 工具包使用指南
    如何关闭Acrobat Reader DC自动更新
    MySql like模糊查询使用详解
    注册表删除我的电脑WPS云盘图标
    解除Word文档的限制编辑!
    IIS Ftp端口设置
    [UnityShader基础]12.坐标空间
  • 原文地址:https://www.cnblogs.com/ywtk/p/3958484.html
Copyright © 2011-2022 走看看