Android第一行代码学习笔记三----广播

简介

Android 中的广播主要可以分为两种类型,标准广播和有序广播。

标准广播:完全异步执行,效率会比较高,无法被截断。

有序广播:同步执行,广播接收器有先后顺序,可以截断。


接收系统广播

Android 内置了很多系统级别的广播,可以通过监听这些广播来得到各种系统的状态信息

动态注册

注册广播的方式一般有两种,在代码中注册(动态)和在 AndroidManifest.xml (静态)中注册。
动态注册:新建继承自 BroadcastReceiver的一个类,并重写父类的 onReceive()方法。 当有广播到来时, onReceive()方法就会得到执行。
示例
public class MainActivity extends Activity {
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "network changes",
Toast.LENGTH_SHORT).show();
}
}
}
说明:在onCreate方法中创建了一个IntentFilter实例。广播接收器想要监听什么广播,就在这里添加相应的action 就行了,示例中添加的是值为android.net.conn.CONNECTIVITY_CHANGE 的 action。接下来创建了NetworkChangeReceiver 的实例,调用 registerReceiver()
方法进行注册,将 NetworkChangeReceiver 的实例和 IntentFilter 的实例都传了进去,这样NetworkChangeReceiver 就会收到所有值为 android.net.conn.CONNECTIVITY_CHANGE的广播,也就实现了监听网络变化的功能。动态注册的广播接收器一定都要取消注册才行,示例中是在 onDestroy()方法中通过调用 unregisterReceiver()方法来实现的。

静态注册

动态注册的广播接收器灵活,但是由于注册逻辑写在onCreate中,因此必须在程序启动之后才能接收广播。
实现开机启动示例如下,新建BootCompleteReceiver(不再使用内部类方式,因为需要在配置文件中注册)
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
}
}
AndroidManifest.xml文件

……





说明:标签内出现了一个新的标签,所有静态注册的广播接收器都是在这里进行注册的。通过 android:name来指定具体注册哪一个广播接收器, 然后在标签里加入想要接收的广播。Android系统启动完成后会发出一条值为 android.intent.action.BOOT_COMPLETED的广播,因此这里添加了相应的 action。监听系统开机广播需要声明权限,示例中标签又加入了一条 android.permission.RECEIVE_BOOT_COMPLETED 权限。
访问 http://developer.android.com/reference/android/Manifest.permission.html 可以查看 Android系统所有可声明的权限。
注意:不要在 onReceive()方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中是不允许开启线程的, 当 onReceive()方法运行了较长时间而没有结束时, 程序就会报错。

发送自定义广播

首先定义一个广播接收器来准备接收此广播
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in MyBroadcastReceiver",
Toast.LENGTH_SHORT).show();
}
}
配置文件中注册

……

……






主Activity,点击按钮发送广播
public class MainActivity extends Activity {
……
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.
MY_BROADCAST");
sendBroadcast(intent);
}
});
……
}
……
}
广播是一种可以跨进程的通信方式,因此在我们应用程序内发出的广播,其他的应用程序应该也是可以收到的。
public class MainActivity extends Activity {
……
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.
MY_BROADCAST");
sendOrderedBroadcast(intent, null);
}
});
……
}
……
}
发送有序广播只需要 sendBroadcast() 方法改成 sendOrderedBroadcast() 方法。 sendOrderedBroadcast() 方法接收两个参数,第一个参数仍然是 Intent,第二个参数是一个与权限相关的字符串,这里传入 null。
有序广播中,优先级比较高的广播接收器就可以先收到广播,并可以选择继续传递或者丢弃。配置文件优先级和选择丢弃代码如下:





public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in MyBroadcastReceive",
Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}

本地广播

本地广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播。

public class MainActivity extends Activity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
localBroadcastManager = LocalBroadcastManager.getInstance(this);
// 获取实例
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.
LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent); // 发送本地广播
}
});
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver, intentFilter);
// 注册本地广播监听器
}
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received local broadcast",
Toast.LENGTH_SHORT).show();
}
}
}
本地广播是无法通过静态注册的方式来接收的。



























你可能感兴趣的:(android)