从一开始只认识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是一样的,其实一想就会明白,如果不一样,则会出现接收不到的情况(无法匹配)。到此,关于广播的一些知识就整理完了,希望能给大家带来一点儿帮助。