广播接收器:
Android四大组件之一。
发送广播一般用的是隐式意图!
Broadcast是一种广泛应用在应用程序之间传输信息的机制。
广播是Android中跨进程通讯的一种机制。
组件与组件进行数据传递的时候用BroadcastReceiver(发广播,写广播接收器)。
(数据传递)(数据传递)(数据传递)
普通广播
context.sendBroadcast(intent);
发送普通广播后,所有的广播接收器的接收动作是异步的,互相没有关系。
发送广播一般用的是隐式意图!
广播传递的效率比较高。
有序广播
context.sendOrderedBroadcast();
发送有序广播后,所有可以接收该广播的广播接收器将会按照事先配置好的优先级顺序执行。
广播的传递效率较低。
普通广播的发送与接收:
发送:
sendBroadcast();
接收
编写广播接收器:
(1)编写一个类,继承BroadcastReceiver()。
(2)重写相关抽象方法:
//接收广播后执行
onReceive()
(3)需要在清单文件中注册/或者在代码中注册
就是告诉安卓操作系统可以接受什么样的广播,就会运行你的广播。
普通广播案例1:
当MainActivity中点击按钮之后发广播,在外边写一个广播接收器类去接收,广播接收器接收到之后就会Toast打印当前时间。
MainActivity类:发送时间的广播
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
}
public void doClick(View view){
switch (view.getId()) {
case R.id.button1:
//发送 广播 隐式意图(自定义action)
Intent intent=new Intent("SHOW_TIME");
sendBroadcast(intent);
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
广播接收器类:ShowTimeReceiver负责接收显示时间的广播接收器
/**
* 广播接收器 接收SHOW_TIME广播
*/
public class ShowTimeReceiver extends BroadcastReceiver{
/**
* 在接收到相应广播时执行onReceive方法
*/
public void onReceive(Context context, Intent intent/*可以传参*/) {
//直接处理一些业务处理的方案
String now=new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss").format(new Date());
Toast.makeText(context, now, Toast.LENGTH_SHORT).show();
}
}
清单文件中注册:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- 告诉安卓系统我的这个接收显示时间的receiver广播在哪 -->
<receiver android:name="com.example.android_day07_broadcast.ShowTimeReceiver" >
<intent-filter>
<action android:name="SHOW_TIME" />
</intent-filter>
</receiver>
怎么样用广播更新MainActivity上的UI界面?
注意:如果这个广播接收器是单独拿出来写的,这个广播接收器是不能直接更改当前Activity界面的Textview!
我们可以这样操作:
这个receiver我们不单独写了,我们把这个广播接收器receiver写成MainActivity的一个内部类。这样在广播接收器中onReceiver()方法中就可以访问MainActivity的成员变量Textview。
MainActivity的执行流程:
当MainActivity启动的时候执行onCreate(),并且给textView赋值。
当MainActivity创建之后才能使用这个广播接收器,所以在这个广播接收器里面我们可以直接执行MainActivity中的textView的。
因为这是MainActivity的内部类,我们就不能用静态注册,要用动态注册了。
动态注册广播接收器:
使用代码注册广播接收器:
this.registReceiver(receiver, filter);//flater:清单文件的标签可以配置action
在必要的时候取消广播接收器的注册释放资源:
this.unRegistReceiver(receiver);
普通广播案例2:
当MainActivity中点击按钮之后发广播,还是我这个MainActivity接受广播。(接受广播的是MainActivity的一个内部类广播接收器)接受完广播之后,去更新当前Manacctivity的textView.
1、在MainActivity中编写内部类广播接收器
public class MainActivity extends Activity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
}
public void doClick(View view){
switch (view.getId()) {
case R.id.button1:
//发送 广播 隐式意图 (action)
Intent intent=new Intent("SHOW_TIME");
//发送普通广播
sendBroadcast(intent);
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
//当前MainActivity内部类,继承广播接收器
//广播接收器 接收SHOW_TIME广播
//在广播接收器onReceive()中做更新textView
class TimeReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
//修改activity的textView
String now=new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss").format(new Date());
textView.setText(now);
}
}
protected void onStart() {
super.onStart();
//注册广播接收器
receiver=new TimeReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction("SHOW_TIME");
this.registerReceiver(receiver, filter);
}
protected void onStop() {
super.onStop();
this.unregisterReceiver(receiver);
}
}
2、注册及取消注册:
(1) 代码注册onCreate()注册onDestroy()取消注册
当前Activity创建的时候注册,销毁的时候取消注册
(2) 代码注册onStart()注册onStop()取消注册
开始onStart()的时候注册,onStop的时候取消注册。
用哪一套取决于你想不想当前Activity隐藏在后台之后依然有效,想就在onCreate()中注册,onDestory()中取消注册
我们现在是为了更新UI界面,当前Activity隐藏在后台我们连UI界面都看不到了,所以我们用onStrat(),onStop()这一对。
注:IntentFiler是意图过滤器,
有序广播的使用:
区别:
在注册广播接收器的时候需要给广播接收器设置一个执行的优先级,优先级高的先接受广播。
有序广播接收器案例:
我们写三个广播接收器,A、B、C,广播接收器注册的时候设置优先级,这三个广播接收器都能同时接收同一个广播。
我们在点击按钮的时候发送一个有序广播,广播接收器就会按照我们定义的优先级顺序执行。
我们也可以在B广播接收器中终止后续广播。
有序广播的发送方式:
context.sendOrderedBroadcast();
在MainActivity中再写三个广播接收器,用于测试有序广播的接收器:
package com.example.android_day07_broadcast;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView textView;
private TimeReceiver receiver;
private AReceiver ra;
private BReceiver rb;
private BroadcastReceiver rc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
}
public void doClick(View view){
switch (view.getId()) {
case R.id.button2:
//发送有序广播
Intent i=new Intent("ORDERED_BROADCAST");
sendOrderedBroadcast(i, null);
break;
case R.id.button1:
//发送 广播 隐式意图
Intent intent=new Intent("SHOW_TIME");
sendBroadcast(intent);
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
//广播接收器 接收SHOW_TIME广播
class TimeReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
//修改activity的textView
String now=new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss").format(new Date());
textView.setText(now);
}
}
//设置三个广播接收器,接收AReceiver的时候打印AReceiver
class AReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
Log.i("info", "AReceiver..");
}
}
//设置三个广播接收器,接收BReceiver的时候打印BReceiver
class BReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
Log.i("info", "BReceiver..");
//终止广播的继续传播
abortBroadcast();
}
}
//设置三个广播接收器,接收CReceiver的时候打印CReceiver
class CReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
Log.i("info", "CReceiver..");
}
}
protected void onStart() {
super.onStart();
//注册广播接收器
receiver=new TimeReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction("SHOW_TIME");
this.registerReceiver(receiver, filter);
//注册有序广播的广播接收器
ra=new AReceiver();
IntentFilter fa=new IntentFilter("ORDERED_BROADCAST");
//定义优先级参数 数越小优先级越低,数字越大优先级越高,越先执行
fa.setPriority(100);
this.registerReceiver(ra, fa);
rb=new BReceiver();
IntentFilter fb=new IntentFilter("ORDERED_BROADCAST");
//定义优先级参数
fb.setPriority(200);
this.registerReceiver(rb, fb);
rc=new CReceiver();
IntentFilter fc=new IntentFilter("ORDERED_BROADCAST");
//定义优先级参数
fc.setPriority(300);
this.registerReceiver(rc, fc);
}
//取消注册
protected void onStop() {
super.onStop();
this.unregisterReceiver(receiver);
this.unregisterReceiver(ra);
this.unregisterReceiver(rb);
this.unregisterReceiver(rc);
}
}
有序广播中终止后续广播:
abortBroadcast();
接上面案例,在MainActivity中,BReceiver中调用abortBroadcast();终止广播继续传播传播A不打印。