文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android之广播Broadcast

2022-06-06 13:48

关注

一、自定义广播

activity_main.xml


    

广播接受者MyBroadcastReceiver1.java

public class MyBroadcastReceiver1 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("test", "自定义的广播接收者,接收到了求救广播事件");
        Log.i("test", intent.getAction());
    }
}

AndroidManifest.xml注册静态广播

       
1.静态注册

注意intent.setAction(“Help_Stitch”);参数要与AndroidManifest.xml注册的广播名一致,不然接收不到广播。
MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void send(View view) {
        Log.v("test", "send");
        Intent intent = new Intent();
        //静态广播使用Component
        //包路径项目名,包路径接受者
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver1"));
        // 定义广播的事件类型
        intent.setAction("Help_Stitch");//参数要与onCreate()里的IntentFilter()的参数一致,不然接收不到广播
        // 发送广播
        sendBroadcast(intent);
    }
}

结果
在这里插入图片描述

2.动态注册

注释掉AndroidManifest.xml的静态广播的注册

<!--        



<!--            -->
<!--                -->
<!--            -->
<!--        -->

修改MainActivity.java
注释掉

intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver1"));

添加全局变量,在onCreate注册广播,添加onDestroy()方法注销广播。
注意intent.setAction(“Help_Stitch”);参数要与onCreate()里的IntentFilter(“Help_Stitch”)的参数一致

	//全局变量,用来注册和注销
	private MyBroadcastReceiver1 mMyBroadcastReceiver1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //注册广播
        mMyBroadcastReceiver1 = new MyBroadcastReceiver1();
        IntentFilter intentFilter = new IntentFilter("Help_Stitch");
        registerReceiver(mMyBroadcastReceiver1, intentFilter);
    }
    public void send(View view) {
        Log.v("test", "send");
        Intent intent = new Intent();
        // 定义广播的事件类型
        //参数要与onCreate()里的IntentFilter()的参数一致,不然接收不到
        intent.setAction("Help_Stitch");
        // 发送广播
        sendBroadcast(intent);
    }
	//动态广播注销广播接受者
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mMyBroadcastReceiver1 != null)
            unregisterReceiver(mMyBroadcastReceiver1);
    }

结果如上

二、有序和无序广播

使用到优先级
新建三个接受者

public class MyBroadcastReceiver1 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("test", "自定义的广播接收者【Receiver1】,接收到了求救广播事件");
        Log.i("test", intent.getAction());
    }
}
public class MyBroadcastReceiver2 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("test", "自定义的广播接收者【Receiver2】,接收到了求救广播事件");
        Log.i("test", intent.getAction());
    }
}
public class MyBroadcastReceiver3 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("test", "自定义的广播接收者【Receiver3】,接收到了求救广播事件");
        Log.i("test", intent.getAction());
    }
}
1.静态注册

注意AndroidManifest.xml要注册到

        

优先级:android:priority=“500” 优先级越高则越先注册。
如上使用静态注册,如果没有优先级则注册顺序为1、2、3,但是加了优先级后顺序就为2、3、1。
修改MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void send(View view) {
        Log.v("test", "send");
        Intent intent = new Intent();
        // 定义广播的事件类型
        //参数要与onCreate()里的IntentFilter()的参数一致,不然接收不到
        intent.setAction("Broadcast");
        //静态广播使用Component注册每个广播
        //包路径项目名,包路径接受者
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver1"));
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver2"));
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver3"));
        // 发送广播
        sendOrderedBroadcast(intent,null);
    }

结果
在这里插入图片描述
只有3!
将intent.setComponent()的顺序换一下

        //静态广播使用Component
        //包路径项目名,包路径接受者
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver3"));
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver1"));
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver2"));

结果为2!
在这里插入图片描述
然后把最后一个2的intent.setComponent()注释掉

        //静态广播使用Component
        //包路径项目名,包路径接受者
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver3"));
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver1"));
//        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver2"));

结果是1。
在这里插入图片描述
结论:最后一个intent.setComponent()覆盖了前面的,所以只广播了最后一个。
要想广播全部则需要将三个intent.setComponent()注释掉,改为intent.setPackage()。

public void send(View view) {
        Log.v("test", "send");
        Intent intent = new Intent();
        // 定义广播的事件类型
        //参数要与onCreate()里的IntentFilter()的参数一致,不然接收不到
        intent.setAction("Broadcast");
        //静态广播使用Component
        //包路径项目名,包路径接受者
//        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver3"));
//        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver1"));
//        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver2"));
        intent.setPackage("com.example.ch6");
        // 发送广播
        sendOrderedBroadcast(intent,null);
    }

结果为2、3、1 。

所以多个广播接受者需要用setPackage()。
在这里插入图片描述
如果把AndroidManifest.xml优先级都改成一样的,则顺序为注册顺序1、2、3 。
结果
在这里插入图片描述
还是把优先级设置回来,在send()里同时设置setComponent()和setPackage()

        //静态广播使用Component
        //包路径项目名,包路径接受者
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver1"));
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver2"));
        intent.setComponent(new ComponentName("com.example.ch6", "com.example.ch6.MyBroadcastReceiver3"));
        intent.setPackage("com.example.ch6");

