说一说Android中的广播那回事

来源:互联网 发布:h5 js 跳转到原生界面 编辑:程序博客网 时间:2024/06/01 07:51

好久没有写过广播了 今天写了一个极光推送,,要用到广播才发现是这么的陌生,哎 搞了一个垃圾项目 啥都没有,,都快堕落成一个菜逼了,,写个博客做个回忆。


/**
* 广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。
* 普通广播是完全异步的,可以在同一时刻(逻辑上)被所有广播接收者接收到,消息传递的效率比较高,
*但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;
* 然而有序广播是按照接收者声明的优先级别
*(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000。
*也可以调用IntentFilter对象的setPriority()进行设置),
*被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。
* A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。
* Context.sendBroadcast()
* 发送的是普通广播,所有订阅者都有机会获得并进行处理。
* Context.sendOrderedBroadcast()
*发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,
* 前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),
* 如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。
* 对于有序广播,前面的接收者可以将处理结果存放进广播Intent,
* 然后传给下一个接收者。
*
* 静态订阅广播又叫:常驻型广播,当你的应用程序关闭了,如果有广播信息来,
* 你写的广播接收器同样的能接受到,他的注册方式就是在你的应用程序中的AndroidManifast.xml进行订阅的。
*动态订阅广播又叫:非常驻型广播,当应用程序结束了,广播自然就没有了,
* 比如你在activity中的onCreate或者onResume中订阅广播,同时你必须在onDestory或者onPause中取消广播订阅。
* 不然会报异常,这样你的广播接收器就一个非常驻型的了。
*这里面还有一个细节那就是这两种订阅方式,在发送广播的时候需要注意的是:
* 动态注册的时候使用的是隐式intent方式的,所以在发送广播的时候需要使用隐式Intent去发送,
* 不然是广播接收者是接收不到广播的,这一点要注意。但是静态订阅的时候,
* 因为在AndroidMainfest.xml中订阅的,
* 所以在发送广播的时候使用显示Intent和隐式Intent都可以(当然这个只针对于我们自己定义的广播接收者),
* 所以以防万一,我们一般都采用隐式Intent去发送广播。
* */


先看一下清单文件,Activity,BroadcastReceiver,Service,ContentproVider这四大组件只要使用则必须在清单文件中去注册
这里写图片描述

<!-- 无序广播注册START  -->        <receiver android:name=".receiver.UnSortBroadcastReceiver">            <intent-filter >                <action android:name="static"/>            </intent-filter>        </receiver> <!-- 无序广播注册END -->        <receiver android:name=".receiver.SortBroadcastReceiverA">            <intent-filter android:priority="999">                <action android:name="order"/>            </intent-filter>        </receiver>        <receiver android:name=".receiver.SortBroadcastReceiverB">            <intent-filter android:priority="1000">                <action android:name="order"/>            </intent-filter>        </receiver>

(1.)先来看一下静态注册广播的使用方法
在清单文件中注册 并注明action

public class StaticRegisterBroadcastActivity extends AppCompatActivity {    //静态订阅广播    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button btn = (Button)findViewById(R.id.btn);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //使用静态的方式注册广播,可以使用显示意图进行发送广播                Intent intent = new Intent();                // 接受条件                intent.setAction("static");                //发送内容                intent.putExtra("key","小葵花妈妈开课了,啦啦啦!大喇叭...");                // 发无序广播:                sendBroadcast(intent);            }        });    }
对应的广播接收器
/** * Created by xuenan on 2016/7/1. */// 接受并处理广播的方法.这个方法是在主线程中运行的,所以不要做耗时的操作.// 如果主线程被阻塞大约10秒钟,会产生ANR异常.不要在这个方法中弹Dialog.public class UnSortBroadcastReceiver extends BroadcastReceiver{    @Override    public void onReceive(Context context, Intent intent) {        if ("static".equals(intent.getAction())) {            String value = intent.getStringExtra("key");            Log.e("UnSortBroadcastReceiver",value);        }    }}

说到了这个Dialog就要说一下这个上下文的问题就有context和getApplicationContext()

// Context:什么是上下文?—->运行环境.
// 整个程序的运行环境:
// Context applicationContext = getApplicationContext();
// Activity:只是当前这个Activity的环境.
// 通常情况下,能够使用Activity的地方,都可以使用getApplicationContext()方法.
// 但是在创建Dialog的时候,除外:
// 会产生一个坏的令牌异常.
// Caused by: android.view.WindowManager$BadTokenException:
// Unable to add window – token null is not for an application
所以在弹出上下文的时候,只能使用当前Activity的上下文
(2)动态注册广播接收器
动态订阅广播又叫:非常驻型广播,当应用程序结束了,广播自然就没有了,

public class DynamicRegisterBroadcastActivity extends AppCompatActivity {    //使用动态的方式注册广播    private DynamicReceiver receiver;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button btn = (Button)findViewById(R.id.btn);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent();                intent.setAction("dynamic");                intent.putExtra("dynamic", "动态注册的广播接收器...");                //发送无序广播                sendBroadcast(intent);            }        });    }    @Override    protected void onResume() {        super.onResume();        receiver = new DynamicReceiver();        IntentFilter filter = new IntentFilter();        //filter.setPriority(1000);//代码设置广播的优先级,如果是发送无序广播,这行代码没有用        filter.addAction("dynamic");        // 动态注册广播接收器        registerReceiver(receiver, filter);    }    @Override    protected void onPause() {        super.onPause();        // 取消注册广播接收器        if (receiver != null) {            unregisterReceiver(receiver);        }    }}

相应的广播接收器

public class DynamicReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        if ("dynamic".equals(intent.getAction())) {            String value = intent.getStringExtra("dynamic");            Log.e("DynamicReceiver",value);        }    }}

(3.)有序广播的发送
有序广播是按照接收者声明的优先级别
*(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000。
*也可以调用IntentFilter对象的setPriority()进行设置),
*被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。
* A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。
* Context.sendOrderedBroadcast()
发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,
* 前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),
* 如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。
* 对于有序广播,前面的接收者可以将处理结果存放进广播Intent,
* 然后传给下一个接收者。

public class OrderedBroadcastActivity extends AppCompatActivity {    //有序广播    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button btn = (Button)findViewById(R.id.btn);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //使用静态的方式注册广播,可以使用显示意图进行发送广播                Intent intent = new Intent();                // 接受条件                intent.setAction("order");                //发送内容                intent.putExtra("key","这是发送的有序广播");                // 发无序广播:                //sendBroadcast(intent);                //发送有序广播                sendOrderedBroadcast(intent,null);            }        });    }}

对应两个优先级不同的广播接收器

//有序广播Apublic class SortBroadcastReceiverA extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Bundle bundle = getResultExtras(true);        String content = bundle.getString("next_receiver");        Log.e("Demo:",content+"");    }}
//有序广播A//有序广播的特点,可以看出是一个同步的动作,//接收者之间可以进行数据的交互(上一个传递数据给下一个),也可以控制广播的终止。public class SortBroadcastReceiverB extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        if ("order".equals(intent.getAction())) {            String value = intent.getStringExtra("key");            Log.e("DynamicReceiver",value);        }        //abortBroadcast();//终止此次广播的传输,,不再传递给SortBroadcastReceiverA        //也可以再传递给SortBroadcastReceiverA        Bundle bundle = new Bundle();        bundle.putString("next_receiver", "下一个广播接收者");        setResultExtras(bundle);    }}
0 0
原创粉丝点击