Android 广播机制详解

一、广播的简介

首先,当我们一听到广播这个词时。就可以想到小学是教室的广播。不错Android中的广播机制与我们生活中的广播是有异曲同工之妙的。Android中的发送广播也就像广播室播广播,可以让很多注册过广播的地方收到这条广播。接下来我们对其进行分析。

二、广播的发送

广播的发送主要是分为2种,分别是普通广播(Normal broadcasts)和有序广播(Ordered broadcasts)。他们之间的不同点如下所示 :

普通广播(Normal broadcasts)
普通广播采用的是Context.sendBroadcast()发送的。
普通广播是完全异步的,他可以在同一时刻(逻辑上)被所有注册了的接收者接收到,消息传递的效率比较高,就像教室的广播一样,当发送广播时所有开了广播的教室等会同时收到。但这种方式的缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;

有序广播(Ordered broadcasts)
有序广播是采用Context.sendOrderedBroadcast()发送的
然而有序广播是按照接收者声明的优先级别(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000。也可以调用IntentFilter对象的setPriority()进行设置),被接收者依次接收广播。就相当于公司领导发通知肯定是不会直接到员工手上的,需要先到部门老大那然后部门老大再告诉你,部门老大可以选择不告诉你或者增加一些信息然后通知你。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。中间优先级高的也可以将广播拦截,这样优先级低的就无法收到了。

Demo分析
首先我们先来看一下普通广播的发送

public class MainActivity extends AppCompatActivity {
    Button button;
    public static final String ACTION_INTENT_TEST = "com.terry.broadcast.test";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(ACTION_INTENT_TEST);
                sendBroadcast(intent);
            }
        });
    }
}

上面是一个按钮点击事件然后发送,接下来我们制作一个接收广播的类

public class MyReceiver extends BroadcastReceiver {
    private static final String TAG = "MyReceiver";
    public MyReceiver(){
        Log.d(TAG, "MyReceiver: ");
    }
    @Override
    public void  onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive: ");
    }
}
 <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.terry.broadcast.test"></action>
            </intent-filter>
        </receiver>

我们这里是先制作了一个类来接收,然后再AndroidManifest中注册这个广播设置 也就是我们发送是intent携带的。他会去匹配有这个intent-filter的广播。我们看Log信息
在这里插入图片描述
就这样这个普通广播就接收到了,我们就可以再onReceive中做我们想做的操作。我们可以这个来进行全局的操作。

那么问题来了,Android 如何判断并筛选广播?

前面说过 Android 的广播有各式各样,那么Android 系统是如何帮我们处理我们需要哪种广播并为我们提供相应的广播服务呢?这里有一点需要大家注意,每实现一个广播接收类必须在我们应用程序中的 manifest 中显式的注明哪一个类需要广播,并为其设置过滤器,如下图:
在这里插入图片描述
我们正是在<intent-filter> <action android:name="com.terry.broadcast.test"></action> </intent-filter>中设置筛选的。然后发送时携带它

Demo分析二有序广播
我们上面不变,然后同样的创建再创建一个广播。唯一的差别就是AndroidManifest的设置不同。然后我们采用Context.sendOrderedBroadcast()的发送方式

<receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="100">
                <action android:name="com.terry.broadcast.test" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".MyReceiver2"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="200">
                <action android:name="com.terry.broadcast.test" />
            </intent-filter>
        </receiver>

很明显可以看到广播二的priority="200"是200而第一个是100,所以这个的优先级比100的高它会先接收。我们看Log

确实广播二比广播一先接收到
那么我们要怎么截断数据呢那便是在优先级高的广播onReceived中添加代码
**abortBroadcast();**就OK了我们来看Log
在这里插入图片描述
确实拦截了。

小结:
在Android 中如果要发送一个广播必须使用sendBroadCast 向系统发送对其感兴趣的广播接收器中。
使用广播必须要有一个intent 对象必设置其action动作对象
使用广播必须在配置文件中显式的指明该广播对象
每次接收广播都会重新生成一个接收广播的对象
在BroadCast 中尽量不要处理太多逻辑问题,建议复杂的逻辑交给Activity 或者 Service 去处理
如果在AndroidManifest.xml中注册,当应用程序关闭的时候,也会接收到广播。在应用程序中注册就不产生这种情况了。

下面自己来看一下如何在应用程序中注册BroadcastReceiver

利用代码注册 BroadcastReceiver 时有以下步骤:

1)生成一个 BroadcastReceiver 对象;

2)生成一个 IntentFilter 对象;

3)为 IntentFilter 对象添加一个 Action ;

4)利用 IntentFilter 和 BroadcastReceiver 绑定注册一个 BroadcastReceiver 到系统中,当系统广播发出Action事件的时候,就会匹配到该BroadcastReceiver。然后执行 onReceive方法,我们可以在里面写我们需要做的事,如网络变动、开机启动之类的。

Android广播机制源码下载,里面有更详细的内容

猜你喜欢

转载自blog.csdn.net/q376794191/article/details/85292952