《Android第三章》广播Broadcast Receiver
《Android第一行代码》书本记录
Broadcast Receiver类型:
- 标准广播(无序广播):是一种完全异步执行的广播,在广播发出后,所有广播接收器几乎会同时接收到这个广播消息,因此没有先后顺序可言,这种广播的效率比较高,同时意味着无法截断.
- 有序广播:是一种同步执行的广播,在广播发出后,同一个时刻只有一个广播接收器能接收到,当这个广播接收器中的逻辑执行完广播才会传递.所有此时的广播接收器是由先后顺序的,优先级高的广播接收器可以先接收,并且前的广播接收器可以截断正在传递的广播,这样后面的广播接收器就无法接收信息.
Broadcast Receiver注册方式:
- 动态注册:在代码中注册
- 例子:
动态注册监听网络变化: public class MainActivity extends AppCompatActivity { private NetWorkChangeReceiver netWorkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
//设置意图 IntentFilter intentFilter=new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//创建广播接收器 netWorkChangeReceiver = new NetWorkChangeReceiver();
//注册广播 registerReceiver(netWorkChangeReceiver,intentFilter); } public class NetWorkChangeReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(MainActivity.this, "网络发生了变化", Toast.LENGTH_SHORT).show(); } } @Override protected void onDestroy() { super.onDestroy(); //动态注册记得取消广播注册 unregisterReceiver(netWorkChangeReceiver); } }
- 静态注册:要在AndroidManifest.xml文件注册
- 例子:
静态注册实现开机启动例子: AndroidManifest.xml文件里需要注册: 增加权限: <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 注册 <receiver android:name=".MainActivity$NetWorkChangeReceiver" android:enabled="true" android:exported="true" > <intent-filter > <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver>
编写广播类:
public class BootCompleteReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "开机完成", Toast.LENGTH_SHORT).show();
}
}
- 注意:不要在onReceive()方法执行过多逻辑或者进行任何耗时操作,因为在广播接收器中是不允许开启线程的,当onRecevie()方法运行了较长时间而没有结束时,程序就会报错。
- 因此广播接收器扮演的角色大多数都是打开程序或者其他组件角色,比如创建一条状态栏通知,或者启动一个服务等.
发送自定义广播:
- 发送标准(无序)广播:
-
发送广播前先定义一个广播接收来接收广播来测试,不然白发: public class MyBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(MainActivity.this, "接收到广播", Toast.LENGTH_SHORT).show(); } } 然后AndroidManifest.xml注册广播: <receiver android:name=".MainActivity$MyBroadcastReceiver" android:enabled="true" android:exported="true" > <intent-filter > <action android:name="android.intent.broadcasttest.MY_BROADCAST"/> </intent-filter> </receiver> 然后设置一个按钮发送广播,action设置为android.intent.broadcasttest.MY_BROADCAST: public void sendBroadcast(View view){ Intent intent=new Intent("android.intent.broadcasttest.MY_BROADCAST"); sendBroadcast(intent); } 点击按钮就能接收到广播的了
- 发送有序广播:
-
发送广播前先定义一个广播接收来接收广播来测试,不然白发: public class MyBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(MainActivity.this, "接收到广播", Toast.LENGTH_SHORT).show();
//abortBroadcast()如果调用这个方法表示截断广播 } } 然后AndroidManifest.xml注册广播,注意这里多了一个属性android:priority,这里就是设置优先级,数越大优先级越高 <receiver android:name=".MainActivity$MyBroadcastReceiver" android:enabled="true" android:exported="true" > <intent-filter android:priority="100" > <action android:name="android.intent.broadcasttest.MY_BROADCAST"/> </intent-filter> </receiver> 然后设置一个按钮发送广播,action设置为android.intent.broadcasttest.MY_BROADCAST: public void sendBroadcast(View view){ Intent intent=new Intent("android.intent.broadcasttest.MY_BROADCAST"); sendOrderedBroadcast(intent,null); } 发送有序广播只需要修改一行代码即可,把sendBordcast换成sendOrderedBroadcast即可,
sendOrderedBroadcast第一个参数为intent,第二个参数为null,这是关于一个权限的参数,填NUll即可
本地广播:
- 前面我们发送和接收的广播全部属于系统全局广播,即发出的广播能被其他任何应用程序接收到,并且我们也可以接收来自于其他任何应用程序的广播。这样很容易引起安全问题,为了能够简单地解决广播的安全性问题,Android引入了一套本地广播机制,这个机制发出的广播只能够在应用程序内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播。
- 例子
-
本地广播的用法并不复杂,主要使用了LocalBroadcastManager来对广播进行管理,并提供了发送广播和注册广播接收器的方法: public class MainActivity extends AppCompatActivity { private LocalBroadcastManager localBroadcastManager; private LocalReceiver localReceiver; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); localBroadcastManager=LocalBroadcastManager.getInstance(this); IntentFilter intentFilter=new IntentFilter(); intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST"); localReceiver=new LocalReceiver(); localBroadcastManager.registerReceiver(localReceiver,intentFilter); } public void sendLocalBroadcast(View view){ //点击按钮发送广播 Intent intent=new Intent("com.example.broadcasttest.LOCAL_BROADCAST"); localBroadcastManager.sendBroadcast(intent);//发送本地广播 } 销毁时取消注册广播: @Override protected void onDestroy() { super.onDestroy(); localBroadcastManager.unregisterReceiver(localReceiver); } 广播接收器: class LocalReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(MainActivity.this,"本地广播",Toast.LENGTH_SHORT).show(); } } }
两者及其接收广播的区别:
(1)动态注册广播不是常驻型广播,也就是说广播跟随Activity的生命周期。注意在Activity结束前,移除广播接收器。
静态注册是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
(2)当广播为有序广播时:优先级高的先接收(不分静态和动态)。同优先级的广播接收器,动态优先于静态
(3)同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后注册的。
(4)当广播为默认广播时:无视优先级,动态广播接收器优先于静态广播接收器。同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后册的

浙公网安备 33010602011771号