广播(Broadcast)

啥叫广播
例如:电池电量低的时候会提醒电量不足 这就是广播
广播即在组件之间传递消息的机制

image

Binder机制

Binder机制作为Android系统中非常重要的一部分,为不同进程之间的数据共享和通信提供了高效、稳定的解决方案。开发者在Android开发中,可以通过Android提供的Binder API轻松实现进程间通信,而无需关注Binder机制的底层实现细节。
具体详细参考:https://blog.csdn.net/carson_ho/article/details/73560642

应用场景
  1. 同一个APP内同一组件内通信(单个或多个线程)
  2. 同一个APP内不同组件之间通信(单个进程)
  3. 同一个APP多个进程的不同组件之间通信
  4. 不同APP组件之间通信
  5. Android和APP之间通信

广播接收者

多个接收者可以接受处理一个广播事件

image

那代码里是怎样的呢

image

那之前提到过注册 来看看注册和所需要写的方法

注册还是分为静态注册和动态注册
8.0以后前者已被舍弃
所以需要动态注册

也是三步走:
//1.实例化广播接收者
MyReceiver receiver = new MyReceiver();
//2.处理中心(过滤器)
IntentFilter intentFilter = new IntentFilter("要过滤的广播");
//3.注册广播
registerReceiver(receiver,intentFilter);
注意注意小坑小补充

这里的注册实例化要写在onStart()方法中 而不是写在重写方法onReceive()中

Intent为意图 一般用于启动Activity和Service及发送广播
IntentFilter:
action属性:Intent对象的动作
data属性:指定数据的Uri或者数据MIME类型
category属性:为action属性添加额外信息


看一个案例:

image

点击喇叭后 发送广播 吃饭了 小兔子那里也弹出来消息

package com.example.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

public class EatActivity extends AppCompatActivity {
    private ImageView iv_horn;
    private TextView tv_right_content;
    private TextView tv_left_content;
    private MyEatReceiver receiver;


    @Override
    protected void onStart() {
        super.onStart();
        setContentView(R.layout.activity_eat);
        iv_horn = findViewById(R.id.iv_horn);
        tv_right_content = findViewById(R.id.tv_right_content);
        tv_left_content = findViewById(R.id.tv_left_content);


        //动态注册广播
        receiver = new MyEatReceiver(); //实例化广播接收者
        String act="Open Eat";
        //处理中心 过滤
        IntentFilter intentFilter = new IntentFilter(act);
        registerReceiver(receiver,intentFilter);

        //第一种方法匿名内部类实现点击方法
        iv_horn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tv_right_content.setText("开饭");
                Intent intent = new Intent();
                intent.setAction("Open Eat");
                sendBroadcast(intent);
            }
        });

    }


    //自定义广播
    public class MyEatReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("Open Eat")) {
                tv_left_content.setVisibility(View.VISIBLE);
            }
            Log.i("高远",intent.getAction());
        }
    }

    //伴随Activity的销毁 注册的广播接受者也伴随销毁
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }
}

需要注意的就是:动态注册的广播接收者伴随Activity的销毁而销毁


自定义广播与类型

上述案例即使自定义的广播 不过要继承BroadcastReceiver
广播的类型分为:
无序广播和有序广播
无需广播即是发送一条广播 所有广播接收者都会接受
主要看看有序广播
还是一个案例:

image
模拟四种情况
1.设置优先级 有序广播
2.优先级一样 先注册的先接受
3.拦截广播 优先级高的被拦截 广播将不再向后传递
4.拦截广播 sendOrderedBroadcast第三个参数可以指定传递

package com.example.broadcast;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

public class DuckActivity extends AppCompatActivity {
    private ImageView iv_horn2;
    private TextView tv_left_content, tv_one, tv_two, tv_three;
    private OneBroadcast one;
    private TwoBroadcast two;
    private ThreeBroadcast three;
    private int num = 0;

    @Override
    protected void onStart() {
        super.onStart();
        setContentView(R.layout.activity_duck);
        init();
        registerReceiver();
    }


