Android Broadcast
介绍
广播嘛,就是字面意思,就如我们在学校,听到下课铃就知道要下课,老是听到下课铃就知道假装没听到一样,不同的APP能根据自身不同的需求对接受到的广播信息进行不同或相同的处理!
广播机制就厉害在Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序只会接受到自己关心的广播内容,这些广播可能是系统本身的,也可能是其他应用程序的!
标准广播
一种完全异步执行的广播,在广播发出后,所有广播接收器几乎在同一时间接收到该广播,它们之间没有优先顺序,效率高的同时意味着广播无法被截断
有序广播
这种就与标准广播完全相反,这是一种同步执行的广播,在广播发出后,在同一时刻只有一个广播接收器能接收到该广播内容,在这个广播接收器的逻辑执行完之后才会继续传递,优先级越高越先处理!而且高等级的广播可以对广播做截断处理,即不让比它等级低的广播接收器接收该广播!
动态注册
在代码中注册广播
静态注册
在AndroidManifest.xml中注册广播
系统广播
动态注册实例
代码实现
编写修改MainActivity.java文件
public class MainActivity extends AppCompatActivity {
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) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isAvailable()) {
Toast.makeText(MainActivity.this , "网络可用" , Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "网络不可用", Toast.LENGTH_SHORT).show();
}
}
}
}
我们先看一下NetworkChangeReceiver类,这个就是传说中的广播接收器,你看它重写的那个方法就是逻辑处理!首先通过getSystemService方法获得了ConnectivityManager的实例,这是一个系统服务类,专门用于管理网络连接的。然后调用它的getActiveNetworkInfo方法就可以得到NetworkInfo的实例,最后调用NetworkInfo的isAvailable方法,就可以直接判断是否有网络了并且弹出提示信息!还有一件事!这里的访问系统的网络状态是一种较敏感的操作,必须声明权限!!!如下:
编写修改AndroidManifest.xml文件
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
继续看java代码,在onCreate方法中,先获得IntentFilter的实例,然后给他添加一个长长的奇奇怪怪的值,这个是什么呢,噢,当网络状态发生变化的时候,系统就会发出这样的一条广播,也就是说,我们想要对什么广播进行监听,往里加它对应的名字就行啦!
然后创建一个NetworkChangeReceiver的实例,然后调用registerReceiver方法进行注册就行啦,参数需传入NetworkChangeReceiver的实例和IntentFilter的实例,这样NetworkChangeReceiver就会收到值为android.net.conn.CONNECTIVITY_CHANGE广播!
最后也很重要呀!我们要重写onDestroy方法,完成对已注册的广播接收器的注销呢!
成果展示
运行程序之后,我的手机状态原本是只有数据的,然后我们将数据关闭之后,如图:
当我们将数据打开之后,如图:
静态注册实例
代码实现
右键MainActivity.java所在的文件夹,然后New→Other→Broadcast Receiver,然后我这里的名字就没改,下面的两个框框都勾上,勾上就对了!然后修改MyReceiver.java文件:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context , "嘿,靓仔居然开机了呀!大家快来看!!" , Toast.LENGTH_LONG).show();
}
}
编写修改AndroidManifest.xml文件:
加个权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
在你新建的广播接收器里面加上intent-filter标签的内容就可了,监听系统开机广播也要权限的!!
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
按这个方式创建的广播接收器就不用自己在AndroidManifest.xml文件中自己注册了,studio会很乐意帮我们做这种事的,很方便,加上一点点就行,这个android.intent.action.BOOT_COMPLETED是Android开机成功后会发出的广播,然后告诉我们的接收器,这样它就会盯着它了!
自定义广播
标准广播
代码实现
先静态注册一个广播接收器,然后修改它的处理逻辑:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context , "我第一个收到这个消息啦!" , Toast.LENGTH_SHORT).show();
}
}
然后编写修改AndroidManifest.xml文件中的广播接收器的内容:
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="SEND_MESSAGE"/>
</intent-filter>
</receiver>
这里制定接受的广播action名字为:“SEND_MESSAGE”!!!
编写修改activity_main.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button"
android:text="发送广播"/>
</LinearLayout>
编写修改MainActivity.java文件:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("SEND_MESSAGE");
intent.setComponent(new ComponentName("com.example.broadcast" , "com.example.broadcast.MyReceiver"));
sendBroadcast(intent);
}
});
}
}
给按钮添加事件,当点击按钮的时候发出该action,创建Intent实例时传入一个参数即为action名字!然后调用Intent实例的方法setComponent传入一个ComponentName匿名实例,该实例有两个参数,其一是接收该广播的目标的包名,这里就是自身;其二是我们类名路径,然后调用方法sendBroadcast传入Intent实例就可以了!
成果展示
当点击按钮之后会有提示消息弹出,说明广播发出及接收正常!
有序广播
代码实现
静态创建一个广播接收器修改处理逻辑:
public class MyReceiver2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context , "呜啦啦啦啦我是第二!!!" , Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}
abortBroadcast方法用于阻断广播
然后编写修改AndroidManifest.xml文件中的广播接收器的内容:
<receiver
android:name=".MyReceiver2"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="SEND_MESSAGE"/>
</intent-filter>
</receiver>
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="50">
<action android:name="SEND_MESSAGE" />
</intent-filter>
</receiver>
先给新建的广播接收器加上action名字!然后就是priority用于规定优先级,后面的数字越大就越高!
编写MainActivity.java文件:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("SEND_MESSAGE");
//intent.setComponent(new ComponentName("com.example.broadcast" , "com.example.broadcast.MyReceiver"));
intent.setPackage(getPackageName());
//sendBroadcast(intent);
sendOrderedBroadcast(intent , null);
}
});
}
}
这里只做了很小的改变,将setComponent方法注释,用Intent实例的setPackage方法,传入参数通过getPackageName方法获得的当前的包名,这样所有的接收器都被指定了,然后将sendBroadcast方法注释,使用sendOrderedBroadcast方法,第二个参数是权限有关的,这里不做处理,因为比较复杂!
成果展示
运行程序,发现只有新建的广播接收器能接到这个广播!因为第二个的优先级较高,等他处理完逻辑后又将广播阻断了,导致广播无法继续往下传,于是就出现了这种情况!
小结
广播是Android中非常重要的组件之一,非常极大的方便了APP的很多功能的开发,而且广播机制也在不断的优化,可以多多阅读官方文档来学习最新的知识嗷!溜了溜了~~~~