Android四大组件之Broadcast使用及运行机制

广播介绍

1.安卓四大组件之一
2.广播使用了观察者模式
3.进程间通信

广播发送

  • 广播分类
1.普通广播(Broadcast)
<1>.发送一个广播,所有监听该广播的广播接收者都可以监听到改广播
<2>.完全异步的,接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播

2.有序广播(OrderedBroadcast)
<1>.按照接收者的优先级顺序接收广播,优先级别在intent-filter中的priority中声明,-1000到1000之间,值越大,优先级越高
<2>.可以终止广播意图的继续传播.接收者可以篡改内容.广播Intent的传播一旦终止,后面的接收者就无法接收到广播

3.粘性广播(StickyBroadcast)
<1>.粘性广播在发送后就一直存在于系统的消息容器里面,等待对应的处理器去处理,如果暂时没有处理器处理这个消息则一直在消息容器里面处于等待状态
<2>.粘性广播的Receiver如果被销毁,那么下次重建时会自动接收到消息数据
<3>.发送黏性广播需要权限<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<4>.粘性广播一般用来确保重要的状态改变后的信息被持久保存,并且能随时广播给新的广播接收器
<5>.可以【先发送,后接收】
Andriod Application Study Note Url 10 sendBroadcast.jpg
  • 发送广播
public class MainActivity extends Activity {
    private static final String NORMAL_ACTION = "com.example.broadcast_NORMAL";
    private static final String ORDER_ACTION = "com.example.broadcast_ORDER";
    private static final String STICKY_ACTION = "com.example.broadcast_STICKY";

    private static final String RECEIVER_PERMISSION = "com.example.broadcast_RECEIVER_PERMISSION";

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

        sendNormalBroadcast();
        sendOrderBroadcast();
        sendStickyBroadcast();
    }

    // 发送普通广播
    private void sendNormalBroadcast() {
        Intent intent = new Intent();
        intent.setAction(NORMAL_ACTION);
        intent.putExtra("args", "Normal Broadcast");
        sendBroadcast(intent);
    }

    // 发送有序广播
    private void sendOrderBroadcast() {
        Intent intent = new Intent();
        intent.setAction(ORDER_ACTION);
        intent.putExtra("args", "Order Broadcast");
        sendOrderedBroadcast(intent, RECEIVER_PERMISSION);
    }

    // 发送粘性广播
    private void sendStickyBroadcast() {
        Intent intent = new Intent();
        intent.setAction(STICKY_ACTION);
        intent.putExtra("args", "Sticky Broadcast");
        sendStickyBroadcast(intent);
    }
}

广播注册

  • 注册广播方式
1.静态注册
在AndroidManifest.xml文件中定义,注册的广播接收器必须继承BroadReceiver

2.动态注册
在程序中使用Context.registerReceiver进行注册
  • 静态注册方式
 
<!-- 配置到AndroidManifest.xml中 -->
<receiver android:name=".BootBroadcastReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>
// 继承BroadcastReceiver,重写onReceive方法
public class BootBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO something
    }
}
  • 动态注册方式
public class TestActivity extends Activity {
    private IncomingSMSReceiver mReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mReceiver = new IncomingSMSReceiver();
        registerReceiver();
    }

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

    // 注册IncomingSMSReceiver广播接收器
    private void registerReceiver() {
        IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
        registerReceiver(mReceiver, filter);
    }

    // 程序退出后,需要取消注册
    private void unregisterReceiver() {
        unregisterReceiver(mReceiver);
    }

    // 继承BroadcastReceiver,重写onReceive方法
    private class IncomingSMSReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO
        }
    }
}
  • 动态注册与静态注册区别
1.动态注册的广播永远要快于静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级有多低

2.动态注册广播不是常驻型广播,也就是说广播跟随activity的生命周期。注意:在activity结束前,移除广播接收器
  静态注册是常驻型 ,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行

3.在同一个优先级下,谁先启动的快,谁将先接收到广播

广播接收

  • 接收广播
通过静态或动态方式注册后,重写onReceive方法,当收到广播后会回调该方法
  • 常见系统广播
// 开机启动完成
Intent.ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";

// 外置存储卸载/挂载
Intent.ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED";
Intent.ACTION_MEDIA_MOUNTED = "android.intent.action.MEDIA_MOUNTED";

// 灭屏/亮屏
Intent.ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF"
Intent.ACTION_SCREEN_ON = "android.intent.action.SCREEN_ON";

// 飞行模式状态改变
Intent.ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE";

// 低电
Intent.ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";

// 配置改变,如屏幕旋转
Intent.ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED";

// 插入耳机
Intent.ACTION_HEADSET_PLUG = android.media.AudioManager.ACTION_HEADSET_PLUG;

// 关机
Intent.ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";

// 重启
Intent.ACTION_REBOOT = "android.intent.action.REBOOT";
  • 实例
public class ReceiveBroadcast extends Activity {
    private static final String TAG = "ReceiveBroadcast";

    private static final String NORMAL_ACTION = "com.example.broadcast_NORMAL";
    private static final String ORDER_ACTION = "com.example.broadcast_ORDER";
    private static final String STICKY_ACTION = "com.example.broadcast_STICKY";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        IntentFilter filter = new IntentFilter();
        filter.addAction(NORMAL_ACTION);
        filter.addAction(ORDER_ACTION);
        filter.addAction(STICKY_ACTION);
        registerReceiver(mBroadcastReceiver, filter);
    }

    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (NORMAL_ACTION.equals(action)) {
                // 接收无序广播
                String message = intent.getStringExtra("args");
                Log.v(TAG, "无序广播:" + message);
            } else if (ORDER_ACTION.equals(action)) {
                // 接收有序广播
                Bundle bundle = intent.getExtras();
                bundle.putBoolean("is_continue", true);

                // 向后面的接收者传递数据
                setResultExtras(bundle);

                // 终止继续传递
                // abortBroadcast();
            } else if (STICKY_ACTION.equals(action)) {
                // 接收粘性广播,先发送,后注册也能收到
                String message = intent.getStringExtra("args");
                Log.v(TAG, "粘性广播:" + message);

                // 移除该粘性广播
                removeStickyBroadcast(intent);
            }
        }
    };
}

实现原理

  • 原理
1. 广播使用了观察者模式实现
2. 接收广播前需要注册,主要注册到ActivityManagerService中,一个广播发出后会到AMS中,这时候AMS会对注册了该广播的程序进行派发
  • 原理图
Andriod Application Study Note Url 10 yuanli.jpg

流程

  • 注册流程
动态注册 - 动态注册是直接注册到AMS中
Andriod Application Study Note Url 10 dongtaizuce.jpg


Andriod Application Study Note Url 10 dongtaizuce1.jpg


Andriod Application Study Note Url 10 dongtaizuce2.jpg
静态注册 - 静态注册是配置到配置清单文件里,由PMS解析,AMS直接从PMS获取
Andriod Application Study Note Url 10 jingtai.jpg


Andriod Application Study Note Url 10 jingtai1.jpg
  • 发送接收流程
派发流程
Andriod Application Study Note Url 10 paifa.jpg
无序广播派发与接收流程
Andriod Application Study Note Url 10 paifa1.jpg
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值