Android-广播详解

发布于:2025-07-27 ⋅ 阅读:(19) ⋅ 点赞:(0)

目录

动态注册

静态注册:

显示广播和隐式广播的区别:

标准广播和有序广播的发送:

发送有序广播

发送无序广播

使用本地广播:


广播的分类:

按照发送方式分类:

  1. 标准广播

是一个完全异步执行的广播,几乎同时的接收器会收到这个广播,效率比较高,无法截断;

     2. 有序广播

是同步执行,同一时刻只有一个接受器才能接受到消息,优先级高的接收器先接受到,同时也可以进行截断

     3. 本地广播

应用内广播,不会被其他应用接收到,更安全,不会泄露信息,但只能用于同一个 app 内部通信。

      4. 粘性广播

广播发送后会一直保留,即使接收器之后才注册也能收到最近的一条广播,但可能造成数据泄露、资源占用;

但如果按照注册方式分类,可以分为静态注册和动态注册:我们先来看看动态注册:

动态注册

我们来对过程做一个解析:

  1. 自定义一个网络接收器的类:继承BroadcastReceiver;

  2. 注册:new一个intentfilter对象,通过对象的addAction方法,可以将我们所要接受的广播进行添加;最后获得网络接收器的实例,通过方法registerReceiver(),有两个参数,第一个参数是网络接收器的对象,第二个参数是intentfilter的对象;

  3. 因为是动态在Oncreat里面注册的对象,所以还需要在onDestory的时候进行销毁:调用unregisterReceiver(网络接收器的对象);

  4. 我们还需要判断是否有网络进行具体的提示:

通过方法getSystemService方法得到服务类ConnectiVITYManager的实例,参数是Context.CONNECTIVITY_SERVICE,然后通过实例的getActiveNetWorkInfo()方法,得到networkinfo的对象,通过isAvailable方法的判断;

上面这段是判断有无网络的提示,如果您只是单纯想学习广播的话,可以不用看,但最好完成这个案例;代码如下:


public class MainActivity extends AppCompatActivity {
    private  NetworkChangeReceiver ncr;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        IntentFilter intentfilter = new IntentFilter();
        intentfilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        ncr  = new NetworkChangeReceiver();
        registerReceiver(ncr,intentfilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(ncr);
    }

    class NetworkChangeReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
            if(activeNetworkInfo!=null && activeNetworkInfo.isAvailable()){
                Toast.makeText(context,"uesablae",Toast.LENGTH_SHORT).show();

            }
            else{
                Toast.makeText(context,"unuseable",Toast.LENGTH_SHORT).show();
            }


        }
    }

为了大家理解,我把重点的代码贴到这里:
 

    IntentFilter intentfilter = new IntentFilter();
        intentfilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        ncr  = new NetworkChangeReceiver();
        registerReceiver(ncr,intentfilter);

静态注册:

不是所有的都允许静态注册,要根据最新的文档来确定:

要点如下:

  1. 不用打开app,也能实现注册;

  2. 步骤是:在包下创建一个接收器,在接收器的onrecive方法中,弹出提示消息,作为我们的成果演示;

  3. 添加intentfilter标签,同时也需要得到许可:user-permisssion

<receiver
    android:name=".BootCompleteReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
         <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>
//许可
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

以上都是在androidmanifest,xml文件中进行的;

pay attention to!!!

不建议添加过多的逻辑,因为不允许开启线程,当有onreceive方法耗时操作时,程序就会报错 ;

显示广播和隐式广播的区别:

显示广播:指明确了我要发的组件,通过intent.setpackage()参数是getPackageName();

通过方法指定了广播目标所属的包名,只会发给app中具有对应action的接收器

隐式广播: 不指定接收器,只指定action,所有注册action的接收器选择谁来接收

Android8.0以后静态注册只接受显示广播,除了系统广播;

那么有人要问了,我在这里为什么要强调显示广播和隐式广播的区别呢?

是因为:

  • 从 Android 8.0 开始,系统对静态注册的隐式广播进行了限制,以减少后台资源消耗、提升性能;

  • 被系统限制的隐式广播只支持显式广播的方式发送;

标准广播和有序广播的发送:

发送有序广播

1. 通过Intent对象,参数是广播的值,跟注册接受广播器的action是一致的,都包括包名.名字;

  1. 通过方法:sendBoradcast(intent对象)来发送信息;

发送无序广播

  1. 可以通过在XML文件中的广播组件中,利用android:priority来设置优先级;

  2. 通过sendOrderedbroadcase(intent,null)来发送

因为两者代码只有一处不一样,所以这里就贴出一段代码: 

Intent a = new Intent("com.example.broadcasttest.MY_M ES");
a.setPackage(getPackageName());
sendOrderedBroadcast(a,null);

使用本地广播:

只需要在类中定义成员变量: 通过LocalBroadcastManager对广播进行管理,并提供了注册和发送广播的方法;

  1. 获取实例:LocalBroadcastManager.getINstance(this)方法

  2. 通过实例对象可以registerReceiver和sendBroadcast(intent)

注意事项: 只能通过动态注册的方式,静态注册主要是想让我们没打开程序时也能收到广播,但是发送广播时,程序肯定启动,就没必要使用静态注册

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private  NetworkChangeReceiver nevt;
    private LocalBroadcastManager lbm;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        lbm = LocalBroadcastManager.getInstance(this);
        IntentFilter iff= new IntentFilter();
        iff.addAction("android.intent.action.pp");
       nevt = new NetworkChangeReceiver();
        lbm.registerReceiver(nevt,iff);
        @SuppressLint({"MissingInflatedId", "LocalSuppress"}) View view = findViewById(R.id.button);
        view.setOnClickListener(this);
    }

实例总结:

  1. 如果有提示牌,记得用show来调用;

  2. 在配置xml文件中,主活动必须设置为可以由外部应用来调用

android:exported="true"

  1. 总体的思路:先化个登录界面的ui,然后写登录界面的活动:从文本框里获取字符串比较,如果成功的话就跳转到下一个活动,再写主活动,在主活动中,设置按钮,发送广播;在定义广播接收器,BasicActivity:因为必须要让所有的活动都可以接受到,这个一开始就先写,因为效果是关闭,所以ActivityCollector也必须先写;

 以上的实例总结是我个人的学习总结,各位可用于知识点的复习,如果不需要可跳过;

 好啦,就到这里!


网站公告

今日签到

点亮在社区的每一天
去签到