• Android 中的广播(Broadcast)


    Android 广播(broadcast)

    饮水思源 本文章内容学习和总结自

    郭霖大神:《Android第一行代码》

    Overview

    就像我们的学校里的喇叭一样,是用来通知的。而Android中的广播,要更加的灵活。

    广播分类

    • 无序广播:是一种完全异步的执行的广播,广播发出以后,所有的广播接收器几乎都会在同一时间接收到这条广播,没有先后的顺序,效率相对较高,并且无法截断。
    • 有序广播: 是一种同步执行的广播,在广播发出以后,同一时刻只会有一个广播接收器能够收到这条广播消息,该广播接收器的逻辑执行完毕后,广播才会继续传递。广播是有先后顺序的,优先级较高的广播接收者会优先接收到消息,可以经广播进行截断或者向广播中添加新的内容。

    Note:

    • 广播接收者,是四大组件中特殊的一个,他可以在清单文件中静态注册,也可以通过代码动态注册。
    • 如果是动态注册的时候,必须在 onDestroy() 生命周期方法中取消注册,否则就会造成内存泄漏。
    • 无序广播无法在,广播传递的过程中截止广播和添加数据。
    • 有序广播可以在,广播传递的过程中添加数据或者截断广播
      • 添加数据使用,this.setResultData(); 等方法.
      • 截断广播使用, this.abortBroadcast();
    • 有序广播通过设置广播接收者的优先级我们可以来确定,哪个广播接收者可以优先接收到广播。
    • 系统的广播
      • 当一个系统的广播,是频发发出的,那么该广播只能通过动态注册的方式来接收,比如 屏幕开关的广播

    为什么有序广播的优先级是-1000至1000

    接收系统的广播

    Android 中内置了许多的系统的广播,我们可以通过监听系统的广播来得到各种系统的状态信息,手机开机发出广播,网络变化发出广播等等。

    动态注册广播接受者

    Demo: 动态注册广播接收者,接收网络发生变法的广播

    package com.example.it.studybroadcast;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.Toast;
    
    public class HomeActivity extends AppCompatActivity {
    
        private NetWorkReceiver receiver;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_home);
    
            //创建一个意图过滤器
            IntentFilter filter = new IntentFilter();
            //接收网络改变的action
            filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    
            receiver = new NetWorkReceiver();
    		//注册广播
            this.registerReceiver(this.receiver, filter);
        }
    
        /*
        * 取消注册
        * */
        @Override
        protected void onDestroy() {
            super.onDestroy();
            this.unregisterReceiver(this.receiver);
        }
    
        public class NetWorkReceiver extends BroadcastReceiver {
    
            @Override
            public void onReceive(Context context, Intent intent) {
    
                ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    
                //如果当前有默认的网络就返回NetworkInfo 否则就返回 null
                NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
                //因为可能是null 所以要先判断是否为空
                if (networkInfo != null && networkInfo.isAvailable()) {
                    if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                        Toast.makeText(context, "Wifi", Toast.LENGTH_SHORT).show();
    
                    } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                        Toast.makeText(context, "流量", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(context, "世界上最遥远的距离就是没有网", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
    
    

    静态注册广播接收者

    Demo:实现开机启动

    清单文件

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.it.studybroadcast">
    
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".HomeActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name=".RootComplatedActivity"></activity>
    		<!--注册我们的开机广播-->
            <receiver
                android:name=".MyBootComplatedReceiver"
                android:enabled="true"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                </intent-filter>
            </receiver>
        </application>
    
    </manifest>
    

    Java 代码

    public class MyBootComplatedReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent gotoIntent = new Intent(context, RootComplatedActivity.class);
            context.startActivity(gotoIntent);
        }
    }
    

    自定义广播

    无序广播

    发送一个无序广播

    public void sendOrdered(View view) {
        Intent intent = new Intent();
      	//放入我们的数据
        intent.putExtra("MyKey", "我是自定义发送的广播");
        //放我我们Action,用来区分其他广播,注意Acting不要和系统的广播重复
        intent.setAction("com.example.it.studybroadcast.CustomBroadcast");
        this.sendBroadcast(intent);
    }
    

    定义广播接收者接收我们的无序广播

    清单文件中配置一下广播接收者

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.it.studybroadcast">
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
    		------
            <receiver
                android:name=".MyReceiver"
                android:enabled="true"
                android:exported="true">
                <intent-filter>
                    <action android:name="com.example.it.studybroadcast.CustomBroadcast" />
                </intent-filter>
            </receiver>
          	-----
        </application>
    
    </manifest>
    

    Java 代码

    public class MyReceiver extends BroadcastReceiver {
        public MyReceiver() {
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            String value = intent.getStringExtra("MyKey");
            Toast.makeText(context, value, Toast.LENGTH_SHORT).show();
        }
    }
    
    有序广播

    清单文件

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.it.studybroadcast">
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
    		------
            <receiver
                android:name=".MyOrderedReceiverOne"
                android:enabled="true"
                android:exported="true">
              	<!--设置我们的优先级 优先级的范围是 -1000到1000-->
                <intent-filter android:priority="1000">
                    <action android:name="com.example.it.studybroadcast.MyOrderedBroadcast" />
                </intent-filter>
            </receiver>
            <receiver
                android:name=".MyOrderedBroadcastTwo"
                android:enabled="true"
                android:exported="true">
                <intent-filter android:priority="999">
                    <action android:name="com.example.it.studybroadcast.MyOrderedBroadcast" />
                </intent-filter>
            </receiver>
          -------------
        </application>
    </manifest>
    
    

    Java 代码

    /*
    * 发送一个有序广播
    * */
    public void sendOrderedBroadcast(View view) {
        Intent intent = new Intent();
        intent.setAction("com.example.it.studybroadcast.MyOrderedBroadcast");
        //放入一些数据
        intent.putExtra("MyKey", "MyKeyVlaue");
        /*
        * 参数:
        * intent: 我们发送的意图
        * receiverPermission: 广播接收者必须有的权限
        * */
        this.sendOrderedBroadcast(intent, null);
    }
    
    /*
    	广播接收者
    */
    public class MyOrderedReceiverOne extends BroadcastReceiver {
        public MyOrderedReceiverOne() {
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            String value = intent.getStringExtra("MyKey");
            Toast.makeText(context, value, Toast.LENGTH_SHORT).show();
    
            //添加数据
            this.setResultData("我是添加的内容!");
        }
    }
    
    
    public class MyOrderedBroadcastTwo extends BroadcastReceiver {
        public MyOrderedBroadcastTwo() {
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, getResultData(), Toast.LENGTH_SHORT).show();
            //截断我们的广播
            this.abortBroadcast();
        }
    }
    
    

    源码下载

    https://git.oschina.net/ShareKnowledge/StudyBroadcast

  • 相关阅读:
    Jmeter----读取excel表中的数据
    Jmeter-----【mac电脑】配置web浏览器的代理抓取请求
    Git----GitHub上传本地文件到git
    Postman----Newman的使用
    Postman----安装Newman
    Postman----设置代理抓取手机上的请求
    postman-----使用CSV和Json文件实现批量接口测试
    【已解决】【Mac】 运行adb提示command not found,需要配置adb环境
    浅析Java中的final关键字
    git branch简单使用
  • 原文地址:https://www.cnblogs.com/slyfox/p/7216145.html
Copyright © 2020-2023  润新知