您的位置:首页 > 移动开发 > Android开发

说一说Android中的广播那回事

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

/**

* 广播被分为两种不同的类型:“普通广播(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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 博客