Android中的广播Broadcast

从一开始只认识Activity到现在开始逐步学习其他三大组件,这是个漫长的过程,今天刚好学了一点儿Broadcast的内容,总结一下。顾名思义,Broadcast,即为广播的意思,那么这样一个广播在Android开发中起什么作用呢?首先,从传统意义上来讲,广播的作用是为了传递信息,那么Broadcast同样也是用来传递信息的,而且传递的还是全局信息,即Android中的系统信息,比如短信的收发,不同应用程序之间的信息传递,这些都是基于Broadcast来实现的。相对于Activity来说,广播是一种被动接收数据的组件,类似于事件(Event),只有信息传过来才会被调用,看似和阻塞式方法有点儿像,二者都是有信息传入才执行,但是阻塞式方法是同步的,会一直等待,直到执行完方法,而Broadcast并不是一直在等待,只有有消息传来才会调用,其他时间并没有在等待。

Broadcast在使用时,通常会有两种注册方式,动态注册和静态注册,其实很好理解,所谓动态注册,就是可以直接通过registerReceiver方法来注册,类似于需要即注册;而静态注册,则是通过自定义一个Broadcast的子类,然后通过AndroidMainfest.xml文件中注册,这种注册方式就像是一开始就在Android中标记了一个广播,只是不清楚什么时候使用。两种方式均有存在的意义(存在即合理嘛),但后者如果需要注册的广播数量较多的话,则会在一开始占用很多的资源内存,因为一开始或许并不会全部调用到。下面是两种注册方式的部分代码:

1.动态注册:(利用Broadcast获得手机当前电量)

 private TextView tvBatteryChanged;
    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //判断接收到的是否为电量变化的Broadcast Action
            if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())){
                //level表示当前电量的值
                int level = intent.getIntExtra("level",0);
                //scale表示电量的总刻度
                int scale = intent.getIntExtra("scale",100);
                //将当前电量换算成百分比的形式
                tvBatteryChanged.setText("电池用量:" + (level * 100 / scale) + "%");
            }
        }
    };
@Override
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     tvBatteryChanged = (TextView) findViewById(R.id.textView);
     //注册Receiver
     registerReceiver(broadcastReceiver,new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
很明显,上述注册方式是直接在onCreate中调用注册,而在这之前,已经实例化一个Broadcast对象,复写了其中的onReceive方法。

2.静态注册:

2.1自定义一个继承自Broadcast类的子类

public class BatteryBroadcast extends BroadcastReceiver {
    TextView tvBatteryChanged;
    @Override
    public void onReceive(Context context, Intent intent) {
        //判断接收到的是否为电量变化的Broadcast Action
        if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())){
            //level表示当前电量的值
            int level = intent.getIntExtra("level",0);
            //scale表示电量的总刻度
            int scale = intent.getIntExtra("scale",100);
            //将当前电量换算成百分比的形式
            tvBatteryChanged.setText("电池用量:" + (level * 100 / scale) + "%");
        }
    }
}
2.2 AndroidMainfest.xml文件中注册

<receiver android:name=".BatteryBroadcast">
     <intent-filter>
         <action android:name="android.intent.action.ACTION_BATTERY_CHANGED"/>
     </intent-filter>
</receiver>
这样就实现了静态注册,需要注意的是,不管是动态注册还是静态注册,我们都可以自定义Action来进行判断,例如在静态注册中,Mainfest.xml文件中的注册receiver其中的action可以使用自定义的action,有些时候,同时也会添加一个自定义的category,例如下面这个Demo。

<receiver android:name=".CustomReceiver">
   <intent-filter>
        <action android:name="mobile.android.renkai.MYBROADCAST"/>
        <category android:name="mobile.android.renkai.mycategory"/>
   </intent-filter>
</receiver>
了解了注册的方式,那么我们想要实现某个事件的信息接收,具体应该怎么做呢?其实,广播的原理很简单,通过判断一个具体的动作,对这个动作我们可以自定义一种信息(或者系统本身就已经定义好了该动作的信息),然后通过该动作状态的改变,将信息传递到接收器中,从而告知我们是实现了什么动作,所以,个人认为,广播的关键在于动作事件。了解了这个以后,要实现的话,就很简单了,只需要复写Broadcast类的onReceive方法即可。

接下来,通过两个Demo来了解一下关于Broadcast的接收

1.简单的熄屏和亮屏信息接收(系统自身的动作)

ScreenOnOffReceiver.class

public class ScreenOnOffReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //接收屏幕唤醒状态的广播
        if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())){
            Log.d("screen","ok");
            System.out.println("Screen is ok!");
        }
        //接收屏幕休眠状态的广播
        else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())){
            Log.d("screen","off");
            System.out.println("Screen is off!");
        }
    }
}
MainActivity.class

 private ScreenOnOffReceiver screenOnOffReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        screenOnOffReceiver = new ScreenOnOffReceiver();
        IntentFilter intentFilter = new IntentFilter();
        //设置屏幕唤醒广播的动作
        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
        //设置屏幕休眠广播的动作
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
        registerReceiver(screenOnOffReceiver,intentFilter);
    }
我们使用了动态注册的方式,通过添加了两个动作来实现判断。

2.自定义发送端和接收器

2.1发送端

通过查阅API发现,发送广播的方法有四种,但比较常用的是sendBroadcast,其参数类型也比较简单,只有一个Intent,本文通过自定义添加一个action和category来进行广播的发送和接收。代码如下:

public void onClick_sendBroadcast(View v){
        //指定广播动作
        Intent broadcastIntent = new Intent("mobile.android.renkai.MYBROADCAST");
        //添加category
        broadcastIntent.addCategory("mobile.android.renkai.mycategory");
        //设置广播数据
        broadcastIntent.putExtra("name","broadcast_data");
        //发送广播
        sendBroadcast(broadcastIntent);
        Toast.makeText(this, "广播发送成功!", Toast.LENGTH_SHORT).show();
    }
2.2广播接收器

CustomReceiver.class

public class CustomReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if ("mobile.android.renkai.MYBROADCAST".equals(intent.getAction())){
            //获得广播数据
            String name = intent.getStringExtra("name");
            Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
        }
    }
}
静态注册:

<receiver android:name=".CustomReceiver">
   <intent-filter>
       <action android:name="mobile.android.renkai.MYBROADCAST"/>
       <category android:name="mobile.android.renkai.mycategory"/>
   </intent-filter>
</receiver>
这样就可以实现自定义收发广播,而且是在不同的Activity之间,仔细阅读上述代码,你会发现,在接收器的注册代码中的action和category和发送端自定义的action和category是一样的,其实一想就会明白,如果不一样,则会出现接收不到的情况(无法匹配)。到此,关于广播的一些知识就整理完了,希望能给大家带来一点儿帮助。














发布了72 篇原创文章 · 获赞 42 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/xiaoxun2802/article/details/72791237