第一章 四大组件之Broadcast Receiver

本文详细解析了Android中的广播机制,包括广播接收者与发送者的定义、创建与注册过程,探讨了不同类型的广播如普通广播、系统广播、有序广播及本地广播的特点与应用场景。此外,文章还介绍了如何处理广播的优先级,以及部分常见的系统广播常量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

零:参考

一、广播接收者

(一)定义

用于接收广播的组件,用于组件与组件之间进行通信,可以跨应用程序传递。
  • 注意:广播接收器运行在UI线程。
  • 优点:很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。

(二)创建、注册

1. Broadcast Receiver的创建

  • 继承BroadcastReceiver类,并实现其onReceive 方法。
  • 在onReceive方法内,我们可以获取随广播而来的Intent中的数据,这非常重要,就像无线电一样,包含很多有用的信息。
  • 代码演示:
public class MyBroadcastReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
   //对接收到的广播进行处理,intent里面包含数据
    }
}

2. Broadcast Receiver的注册

  • 在创建完BroadcastReceiver之后,还不能够使它进入工作状态,需要为它注册一个指定的广播地址。
  • 没有注册广播地址的BroadcastReceiver就像一个缺少选台按钮的收音机,虽然功能俱备,但也无法收到电台的信号。
(1)静态注册
  • 方式:在AndroidManifest.xml里通过< receiver >标签声明。
  • 特点:
    • App首次启动时,系统会自动实例化MyBroadcastReceiver类,并注册到系统中。
    • 常驻进程中,不受组件生命周期影响,就算组件生命周期结束后,还有广播发送过来,还是会被唤醒调用。
  • 应用场景:需要时刻监听广播。
  • 代码演示:
public class BootCompleteReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Boot complete", Toast.LENGTH_LONG).show();
    }
}
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        ...
		<receiver
			android:name=".broadcast.BootCompleteReceiver"
		    android:enabled="true"
		    android:exported="true">
		    <intent-filter>
		    	<action android:name="android.intent.action.BOOT_COMPLETED" />
		    </intent-filter>
		</receiver>
</application>
(2)动态注册
  • 方式:在代码中调用Context.registerReceiver()方法。
  • 特点:跟随组件的生命周期变化,如果组件生命周期结束了,广播就必须结束,否则会产生内存泄漏。
  • 应用场景:需要在特定时刻接收广播接收广播。
  • 代码演示:
public class MyBroadcastReceiver extends BroadcastReceiver {

    private static final String TAG = "MyBroadcast";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive: ");
        Toast.makeText(context, "received in MyBroadcast", Toast.LENGTH_SHORT).show();
    }
}
public class BroadcastActivity extends AppCompatActivity {

    MyBroadcastReceiver mBroadcast;
    // 选择在Activity生命周期方法中的onResume()中注册
    @Override
    protected void onResume() {
        super.onResume();

        // 1. 实例化BroadcastReceiver子类 &  IntentFilter
        mBroadcast = new MyBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();

        // 2. 设置接收广播的类型
        intentFilter.addAction(CONNECTIVITY_SERVICE);

        // 3. 动态注册:调用Context的registerReceiver()方法
        registerReceiver(mBroadcast, intentFilter);
    }

    // 注册广播后,要在相应位置记得销毁广播
    // 即在onPause() 中unregisterReceiver(mBroadcastReceiver)
    // 当此Activity实例化时,会动态将MyBroadcastReceiver注册到系统中
    // 当此Activity销毁时,动态注册的MyBroadcastReceiver将不再接收到相应的广播。
    @Override
    protected void onPause() {
        super.onPause();
        //销毁在onResume()方法中的广播
        unregisterReceiver(mBroadcast);
    }
}
  • 注意:在onResume()中注册和在onPause()中注销的原因:防止内存泄漏(某些场景中,onStop()不会被调用)。

(三)优先级

  • 优先级的范围:-2147483647到2147483647
  • 优先级的长度范围:Integer类型数据的最大值4294967296(2的32次方)。

(四)应用

  • 应用场合:发送频率低的情况可以使用,数据量小的情况可以使用。
  • 实际应用:
    • 操作系统电池电量低会发送一个广播,这样我们的程序里面可以去监听这个广播,可以关闭程序里面比较耗电的功能,提示用户注意保存进度;
    • 安装新应用;
    • 普通应用程序,例如启动特定线程,文件下载完毕等。

二、广播发送者

(一)发送方式

通过“意图(Intent)”的sendBroadcast()方法发送出去。

(二)广播类型

  • 普通广播(Normal Broadcast)
  • 系统广播(System Broadcast)
  • 有序广播(Ordered Broadcast)
  • 本地广播(Local Broadcast)

1. 普通广播

  • 开发者自身定义 intent的广播,通过Context.sendBroadcast(Intent intent)发送,可以同时被所有广播接收者无需等待的接收到。
    优点:异步、无差别接收、效率高。
  • 代码演示:
public class MyBroadcast extends BroadcastReceiver {

