一 : 广播类型
1.标准广播:是一种完全异步执行的广播,在广播发出中后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,没有先后循序,这种广播的效率比较高,但同时意味着它是无法被截断的。
2.有序广播:是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够接收到这条广播消息,但这个广播接收器中的逻辑执行完毕后,广播才会继续传递。他有先后顺序,优先级高的接收器先接受到广播,并且前面的广播接收器还可以截断正在传递的广播,这样后面的接收器就无法接收到广播消息了。
二 :使用方式
1.动态注册:(监听网络变化)
优点:可以自由控制注册和注销,但必须在程序启动之后才能接受到广播
第一步:新建一个类继承BroadcastReceiver重写onReceive在这个onReceive里接受到广播消息。
第二步 :创建一个activityclass NetworkChangeReceiver extends BroadcastReceiver{ /** * 不要在onReceive中添加过多的逻辑或好似操作, * 因为广播接收器中是不允许开线程的。它一般用于创建 * 一条状态通知栏,活着启动一个服务。 * @param context * @param intent */ @Override public void onReceive(Context context, Intent intent) { // 获取网络是否可用 ConnectivityManager systemService = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = systemService.getActiveNetworkInfo(); if (null != activeNetworkInfo &&activeNetworkInfo.isAvailable()){ Toast.makeText(context,"network is available",Toast.LENGTH_SHORT).show(); }else { Toast.makeText(context,"network is unavailable",Toast.LENGTH_SHORT).show(); } } }
public class BroadcastActivity extends AppCompatActivity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_broadcast); // 获取一个过滤器的实例 intentFilter = new IntentFilter(); // 添加广播信息过滤。当网络变化时,系统会发出一条android.net.conn.CONNECTIVITY_CHANGE的广播 intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); // 创建广播实例 networkChangeReceiver = new NetworkChangeReceiver(); // 注册广播 registerReceiver(networkChangeReceiver,intentFilter); } @Override protected void onDestroy() { super.onDestroy(); // 动态注册的广播一定要取消注册才行 unregisterReceiver(networkChangeReceiver); }}第三步:清单文件配置网络权限
<!-- 监听网络权限 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2.静态注册:(开启自启)
第一步:不用启动程序就可以接受广播
通过右键new->other->Broadcast Receiver创建一个receiver。这样的好处是,重写了onReceiver方法。并且在清单文件中,自动注册了这个receiver。我们只需要添加过滤的intentfilter就可以了
同时它也需要在清单文件中添加权限<receiver android:name=".day02.broadcast.MyReceiver" android:enabled="true" android:exported="true"> <!--添加这个广播的过滤--> <intent-filter> <!-- android系统启动完成后会发送一条这样的广播 --> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
<!-- 监听开机广播权限 --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
3.发送自定义的广播
发送标准广播
第一步:通过右键new->other->Broadcast Receiver创建一个MyBroadCastReciver。在onReceiver写上接受到广播的提示,比如说一个吐司。
在清单文件里面添加上将要发送的广播过滤
<receiver android:name=".day03.broadcast.MyBroadCastReciver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.lvyequeen.test.day03.broadcast.MY_BTOADCAST" /> </intent-filter>
第二步;创建一个activity,activty里添加一个按钮用来发送这个通知
public class MyBroadcastActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_broadcast); initView(); } private void initView() { findViewById(R.id.bdSend).setOnClickListener(this); } @Override public void onClick(View v) { Intent intent = new Intent("com.lvyequeen.test.day03.broadcast.MY_BTOADCAST"); // 发送标准广播 sendBroadcast(intent); 发送有序广播 // sendOrderedBroadcast(intent ,null); } }
发送有序广播
1.如上,发送广播的时候将senBroadcast改成sendOrderedBroadcast.
2.在清单文件中注册的receiver中添加一个优先级 android:priority
例如:
<receiver android:name=".MyOtherReceiver" android:enabled="true" android:exported="true"> <!--添加一个优先级--> <intent-filter android:priority="100"> <action android:name="com.lvyequeen.test.day03.broadcast.MY_BTOADCAST"/> </intent-filter> </receiver>3.如果想要截断广播,则在onrecevier方法中添加abortBroadcast()方法
public class MyOtherReceiver extends BroadcastReceiver { public MyOtherReceiver() { } @Override public void onReceive(Context context, Intent intent) { // TODO: This method is called when the BroadcastReceiver is receiving // an Intent broadcast. // throw new UnsupportedOperationException("Not yet implemented"); Toast.makeText(context,"这是测试广播的另一个app应用",Toast.LENGTH_LONG).show(); // 接受到广播后阻断他的传输 abortBroadcast(); } }
四:使用本地广播
之前的广播属于系统全局广播,可以被任何其他程序接收,也可以接受来自其它任何程序的广播,很不安全。(广播数据被截获,接受到很多垃圾信息)
本地广播只有在应用程序内部使用(因此它不能用过静态注册的方式来接收)
使用方法
通过一个LocalBroadcastManager manager;
来管理receiver的注册和注销和发送
public class LocalBroadcastActivity extends AppCompatActivity implements View.OnClickListener { private LocalBroadcastManager manager; private IntentFilter intentFilter; private LocalReceiver receiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_local_broadcast); initView(); } private void initView() { findViewById(R.id.localBd).setOnClickListener(this); manager = LocalBroadcastManager.getInstance(getApplicationContext()); intentFilter = new IntentFilter(); intentFilter.addAction("com.lvyequeen.test.day03.broadcast.MY_BTOADCAST"); receiver = new LocalReceiver(); // 注册这个广播接受者 manager.registerReceiver(receiver, intentFilter); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.localBd: Intent intent = new Intent("com.lvyequeen.test.day03.broadcast.MY_BTOADCAST"); // 发送广播 manager.sendBroadcast(intent);//发送本地广播 break; } } @Override protected void onDestroy() { super.onDestroy(); // 注销这个广播接受着 manager.unregisterReceiver(receiver); } public class LocalReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "收到了本地广播啦", Toast.LENGTH_SHORT).show(); } } }
五:最强实践,实现强制下线功能
功能需求:不论在哪一个界面,只要异地登录了,则在界面弹出提示
实现思路:
先写一个广播接收者类(静态注册的广播接收者不能弹出对话框)所以写一个动态的receiver,然后在重写的onrecevier中加一个弹出框提示
不能每个activity都去注册,所以创建一个BaseActivity。在onResume中注册这个广播接收者。在onPause中注销这个广播接收者。这样做的原因是:只有位于栈顶的活动的activity才能接受到这个广播,非栈顶的活动,不应该也没必要接受这条广播。