说一说Android中的广播那回事

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


/**
* 广播被分为两种不同的类型:“普通广播(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);
            }
        });
    }
}

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

//有序广播A
public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值