Android - 广播Broadcast

简介

当某个特定事件发生时发送广播通知那些对该事件感兴趣的应用。可以是本应用,比如音乐软件常有的前台服务在通知栏里切歌都是用的广播;也可以跨应用,比如:系统中的锁屏,网络变更,耳机按钮点击都会有广播,但是需要注意各个版本之间系统广播的差异,因为Android越来越注重用户隐私,一些系统广播可能无法获取想要的信息。

发送广播

  • LocalBroadcastManager.sendBroadcast:用于当前应用内部发送广播,接收器也在本应用,这样更安全也更高效,因为不用跨进程。
//新建意图
Intent intent = new Intent();
intent.setAction("com.dean.broadcast.MUSIC_NEXT");
intent.putExtra("control","next");
//发送广播
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
  • Context.sendOrderedBroadcast:通过intent-filter中的priority来控制按顺序一个一个发送广播,如果priority一样则顺序随机。当前接收器处理完广播后可以向下传递结果,也可以阻止广播向下传递。
Intent intent = new Intent();
intent.setAction("com.dean.broadcast.MUSIC_NEXT");
intent.putExtra("control","next");
mContext.sendBroadcast(intent);
  • Context.sendBroadcast:随机顺序全体发送广播,效率高,但是无法传递结果也无法中止。
Intent intent = new Intent();
intent.setAction("com.dean.broadcast.MUSIC_NEXT");
intent.putExtra("control","next");
mContext.sendOrderedBroadcast(intent);

接收广播

  1. 创建广播接收类,类继承自BroadcastReceiver,并且在onReceive方法中处理广播内容
  2. 注册广播
  • 静态注册:在AndroidManifest.xml中注册
<receiver android:name=".services.MusicBroadcastReceiver">
	<intent-filter >
		<action android:name="android.intent.action.MEDIA_BUTTON"/>
	</intent-filter>
</receiver>
  • 动态声明
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
registerReceiver(musicBroadcast, intentFilter);

注:

  1. 如果广播接收器接收到广播,onReceive()方法会被执行,这时该应用的进程就是前台进程,几乎不会被回收。如果是静态注册的,并且广播发射时应用没有在运行,这时应用会启动,因此许多系统广播都改为了动态注册。
  2. onReceive()执行完成后,进程会被降低优先级,如果是静态注册被启动的应用可能会被立即终止
  3. 在onReceive内处理广播时,不应有耗时操作,因为onReceive是在主线程中运行的,即使新开线程,也会在onReceive执行完后系统回收进程时一并回收在onReceive派生出的线程
  4. 如果要提高进程存活度,在接收到广播后多执行一段时间,可以在onReceive内直接使用goAsync()或者使用JobScheduler 调度 JobService
@Override
public void onReceive(Context context, Intent intent) {
	InnerTask innerTask = new InnerTask(goAsync(), "a");
	innerTask.execute();
}

private static class InnerTask extends AsyncTask<String, Integer, Integer>{
	PendingResult pendingResult;
	String params;

	public InnerTask(PendingResult pendingResult, String params){
		this.pendingResult = pendingResult;
		this.params = params;
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		Log.d(LOG_TAG, "广播任务开始");
	}

	@Override
	protected Integer doInBackground(String... strings) {
		Log.d(LOG_TAG, "广播任务进行中");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return 0;
	}

	@Override
	protected void onPostExecute(Integer s) {
		super.onPostExecute(s);
		pendingResult.finish();
		Log.d(LOG_TAG, "广播任务完成");
	}
}


执行结果
19:36:00.982 31798-31798/com.mh.smart D/MusicBroadcastReceiver: 广播任务开始
19:36:00.988 31798-509/com.mh.smart D/MusicBroadcastReceiver: 广播任务进行中
19:36:05.993 31798-31798/com.mh.smart D/MusicBroadcastReceiver: 广播任务完成

实例:耳机插拔广播接收

新建广播接收类
public class MusicBroadcastReceiver extends BroadcastReceiver {
    private static final String LOG_TAG = MusicBroadcastReceiver.class.getSimpleName();
    @Override
    public void onReceive(Context context, Intent intent) {
        //耳机插拔
        if (Intent.ACTION_HEADSET_PLUG.equals(intent.getAction())){
            if (intent.hasExtra("state")){
                if (intent.getIntExtra("state", 0) == 0){
                    Log.d(LOG_TAG, "耳机拔出");
                }else if (intent.getIntExtra("state", 0) == 1){
                    Log.d(LOG_TAG, "耳机插入");
                }
            }
        }
    }
}


注册广播:需要动态
private void registerMusicBroadcast(){
	musicBroadcast = new MusicBroadcastReceiver();
	IntentFilter intentFilter = new IntentFilter();
	intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
	registerReceiver(musicBroadcast, intentFilter);
}


及时关闭:一般看在哪注册,oncreate注册就是ondestory销毁。onresume注册就在onpause销毁
unregisterReceiver(musicBroadcast);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值