Android的广播机制

mac2022-06-30  111

 

 

一 广播机制

广播分为标准广播和有序广播,标准广播是异步执行的广播,没有先后顺序。而有序广播是一种同步执行的广播,有接收的先后顺序,所以可以被截断。

二 接收系统广播

1.动态注册(在代码中注册)

  广播接收器是一个类。继承自BroadcastReceiver类,重写了onReceiver()的方法,当有该广播传入,则执行方法里的内容。

实现方法:

在mainactivity中建立一个内部类继承自broadcastreceiver类,重写onReceiver方法,显示一个提示符。在onCreate()方法中创建了IntentFilter实例并给他添加了要检测广播的值的action, 要监听什么广播就插入相应的广播值,然后创建一个内部类networkChangeReceiver的实例。最后调用registerReceiver方法注册。 1 public class MainActivity extends AppCompatActivity { 2 3 private IntentFilter intentFilter; 4 5 private NetworkChangeReceiver networkChangeReceiver; 6 7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.activity_main); 11 // 实例化一个intentFilter 想监听什么广播就把他加到里面。 12 intentFilter = new IntentFilter(); 13 14 intentFilter.addAction("android.net.conn.CONNECTIVITY_CHAGNE"); 15 networkChangeReceiver = new NetworkChangeReceiver(); 16 // 调用registerReceiver方法注册 17 registerReceiver(networkChangeReceiver, intentFilter); 18 } 19 // 动态注册的广播接收器需要取消注册 20 @Override 21 protected void onDestroy(){ 22 super.onDestroy(); 23 unregisterReceiver(networkChangeReceiver); 24 } 25 26 class NetworkChangeReceiver extends BroadcastReceiver { 27 @Override 28 public void onReceive(Context context, Intent intent) { 29 Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show(); 30 } 31 } 32 }

 2.静态注册(在AndroidManifest.xml中注册)

与动态注册相比,静态注册没有那么灵活,但是可以在程序没有启动时候就接收到广播。

静态方法可以快捷创建一个广播接收器,在包名右键新建中,选择other,broadcast receiver。

弹出如下的窗口:

其中Exported表示是否允许接收本程序以外的广播,而Enabled属性表示是否启用这个广播。新建后在onReceiver()方法中再重写需要实现的步骤。

此外,静态广播需要在AndroidManifest,xml中注册才能使用。(已被as自动注册。)

1 <receiver 2 android:name=".BootCompleteReceiver" 3 android:enabled="true" 4 android:exported="true"> 5 <intent-filter>           //加入要要接收的广播内容 6 <action android:name="android.intent.action.BOOT_COMPLETED" /> 7 </intent-filter> 8 </receiver>

然后在AndroidManifest.xml文件中加入要监听的广播。

注意:

不要在onReceive中执行耗费时间的操作,因为他不允许开多线程。在接收系统广播的时候,有的广播需要一定的权限声明

三 自定义广播

1.发送标准广播

  新建一个广播接收器MyBroadcastReceiver。在onReceive()方法中加入一个toast的显示提示。然后在AndroidManifest.xml中加入要接收的action。要接收的action为:“com.example.broadcasttest.MY_BROADCAST”。

  所以我们要发广播的时候就需要发一条值为“com.example.broadcasttest.MY_BROADCAST”的广播。

  在布局文件中加入一个名为button的按键,在MainActivity中为button注册点击事件。具体为构建一个Intent对象,把要发送的广播传入,调用Context的sendBroadcast()方法将广播发送出去,这时所有监听该内容的广播接收器都会受到信息。这就是一条标准广播。

1 Button button = (Button) findViewById(R.id.button); 2 button.setOnClickListener(new View.OnClickListener() { 3 @Override 4 public void onClick(View view) { 5 Intent intent = new 6 Intent("com.example.boardcasttest.MY_BROADCAST"); 7 sendBroadcast(intent); 8 } 9 });

注:

在Android8以后为了管理系统和节约电量特别针对广播和服务发送intent的方式启动做出的改变,也就是说广播和服务不能随意收intent了,要对广播和服务更精确的指向。

所以在intent中需要加一句,ComponentName的第一个参数是自定义广播的包名,第二个参数是广播接收器的类。

1 intent.setComponent(new ComponentName("com.example.broadcasttest","com.example.broadcasttest.MyBroadcastReceiver"));

2.发送有序广播

广播可以跨进程,可以在不同的应用中接收到广播。所以只要有广播接收器,并在不同的项目中的Androidmanifest中添加对应的要接收的广播的值,就可以接收到不同项目的广播内容。

而有序广播与标准广播的区别只是在于在intent中 将sendbroadcast()改为sendOrderBroadcast(),而sendOrderBroadcast()中有两个参数,第一个还是intent,第二个是传入权限相关的字符串null。

而有序广播最重要的就是先后顺序,是根据注册时候设定的。通过intent中的 Android:priority=""来设置权值。如:

1 <receiver 2 android:name=".MyBroadcastReceiver" 3 android:enabled="true" 4 android:exported="true"> 5 <intent-filter android:priority="100"> 6 <action android:name="com.example.boardcasttest.MY_BROADCAST"/> 7 </intent-filter>

其次如果想要在有序广播中截断广播,需要在广播接收器中的onReceive方法中调用abortBroadcast()方法。如果调用了这个方法则说明这条广播被截断。

四 本地广播

因为前面的发送广播和接收广播都是针对全局的,每个程序都能收到其他的广播和发送给其他程序广播。这样会在传送数据时候存在一定的危险。所以使用本地广播可以很好的保护安全。主要是通过一个LocalBroadcastManager来对广播进行管理。实例代码如下:

1 public class MainActivity extends AppCompatActivity { 2 3 private IntentFilter intentFilter; 4 private LocalReceiver localReceiver; 5 private LocalBroadcastManager localBroadcastManager; 6 7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.activity_main); 11 localBroadcastManager = localBroadcastManager.getInstance(this);//获取实例 12 13 Button button = (Button) findViewById(R.id.button); 14 button.setOnClickListener(new View.OnClickListener() { 15 @Override 16 public void onClick(View view) { 17 Intent intent = new 18 Intent("com.example.boardcasttest.LOCAL_BROADCAST"); 19 intent.setComponent(new ComponentName 20 ("com.example.broadcasttest","com.example.broadcasttest.MyBroadcastReceiver")); 21 localBroadcastManager.sendBroadcast(intent);//发送本地广播 22 } 23 }); 24 intentFilter=new IntentFilter(); 25 intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST"); 26 localReceiver = new LocalReceiver(); 27 localBroadcastManager.registerReceiver(localReceiver,intentFilter); 28 } 29 30 // 动态注册的广播接收器需要取消注册 31 @Override 32 protected void onDestroy(){ 33 super.onDestroy(); 34 localBroadcastManager.unregisterReceiver(localReceiver); 35 } 36 37 class LocalReceiver extends BroadcastReceiver { 38 @Override 39 public void onReceive(Context context, Intent intent) { 40 Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show(); 41 } 42 } 43 }

其实可以看出来,本地广播其实和之前的动态注册很像,也是先做一个抽象的内部类作为接受器, 只不过先要通过LocalBroadcastManager先调用getInstance()方法得到实例。注册广播接收器时候和发送广播的时候,也是通过调用LocalBroadcastManager中的 registerReceiver()方法 和 sendBroadcast()方法。

另 本地广播都是动态注册的,没有静态注册的本地广播,因为本来静态广播就是为了在应用没有启动的时候接受广播,而本地广播是只局限于本程序的广播。

 

转载于:https://www.cnblogs.com/Mask-D/p/9347156.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)