android组件广播的基础知识

上一篇博客大概记录了activity的基础知识,这篇博客记录下广播(Broadcast)的基础知识

广播
Broadcast是一种在应用程序间传递信息的机制,既可以在不同程序间传递信息,也可在同一程序内部传递信息。
广播接收器(Broadcast Receiver)是用来接收广播的。
android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样程序就可以只关注自己关心的内容。

广播的类型
广播主要分为四种类型:标准广播,有序广播,本地广播和粘性广播
(1)标准广播:是一种完全异步执行的广播,在广播发出后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息。标准广播的效率比较高,但也意味着无法被截断。
(2)有序广播:是一种同步执行的广播,广播发出后同一时刻只有一个广播接收器可以接收到这条广播消息,只有这个接收器中的逻辑处理完毕后才能继续向前传递。优先级高的接收器先接收到广播且前面得广播接收器可以截断正在传递的广播。
(3)本地广播:本地广播发出的广播只能在应用程序内部进行传递,并且广播接收器也只能接收来自本应用程序发送的广播。有效的解决了广播的安全问题。主要使用LocalBroadcastManager来对广播进行管理
(4)粘性广播:粘性广播会一直滞留,当有匹配该广播的接收器被注册后,接收器就会收到这条广播。

广播的使用
标准广播
(1)接收系统广播
想要使用广播,就需要先创建一个广播接收器。创建方法:新建一个类,继承自BroadcastReceiver,并重写onReceive()方法。
当有广播到来时,onReceiver()方法就会执行,具体的逻辑就会在其中处理。但是不能在onReciver()方法中加入过多的逻辑或任何耗时的操作,因为在广播接收器中不允许开启线程,当onReciver()运行过长时间后程序就会报错。
广播接收器还需要对自己感兴趣的广播进行注册,这样广播接收器才能收到该广播。注册的方式有两种:动态注册(在代码中注册)和静态注册(在AndroidManifest.xml中注册)。
静态注册与动态注册的区别是:动态注册只能在程序启动后才能接收到广播;静态注册在程序未启动的情况下就可以接收到广播。
举个例子:假设我们要监听系统中的网络变化
首先:创建一个NetworkChangeReceiver类继承自BroadcastReceiver,重写onReceive()方法,onReceive()中写入自己想要实现的逻辑。
然后:进行动态注册或者静态注册
动态注册:
1.重写onCreate()方法,在其中添加registerReceiver()方法
2.重写onDestroy()方法,在其中添加unregisterReceiver()方法
静态注册:
在AndroidManifest.xml中添加带代码

<receiver
	android:name = "." //填入自己的类名
	<intent-filter>
		<action android:name = " "/> //填入想要发送的广播
	</intent-filter>
</receiver>

具体代码实现:

	//1.创建一个NetworkChangeReceiver类继承自BroadcastReceiver,重写onReceive()方法
    class NetworkChangeReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context , Intent intent){
            Toast.makeText(context , "网络改变", Toast.LENGTH_SHORT).show();
        }
    }
//动态注册
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();
        //2.添加registerReceiver()方法
        registerReceiver(networkChangeReceiver , intentFilter);
    }

	//3.重写onDestroy()方法
    @Override
    protected void onDestroy(){
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
    }
}

(2)发送自定义广播
发送自定义广播之前,我们要先定义一个广播接收器接收次广播。然后构建一个Intent对象,把要发送的广播值传入,然后调用Context的sendBroadcast()方法将广播发送出去即可。

//定义一个广播接收器
public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        Toast.makeText(context , "这是一条自定义广播" , Toast.LENGTH_SHORT).show();
    }
}
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.example.New2.MY_BROADCAST");
                sendBroadcast(intent);
            }
        });
    }
//在AndroidManifest.xml中注册
  <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.New2.MY_BROADCAST"/>
            </intent-filter>
  </receiver>

有序广播
有序广播的广播接收器是有先后顺序的,而且前面得广播接收器可以将广播阶段,阻止继续传播。这些都是在注册的时候设定的。
只需要把sendBroadcast()改成sendOrderedBroadcast()即可。sendOrderedBroadcast()接收两个参数,第一个为Intent,第二个参数是与权限相关的字符串,这里传入null即可。
例:

Intent intent = new Intent("com.example.New2.MY_BROADCAST");
sendOrderedBroadcast(intent,null); //发送有序广播
<intent-filter android:priority="100"> //添加权限
      <action android:name="com.example.New2.MY_BROADCAST"/>
</intent-filter>

如果想截断广播,不然广播继续传播下去,只要在前面广播接收器的onReceive()方法中调用abortBroadcast()方法即可。

 public void onReceive(Context context, Intent intent) {
        Toast.makeText(context , "这是一条自定义广播" , Toast.LENGTH_SHORT).show();
        abortBroadcast();//截断广播,后面的广播接收器将收不到广播
    }

本地广播
未解决广播的安全性问题,我们可以使用本地广播。
本地广播主要使用LocalBroadcastManager来对广播进行管理,并提供发送广播和注册广播接收器的方法。
首先,通过LoaclBroadcastManger的getInstance()方法得到一个实例;
然后,在注册广播接收器时调用LocalBroadManger的registerReceiver()方法,在发送广播时调用LocalBroadManger的sendBroadcast()方法
例:

//自定义一个本地广播接收器
public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        Toast.makeText(context , "这是一条本地广播" , Toast.LENGTH_SHORT).show();
    }
}
 	private Button button;
    private IntentFilter intentFilter;
    private LocalBroadcastManager localBroadcastManager;
    private MyReceiver myReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager = LocalBroadcastManager.getInstance(this); // 获取实例

        button = findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.example.New2.MY_BROADCAST");
                localBroadcastManager.sendBroadcast(intent); //发送本地广播
            }
        });
        //进行动态注册,本地无法通过静态注册进行
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.New2.MY_BROADCAST");
        myReceiver = new MyReceiver();
        localBroadcastManager.registerReceiver(myReceiver , intentFilter);
    }

本地广播无法通过静态注册的方式进行,因为:静态注册主要是为了让程序在未启动的情况下也能收到广播,而发送本地广播的时候我们的程序一定已经启动了。
本地广播的优势:
(1)明确发送的广播不会离开我们的程序,保证了数据安全
(2)其他广播无法发送到我们程序内部,不需要担心安全漏洞问题
(3)发送本地广播比全局广播更有效

你可能感兴趣的:(android)