观察到结果只有3!并不是2、3、1,也不是1、2、3 。
在这里插入图片描述
所以得出结论:setComponent()比setPackage()调用的优先级高。

2.动态注册

修改MainActivity.java
添加MyBroadcastReceiver1、2、3的全局变量,并在onCreate()中注册(注册顺序为1、2、3),先不设置优先级。在onDestroy()设置MyBroadcastReceiver1、2、3的注销。

public class MainActivity extends AppCompatActivity {
    private MyBroadcastReceiver1 mMyBroadcastReceiver1;
    private MyBroadcastReceiver2 mMyBroadcastReceiver2;
    private MyBroadcastReceiver3 mMyBroadcastReceiver3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IntentFilter intentFilter = new IntentFilter("Broadcast");
        //注册广播
        mMyBroadcastReceiver1 = new MyBroadcastReceiver1();
        registerReceiver(mMyBroadcastReceiver1, intentFilter);
        mMyBroadcastReceiver2 = new MyBroadcastReceiver2();
        registerReceiver(mMyBroadcastReceiver2, intentFilter);
        mMyBroadcastReceiver3 = new MyBroadcastReceiver3();
        registerReceiver(mMyBroadcastReceiver3, intentFilter);
    }
    public void send(View view) {
        Log.v("test", "send");
        Intent intent = new Intent();
        // 定义广播的事件类型
        //参数要与onCreate()里的IntentFilter()的参数一致,不然接收不到
        intent.setAction("Broadcast");
        sendOrderedBroadcast(intent, null,mMyBroadcastReceiver3,
                null,0,null,null);
    }
    //动态广播注销广播接受者
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mMyBroadcastReceiver1 != null)
            unregisterReceiver(mMyBroadcastReceiver1);
        if (mMyBroadcastReceiver2 != null)
            unregisterReceiver(mMyBroadcastReceiver2);
        if (mMyBroadcastReceiver3 != null)
            unregisterReceiver(mMyBroadcastReceiver3);
    }
}

此时AndroidManifest.xml没有改变,即在AndroidManifest.xml中注册顺序为1、2、3,而优先级为2、3、1 。
结果
在这里插入图片描述
然后把MyBroadcastReceiver的位置换一下,动态注册顺序为3、1、2。
结果为3、1、2。
在这里插入图片描述
结论:动态注册未设置优先级时执行顺序和注册顺序一样,且与AndroidManifest.xml无关。
然后给每个mMyBroadcastReceiver添加优先级:setPriority(100);参数为优先级大小。
这里设置3为100,1为300,2为500;注册顺序依旧为3、1、2 。
结果
在这里插入图片描述
结论:动态注册设置了优先级时,执行顺序和优先级有关,优先级越大越先执行,且与AndroidManifest.xml无关。

3.广播拦截机制

沿用上面例子,执行顺序为2、1、3 。
在MyBroadcastReceiver1设置拦截:abortBroadcast();
结果拦截了3 。
在这里插入图片描述
然后注释掉该拦截,在MyBroadcastReceiver2设置拦截:abortBroadcast();
结果只有2!2之后的所有广播都被拦截了。
在这里插入图片描述
如果只想拦截1,且能接收到3,应该在MyBroadcastReceiver2设置拦截,应该在MainActivity.java修改send()的发送广播的sendOrderedBroadcast()函数的参数。

sendOrderedBroadcast(intent, null);

改为

sendOrderedBroadcast(intent, null,mMyBroadcastReceiver3,null,0,null,null);

即指定接收mMyBroadcastReceiver3 。
结果
在这里插入图片描述

4.一个receiver接收多个携带数据的广播

首先让MyBroadcastReceiver2接收两个广播。
修改MyBroadcastReceiver2.java,注释拦截语句

public class MyBroadcastReceiver2 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals("Broadcast")) {
            Log.i("test", "自定义的广播接收者【Receiver2】处理广播"+intent.getAction());
        } else if (action.equals("Broadcast_2")) {
            Log.i("test", "自定义的广播接收者【Receiver2】处理广播"+intent.getAction());
        } else {
            assert false;
        }
    }
}

再修改MainActivity.java
在**onCreate()**函数中绑定路由,再注册,添加

        IntentFilter intentFilter_2 = new IntentFilter();
        intentFilter_2.addAction("Broadcast_2");
        registerReceiver(mMyBroadcastReceiver2, intentFilter_2);

**send()**函数添加

        Intent intent_2= new Intent();
        intent_2.setAction("Broadcast_2");
		//发送广播
		sendOrderedBroadcast(intent_2,null);

注意:一定要一一对应:addAction()和setAction()参数一样
结果 2接收了两个广播。
在这里插入图片描述
接下来添加传递的数据
1)在发送时,调用Intent的putExtra方法,放入键值对;
2)在receiver中用getStringExtra、getIntExtra等方法来取;

在MainActivity.java的send()函数添加键值对
在这里插入图片描述
在MyBroadcastReceiver2.java添加取值。
在这里插入图片描述
结果
在这里插入图片描述


作者:阿宁呀


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