    private static final String TAG = "MyBroadcast";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive: ");
        Toast.makeText(context, "received in MyBroadcast", Toast.LENGTH_SHORT).show();
    }
}
<receiver
	android:name=".broadcast.MyBroadcast"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
    	<action android:name=".broadcast.MY_BROADCAST" />
    </intent-filter>
</receiver>
public class MyBroadcastActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broadcast);

        Button button = findViewById(R.id.btn_broadcast);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent =new Intent();
                intent.setComponent(new ComponentName( "com.example.first.broadcast" ,
                        "MyBroadcast") );
                intent.setAction("com.example.first.broadcast.MY_BROADCAST");
                sendBroadcast( intent );
            }
        });
    }
}
  • 注意:由于Android 8.0在静态广播中使用了限制,参考:https://developer.android.google.cn/about/versions/oreo/android-8.0.html
  • 这里有可能接收不到自定义的广播。
  • 解决方式是(三种方式任选其一)
    • 使用动态广播代替静态广播;
    • 保留原来的静态广播,添加intent.setComponent()方法;
    • 保留原来的静态广播,添加intent.setPackage(getPackageName());

2. 系统广播

  • 只要涉及到手机的基本操作(如开机、网络状态变化、拍照等等),基本上都会发出相应的系统广播。每个系统广播都具有特定的intent-filter,其中主要包括具体的action,系统广播发出后,将被相应的BroadcastReceiver接收。
  • 系统广播在系统内部当特定事件发生时,由系统自动发出。当使用系统广播时,只需要在注册广播接收者时定义相关的action即可,并不需要手动发送广播,当系统有相关操作时会自动进行系统广播。

3. 有序广播

  • 通过Context.sendOrderedBroadcast(intent, receiverPermission)发送,按照接收者声明的优先级别,被接收者依次接收广播。
  • 广播接受者接收广播的顺序规则(同时面向静态和动态注册的广播接受者)
    • 首先按照Priority属性值从大→小排序;
    • Priority属性相同者,动态注册的广播优先。
  • 优点:
    • 广播可以通过接收者调用abortBroadcast()方法截断广播(被截断的广播不能再继续传递该广播)。
    • 接收者能修改处理结果(比如通过传递Bundle)传递给下一个接收者(一般情况下,不建议对有序广播进行此类操作,尤其是针对系统中的有序广播)。
  • 缺点:消息传递的效率比普通广播低。

4. 本地广播

  • 使用LocalBroadcastManager来发送广播以及注册广播接收器。
  • 优点:安全。它发出的广播只会在应用程序的内部传播,不用担心广播被其他应用接收,造成数据泄漏,而广播接收器也只能接收到自己应用发出的广播,不会接收别的应用发来的广播,防止接收垃圾信息。
  • 本地广播无法通过静态注册方式接收。
public class LocalBroadcastActivity extends AppCompatActivity {

    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_local_broadcast);

        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        Button button = findViewById(R.id.btn_local_broadcast);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               Intent intent = new Intent("com.example.first.broadcast.LOCAL_BROADCAST");
               localBroadcastManager.sendBroadcast(intent);
            }
        });

        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.first.broadcast.LOCAL_BROADCAST");
        localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver,intentFilter);//注册本地广播监听器
    }

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

    class LocalReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
        }
    }
}

(三)部分系统广播常量

系统操作action
监听网络变化android.net.conn.CONNECTIVITY_CHANGE
屏幕被关闭Intent.ACTION_SCREEN_OFF
屏幕被打开Intent.ACTION_SCREEN_ON
屏幕锁屏Intent.ACTION_CLOSE_SYSTEM_DIALOGS
关闭或打开飞行模式Intent.ACTION_AIRPLANE_MODE_CHANGED
充电时或电量发生变化Intent.ACTION_BATTERY_CHANGED
电池电量低Intent.ACTION_BATTERY_LOW
电池电量充足Intent.ACTION_BATTERY_OKAY
插上外部电源时发出的广播Intent.ACTION_POWER_CONNECTED
已断开外部电源连接时发出的广播Intent.ACTION_POWER_DISCONNECTED
关闭或打开飞行模式Intent.ACTION_AIRPLANE_MODE_CHANGED
系统启动完成后Intent.ACTION_BOOT_COMPLETED
按下照相时的拍照按键(硬件按键)时Intent.ACTION_CAMERA_BUTTON
插入耳机时Intent.ACTION_HEADSET_PLUG
成功安装APKIntent.ACTION_PACKAGE_ADDED
成功删除APKIntent.ACTION_PACKAGE_REMOVED
重启设备Intent.ACTION_REBOOT
关闭系统时Intent.ACTION_SHUTDOWN
改变输入法时发出的广播Intent.ACTION_INPUT_METHOD_CHANGED
设备当前区域设置已更改时发出的广播Intent.ACTION_LOCALE_CHANGED
时间被设置时发出的广播Intent.ACTION_TIME_CHANGED
时区发生改变时发出的广播Intent.ACTION_TIMEZONE_CHANGED
设备日期发生改变时会发出此广播Intent.ACTION_DATE_CHANGED

三、消息推送

  1. 推送选择:极光推送
  2. 推送集成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值