《第一行代码》——广播

整理自《第一行代码》第五章

Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收到自己所关心的广播内容。这些广播可能是来自于系统的,也可能是来自于其他应用程序的。

标准广播 完全异步执行的广播,在广播发出后,所有广播接收器几乎在同时收到广播信息。效率高,但无法被截断。

有序广播 同步执行的广播,同一时刻只有一个广播接收器能够收到这条广播消息,当逻辑执行完毕后,广播才会继续传递。优先级高的广播接收器可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播。

接收系统广播

广播接收器receive方法中逻辑过多或任何其他运行时间过长都会导致程序报错。因此广播接收器更多扮演一种打开程序其他组件如创建状态栏通知,或启动一个服务等。

动态接收
public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFilter = new IntentFilter();//字面意义为“意图过滤器”
        //匹配测试只考虑 动作、数据(URI及数据类型)和类别 
        //addAction添加想要监听的广播
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetworkChangeReceiver();
       //registerReceiver方法注册广播
        registerReceiver(networkChangeReceiver,intentFilter);
    }

    protected void onDestroy(){
        super.onDestroy();
        //动态注册的广播接收器需要取消
        unregisterReceiver(networkChangeReceiver);
    }
	
    //内部类继承BroadcastReceiver类,当网络状态发生变化时,onReceive方法就会执行
    class NetworkChangeReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context,"network changes",Toast.LENGTH_SHORT).show();
        }
    }
}
静态注册实现开机启动

右击com.example.broadcasttest包——>New——>Other——>Broadcast Receiver,在窗口中设置名字。Exported属性表示是否允许广播接收器接收本程序以外的广播,Enabled属性表示是否启用。完成后可以重写onReceive方法。

AndroidMainfest.xml中已经有<receiver>标签了。但仍需要添加权限。

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
//此条语句没有提示跳出,验证也并不成功,有待考究

发送自定义广播

发送标准广播

新建一个自定义的广播接收类,在AndroidMainfest.xml中声明接收这样的广播。最后的效果是点击按钮即会显示自定义的toast语句。

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();
    }
}
//接收到信息即输出这句话
Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
                sendBroadcast(intent);
            }
        });
//对按钮设置事件监听,可以看到,广播信息是通过intent进行传递的,将其送出。
<receiver android:name=".MyBroadcastReceiver"
           android:enabled="true"
           android:exported="true">
           <intent-filter>
               <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
           </intent-filter>
       </receiver>
发送有序广播

相同的方法定义新的广播接收器,可以发现在点击按钮后都能收到广播信息。

如果需要发送有序广播,只需要将sendBroadcast改为sendOrderedBroadcast方法即可。sendOrderedBroadcast中的两个参数,第一个是意图,第二个是有关权限的字符串,此时传null.

 Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
                sendOrderedBroadcast(intent,null);
            }
        });

广播接收器的先后顺序在注册时设定。此时在先接收到广播的onReceive方法中调用abortBroadcast()方法,即可截断这条广播,优先级小于其的接收器将无法接收。

<receiver android:name=".MyBroadcastReceiver"
           android:enabled="true"
           android:exported="true">
           <intent-filter android:priority="100">//注意此处设定了优先级
               <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
           </intent-filter>
       </receiver>

本地广播

注意要导入support-v4包

首先通过LocalBroadcastManagergetInstantce()方法得到实例,注册时调用LocalBroadcastManagerregisterReceiver()方法,发送广播调用LocalBroadcastManagersendBroadcast()方法。

本地广播只会在程序内部传播。本地广播无法通过静态注册方式来接收。

优势:

  • 可以明确知道正在发送的广播不会离开程序,不必担心数据泄露
  • 其他程序无法发送广播至程序内部,没有安全漏洞的隐患
  • 发送本地广播比发送系统全局广播更高效
 private localReceiver localReceiver;
 private LocalBroadcastManager localBroadcastManager;
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                localBroadcastManager.sendBroadcast(intent);
            }
        });
     	intentFilter = new IntentFilter();
        intentFilter.addAction("com.android.broadcasttest.LOCAL_BROADCAST");
        localReceiver = new localReceiver();
        localBroadcastManager.registerReceiver(localReceiver,intentFilter);
 }
    protected void onDestroy(){
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }
    class localReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context,"local broadcast",Toast.LENGTH_SHORT).show();
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值