Android 本地广播与全局广播

1. 全局广播和本地广播的区别

  • 全局广播:发出去的广播可以被任何应用程序接收到

  • 本地广播:发出去的广播只能被本应用程序接收到,一般使用LocalBroadcastManager对广播进行管理。


2.注册广播

注册广播的方式一般有两种:

  • 在代码注册(动态注册)
  • 在AndroidManifest.xml中注册(静态注册)

动态注册广播监听

新建一个类,让它继承自BroadcastReceiver并重写父类的onReceive()方法就行了。当广播到来时,onReceive()方法会得到执行,开发者就可以在这个方法中进行处理相应的逻辑。

//动态注册广播
 IntentFilter myIntentFilter = new IntentFilter();
 myIntentFilter.addAction(Constant.ACTION_NAME);
 registerReceiver(new MyReceiver(), myIntentFilter);
public class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //相应逻辑处理
        }
    }

静态注册广播监听

动态注册广播缺点:动态注册的广播接收器可以自由的控制注册于注销,在灵活性方面有很大的优势,但是它也存在一个缺点,即必须要在程序启动之后才能接收广播。

静态注册就可以很好的弥补这个缺点,想要使用静态注册必须满足两点:

  • 静态注册同样是要新建一个类继承BroadcastReceiver并重写onReceive()方法
  • 还需要在AndroidManifest.xml中将这个广播接收器的类名注册进去
public class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            //相应逻辑处理
        }
    }
AndroidManifest.xml

<receiver android:name=".MyReceiver"/>

2.广播接收器

Android中广播接收器主要可分两种类型:

  • 标准广播

    标准广播是一种完全异步执行的广播,在广播发出去之后,所有的广播接收
    器几乎都会在同一时刻接收到这条消息,因此它们之间无任何先后顺序可言。这种广播的效率会比较高,但同时也意味着它是无法被截断的。

  • 有序广播

    有序广播则是一种同步执行的广播,在广播发出去之后,同一时刻只会有一个广播接收器能够收到这条消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先接收到广播消息,并且前面的广播接收器还可以截断正在传递的关公,这样的广播接收器就无法接收到消息了。


发送标准广播

1.先定义一个广播接收器来准备接受此广播

public static class MyBroadcast extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
         Toast.makeText(context, "接收到了自定义广播", Toast.LENGTH_SHORT).show();
    }
}
2.在AndroidManifest.xml中注册这个广播接收器

<receiver android:name=".MyBroadcast">
     <intent-filter>
          <action android:name="com.example.mybroadcast" />
     intent-filter>
receiver>
3.发送一个广播

button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
         Intent intent = new Intent("com.example.mybroadcast");
         sendBroadcast(intent);
      }
});

发送有序广播

为了直观的研究有序广播,我又新建了一个项目。这个项目的内容和之前的一样
(广播接收器名为 MyBroadcast_B)

发送有序广播只需要改动一行代码,即将sendBroadcast()方法改成sendOrderedBroadcast()方法。sendOrderedBroadcast()方法接收两个参数,第一个仍是Intent,第二个参数是与权限相关的字符串,这里传入null就行了

button.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
        Intent intent = new Intent("com.example.mybroadcast");
        sendOrderedBroadcast(intent, null);
     }
});

通过android:priority属性给广播接收器设置优先级,从而设定广播接收器的先后顺序,优先级比较高的接收器就可以先收到广播。

<receiver android:name=".MyBroadcast_B">
    <intent-filter android:priority="100">
       <action android:name="com.example.mybroadcast" />
    intent-filter>
receiver>

既然已经获得了优先权,那么我就可以让MyBroadcastReceive选择是否允许广播继续传递了,可以在onReceive()方法中添加abortBroadcast()方法,用来截断广播。

public static class MyBroadcast_B extends BroadcastReceiver {

   @Override
   public void onReceive(Context context, Intent intent) {
      Toast.makeText(context, "接收到了自定义广播", Toast.LENGTH_SHORT).show();

      /*当MyBroadcast_B 接收到消息后 并截断。
       *此时MyBroadcast将不会再接收到广播 
       */
      abortBroadcast();
   }
}

全局广播安全性

为了提高全局广播的安全性,一般会增加权限等控制

<permission android:name="com.example.mybroadcast"/>

<receiver  android:name=".MyBroadcast_B"
           android:exported="true"
           android:permission="com.example.mybroadcast">
     <intent-filter>
        <action android:name="com.example.mybroadcast" />
     intent-filter>
receiver>

3.本地广播

之前所讲的发送和接收广播都是属于系统全局广播,也就是说发出的广播可以被其他任何应用程序接收到,这样大大降低了安全性。因此Android中引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只接收来自本地应该程序发出的广播,大大的解决了广播的安全性问题。用法并不复杂,主要就是使用了一个LocalBroadcastManager来对广播进行管理,并提供了发送广播和注册广播接收器的方法

public class LocalBroadcastMngActivity extends AppCompatActivity {

    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_local_broadcast_mng);

        localBroadcastManager = localBroadcastManager.getInstance(this);//获取实例

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.example.mybroadcast");
                localBroadcastManager.sendBroadcast(intent);//发送本地广播
            }
        });
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.mybroadcast");
        localReceiver = new LocalReceiver();
        //注册本地广播监听器
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(localReceiver);//取消注册
    }
}
class LocalReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
    Toast.makeText(LocalBroadcastMngActivity.this, "接收到本地广播", Toast.LENGTH_SHORT).show();
 }
}

地广播的用法和之前动态注册广播的用法大致相同,只不过现在首先是通过LocalBroadcastManagergetInstance()方法得到了它的一个实例;然后再注册广播接收器的时候调用的是LocalBraodcastManagersendBroadcast()方法,仅此而已。
另外一点还需要说明,本地广播是无法通过静态注册的方式来接收的。

本地广播的优点

  1. 可以明确的知道正在发送的广播不会离开我们的程序,因此不需要担心机密数据泄露问题

  2. 其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全漏洞的隐患。

  3. 发送本地广播比起发送系统全局广播将会更加高效。

你可能感兴趣的:(Android)