    //初始化
    public void init() {
        iv_horn2 = findViewById(R.id.iv_horn2);
        tv_left_content = findViewById(R.id.tv_left_content);
        tv_one = findViewById(R.id.tv_one);
        tv_two = findViewById(R.id.tv_two);
        tv_three = findViewById(R.id.tv_three);
        iv_horn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tv_left_content.setVisibility(View.VISIBLE);
                iv_horn2.setClickable(false);
                Intent intent = new Intent();
                intent.setAction("Duck");
                //发送有序广播
//                sendOrderedBroadcast(intent, null);
                ThreeBroadcast threeBroadcast = new ThreeBroadcast();
                /**
                 * Intent intent:要发送的广播的意图(Intent)。这个Intent对象包含了要发送的数据和动作等信息。
                 * String receiverPermission:接收广播所需要的权限。如果设置为null,则不需要任何权限即可接收此广播。这个参数可以用来限制哪些应用可以接收这个广播。
                 * BroadcastReceiver resultReceiver:当广播发送完毕后,会调用这个BroadcastReceiver的onReceive方法,可以用来处理广播发送的结果。如果你不关心广播的结果,这个参数可以设置为null。
                 * Handler scheduler:用于处理resultReceiver回调的Handler。如果这个参数为null,那么回调将在主线程中运行。通常,你可以将其设置为null,除非你需要在特定的线程中处理回调。
                 * int initialCode:初始的结果代码,可以传递给resultReceiver。这个值通常用于区分不同的广播或表示广播的某种状态。
                 * String initialData:初始的结果数据,可以传递给resultReceiver。这个字符串可以包含任何你需要传递给结果接收器的额外信息。
                 * Bundle initialExtras:一个包含额外数据的Bundle,可以传递给resultReceiver。这是一个键值对的集合,允许你传递更复杂的数据结构给结果接收器。
                 */
                sendOrderedBroadcast(intent, null, threeBroadcast, null, 0, null, null);
            }
        });
    }


    //三个自定义广播

    /**
     * 1.实例化广播接收者
     * 2.处理中心 过滤器
     * 3.注册广播
     * 设置优先级 有序广播 数值越大 优先级越高
     * 数值相同时候 谁先注册 谁优先级高
     * 当在优先级高的onReceive()方法中加入abortBroadcast();就会拦截有序广播 后面就接受不到
     * 但可以在发送有序广播的时候指定广播 无论优先级高低还是拦截 都会接受到
     */
    class OneBroadcast extends BroadcastReceiver {


        @Override
        public void onReceive(Context context, Intent intent) {
            tv_one.setVisibility(View.VISIBLE);
            num = num + 1;
            tv_one.setText(num + "");
            Log.i("高远1", "广播one收到消息!");
            abortBroadcast();
            Log.i("高远1", "广播one被拦截");
            delay();


        }
    }

    class TwoBroadcast extends BroadcastReceiver {


        @Override
        public void onReceive(Context context, Intent intent) {
            tv_two.setVisibility(View.VISIBLE);
            num = num + 1;
            tv_two.setText(num + "");
            Log.i("高远2", "广播two收到消息!");
            delay();
        }
    }

    class ThreeBroadcast extends BroadcastReceiver {


        @Override
        public void onReceive(Context context, Intent intent) {
            num = num + 1;
            tv_three.setText(num + "");
            Log.i("高远3", "广播three收到消息!");
            delay();
        }
    }

    private void registerReceiver() {


        one = new OneBroadcast();
        IntentFilter intentFilter1 = new IntentFilter("Duck");
        intentFilter1.setPriority(1000);
        registerReceiver(one, intentFilter1);

        two = new TwoBroadcast();
        IntentFilter intentFilter2 = new IntentFilter("Duck");
        intentFilter2.setPriority(800);
        registerReceiver(two, intentFilter2);

        three = new ThreeBroadcast();
        IntentFilter intentFilter3 = new IntentFilter("Duck");
        intentFilter3.setPriority(500);
        registerReceiver(three, intentFilter3);
        tv_three.setVisibility(View.VISIBLE);
    }

    //设置延迟
    private void delay() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //伴随Activity的销毁 注册的广播接受者也伴随销毁
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(one);
        unregisterReceiver(two);
        unregisterReceiver(three);
    }
}

posted on 2024-06-18 09:04  蒸饺  阅读(23)  评论(0)    收藏  举报