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

Android四大组件之BroadCastReceive使用总结

2016-10-13 12:05 411 查看

from : http://www.it165.net/pro/html/201505/41147.html

总结得相当好:!!!!

BroadCast的定义:

广播是一种订阅--通知 事件,广播接收者向Android系统 register (订阅广播),广播发送者向Adnroid系统 sendBroadCast(发送广播),然后Android 系统通知所有注册该广播的接收者,广播接收者收到自己注册的广播之后实现自己想做的事情(该事情一般不超过10s,否则应用会出现ANR)。

BroadCast的分类:

1.无序广播:也就是普通广播,只要注册了该action的广播接收者都能收到该广播,且没有先后顺序。 2.有序广播:广播接收者按照优先级高低依次接受该广播,并且优先接收的广播可以通过setResultExtras(Bundle)方法,将处理好的结果传送到下一个广播接收者那里。 3.粘性广播:发送广播调用的方法 sendStickyBroadcast(Intent),和sendBroadcast(Intent)不同。 粘性广播会一直保留在内存当中,直到有广播接收者注册该广播,该广播才算结束。不好解释,等会具体看例子。

BroadCase的使用:

一.普通广播:根据注册方式不同可以分为 静态注册广播和动态注册广播。

1.静态注册广播使用实例

AndroidManifest.xml 如下:

view
sourceprint?

01.
<?xml
version=
"1.0"
encoding=
"utf-8"
?>


02.
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"


03.
package
=
"com.xjp.mybroadcast"
>


04.


05.
<application


06.
android:allowBackup=
"true"


07.
android:icon=
"@drawable/ic_launcher"


08.
android:label=
"@string/app_name"


09.
android:theme=
"@style/AppTheme"
>


10.
<activity


11.
android:name=
".MainActivity"


12.
android:label=
"@string/app_name"
>


13.
<intent-filter>


14.
<action
android:name=
"android.intent.action.MAIN"
/>


15.


16.
<category
android:name=
"android.intent.category.LAUNCHER"
/>


17.
</intent-filter>


18.
</activity>


19.


20.
<!--静态注册广播,此处需要添加广播的action-->


21.
<receiver
android:name=
".BroadCastReceive1"
>


22.
<intent-filter>


23.
<action
android:name=
"com.xjp.mybroadcast.BroadCastReceive1"
></action>


24.
</intent-filter>


25.
</receiver>


26.
</application>


27.


28.
</manifest>


2.广播接收者实现如下:

view
sourceprint?

01.
package
com.xjp.mybroadcast;


02.


03.
import
android.content.BroadcastReceiver;


04.
import
android.content.Context;


05.
import
android.content.Intent;


06.


07.
/**


08.
*
Description:静态广播接收器


09.
*
User: xjp


10.
*
Date: 2015/5/14


11.
*
Time: 14:56


12.
*/


13.


14.
public
class
BroadCastReceive1
extends
BroadcastReceiver
{


15.


16.
@Override


17.
public
void
onReceive(Context
context,Intent intent) {


18.
//TODO
接收到广播之后处理自己的事情


19.
String
action = intent.getAction();


20.
String
result = intent.getStringExtra(
"key"
);


21.
MyLog.d(
"the
BroadCast action is "
+
action +
"
the BroadCast receive result is "
+
result);


22.
}


23.
}


3.广播发送者实现如下:

view
sourceprint?

01.
package
com.xjp.mybroadcast;


02.


03.
import
android.content.Intent;


04.
import
android.os.Bundle;


05.
import
android.support.v7.app.ActionBarActivity;


06.
import
android.view.View;


07.
import
android.widget.Button;


08.


09.


10.
public
class
MainActivity
extends
ActionBarActivity
implements
View.OnClickListener
{


11.


12.
private
Button
btnSend;


13.


14.
@Override


15.
protected
void
onCreate(Bundle
savedInstanceState) {


16.
super
.onCreate(savedInstanceState);


17.
setContentView(R.layout.activity_main);


18.


19.
btnSend
= (Button) findViewById(R.id.button);


20.
btnSend.setOnClickListener(
this
);


21.


22.
}


23.


24.
@Override


25.
public
void
onClick(View
v) {


26.
switch
(v.getId())
{


27.
case
R.id.button:


28.
sendBraodCast();


29.
break
;


30.
}


31.
}


32.


33.
private
void
sendBraodCast()
{


34.


35.
/**


36.
*
申明静态广播的 action 行为


37.
*/


38.
String
action =
"com.xjp.mybroadcast.BroadCastReceive1"
;


39.
Intent
intent =
new
Intent(action);


40.
intent.putExtra(
"key"
,
"静态广播测试"
);


41.
sendBroadcast(intent);


42.
}


43.
}


打印结果如下:


4.静态注册广播特点:

1.注册广播在 AndroidManifest.xml中。 2.广播接收者需重新 继承 BroadcastReceiver 类来实现 onReceive()抽象方法。 3.应用退出无需 注销广播,因此导致:即使广播退出之后,如果有其他应用发送该action行为的广播,此应用还是能接收到该广播的,也就是还会打印上面的 结果。

二.动态广播:

示例

view
sourceprint?

001.
<pre
name=
"code"
class
=
"java"
>
package
com.xjp.mybroadcast;


002.


003.
import
android.content.BroadcastReceiver;


004.
import
android.content.Context;


005.
import
android.content.Intent;


006.
import
android.content.IntentFilter;


007.
import
android.os.Bundle;


008.
import
android.support.v4.content.LocalBroadcastManager;


009.
import
android.support.v7.app.ActionBarActivity;


010.
import
android.view.View;


011.
import
android.widget.Button;


012.


013.


014.
public
class
MainActivity
extends
ActionBarActivity
implements
View.OnClickListener
{


015.


016.
private
Button
btnSend;


017.


018.
private
BroadCastReceive2
myReceive;


019.


020.
private
IntentFilter
filter;


021.


022.
private
final
static
String
ACTION =
"com.xjp.mybroadcast.BroadCastReceive2"
;


023.


024.
@Override


025.
protected
void
onCreate(Bundle
savedInstanceState) {


026.
super
.onCreate(savedInstanceState);


027.
setContentView(R.layout.activity_main);


028.


029.
btnSend
= (Button) findViewById(R.id.button);


030.
btnSend.setOnClickListener(
this
);


031.


032.
myReceive
=
new
BroadCastReceive2();


033.
filter
=
new
IntentFilter();


034.
filter.addAction(ACTION);


035.


036.
}


037.


038.


039.
@Override


040.
protected
void
onResume()
{


041.
/**


042.
*
注册广播


043.
*/


044.


045.
LocalBroadcastManager.getInstance(
this
).registerReceiver(myReceive,
filter);
//官方建议使用


046.


047.
//
this.registerReceiver(myReceive,filter);


048.


049.
super
.onResume();


050.
}


051.


052.


053.
@Override


054.
protected
void
onPause()
{


055.
/**


056.
*
注销广播


057.
*/


058.


059.
LocalBroadcastManager.getInstance(
this
).unregisterReceiver(myReceive);
//官方建议使用


060.


061.
//
this.unregisterReceiver(myReceive);


062.


063.
super
.onPause();


064.
}


065.


066.
@Override


067.
public
void
onClick(View
v) {


068.
switch
(v.getId())
{


069.
case
R.id.button:


070.
sendBraodCast();


071.
break
;


072.
}


073.
}


074.


075.
private
void
sendBraodCast()
{


076.


077.
/**


078.
*
申明广播的 action 行为


079.
*/


080.
Intent
intent =
new
Intent(ACTION);


081.
intent.putExtra(
"key"
,
"动态广播测试"
);


082.


083.
/**


084.
*
官方提倡使用如下发送广播,原因是更快,更安全,不会导致内存泄漏


085.
*/


086.
LocalBroadcastManager.getInstance(
this
).sendBroadcast(intent);


087.


088.
//
this.sendBroadcast(intent);


089.
}


090.


091.


092.
/**


093.
*
内部类实现广播接收器


094.
*/


095.
private
class
BroadCastReceive2
extends
BroadcastReceiver
{


096.


097.
@Override


098.
public
void
onReceive(Context
context,Intent intent) {


099.
//TODO
接收到广播之后处理自己的事情


100.
String
action = intent.getAction();


101.
String
result = intent.getStringExtra(
"key"
);


102.
MyLog.d(
"the
BroadCast action is "
+
action +
"
the BroadCast receive result is "
+
result);


103.
}


104.
}


105.
}


view
sourceprint?

1.


打印结果如下:


动态广播特点:

1.在代码中调用registerReceiver()方法 注册广播。 2.广播接收者需重新 继承 BroadcastReceiver 类实现内部类。 3.动态广播在应用退出时需要 调用unregisterReceiver()方法来注销广播。如果应用退出时没有注销广播,会报如下错误:

因此,我们通常的做法是:在
onResume()中注册广播,在onPause中注销广播。 4.当广播注销之后就接收不到任何系统发送的广播了。

三.有序广播:

示例:

view
sourceprint?

001.
<pre
name=
"code"
class
=
"java"
>
package
com.xjp.mybroadcast;


002.


003.
import
android.content.BroadcastReceiver;


004.
import
android.content.Context;


005.
import
android.content.Intent;


006.
import
android.content.IntentFilter;


007.
import
android.os.Bundle;


008.
import
android.support.v7.app.ActionBarActivity;


009.
import
android.view.View;


010.
import
android.widget.Button;


011.


012.


013.
public
class
MainActivity
extends
ActionBarActivity
implements
View.OnClickListener
{


014.


015.
private
Button
btnSend;


016.


017.
private
BroadCastReceive2
myReceive;


018.


019.
private
BroadCastReceive3
myReceive3;


020.


021.
private
IntentFilter
filter;


022.


023.
private
IntentFilter
filter3;


024.


025.
private
final
static
String
ACTION =
"com.xjp.mybroadcast.BroadCastReceive2"
;


026.


027.
@Override


028.
protected
void
onCreate(Bundle
savedInstanceState) {


029.
super
.onCreate(savedInstanceState);


030.
setContentView(R.layout.activity_main);


031.


032.
btnSend
= (Button) findViewById(R.id.button);


033.
btnSend.setOnClickListener(
this
);


034.


035.
myReceive
=
new
BroadCastReceive2();


036.
filter
=
new
IntentFilter();


037.
filter.addAction(ACTION);


038.
filter.setPriority(
2
);
//设置广播的优先级,
-1000~1000 ,数字越大,优先级越高。


039.


040.
myReceive3
=
new
BroadCastReceive3();


041.
filter3
=
new
IntentFilter();


042.
filter3.addAction(ACTION);


043.
filter3.setPriority(
1
);


044.


045.


046.
}


047.


048.


049.
@Override


050.
protected
void
onResume()
{


051.
/**


052.
*
注册广播


053.
*/


054.
registerReceiver(myReceive,
filter);


055.
registerReceiver(myReceive3,
filter3);


056.


057.


058.
super
.onResume();


059.
}


060.


061.


062.
@Override


063.
protected
void
onPause()
{


064.
/**


065.
*
注销广播


066.
*/


067.


068.
unregisterReceiver(myReceive);


069.
unregisterReceiver(myReceive3);


070.


071.
super
.onPause();


072.
}


073.


074.
@Override


075.
public
void
onClick(View
v) {


076.
switch
(v.getId())
{


077.
case
R.id.button:


078.
sendBraodCast();


079.
break
;


080.
}


081.
}


082.


083.
private
void
sendBraodCast()
{


084.


085.
/**


086.
*
申明广播的 action 行为


087.
*/


088.
Intent
intent =
new
Intent(ACTION);


089.
intent.putExtra(
"key"
,
"有序广播测试"
);


090.


091.
this
.sendOrderedBroadcast(intent,
null
);


092.
}


093.


094.


095.
/**


096.
*
内部类实现广播接收器


097.
*/


098.
private
class
BroadCastReceive2
extends
BroadcastReceiver
{


099.


100.
@Override


101.
public
void
onReceive(Context
context,Intent intent) {


102.
//TODO
接收到广播之后处理自己的事情


103.
String
action = intent.getAction();


104.
String
result = intent.getStringExtra(
"key"
);


105.
MyLog.d(
"the
BroadCast action is "
+
action +
"
the BroadCast receive result is "
+
result);


106.


107.
Bundle
bundle =
new
Bundle();


108.
bundle.putString(
"key"
,
"有序广播处理之后"
+
"\n"
+
"再次发送给下一个广播接收者"
);


109.
intent.putExtra(
"bundle"
,
bundle);


110.
setResultExtras(bundle);


111.
//切断广播,不再让此广播继续往下发送。


112.
//
abortBroadcast();


113.
}


114.
}


115.


116.
/**


117.
*
内部类实现广播接收器


118.
*/


119.
private
class
BroadCastReceive3
extends
BroadcastReceiver
{


120.


121.
@Override


122.
public
void
onReceive(Context
context,Intent intent) {


123.
//TODO
接收到广播之后处理自己的事情


124.
String
action = intent.getAction();


125.
//要不要接受上一个广播接收器receiver2传来的的数据


126.
Bundle
bundle =getResultExtras(
true
);


127.
MyLog.d(
"the
BroadCast action is "
+
action +
"
the BroadCast receive result is "
+
bundle.getString(
"key"
));


128.
}


129.
}


130.
}


view
sourceprint?

1.


有序广播特点:

1.所有广播接收者的action是一致的,发送有序广播调用 sendOrderedBroadcast()方法。 2.有序广播的接收者需要调用setPriority()方法设置广播接收者的优先级。数字越大,优先接受广播。 3.有序广播如果需要终止 广播继续往下发送,可以调用 abortBroadcast()方法切断广播。 4.先接收广播者可以将自己的处理结果通过setResultExtras()方法继续传递给下一个广播接收者。 5.后接收者可以调用 getResultExtras(true)来自己决定是否接收上一个广播传递过来的数据。

四.粘性广播:

示例 需要在 AndroidManifest.xml中添加 权限

view
sourceprint?

1.
<uses-permission
android:name=
"android.permission.BROADCAST_STICKY"
></uses-permission>


发送广播的Activity

view
sourceprint?

01.
package
com.xjp.mybroadcast;


02.


03.
import
android.content.Intent;


04.
import
android.os.Bundle;


05.
import
android.support.v7.app.ActionBarActivity;


06.
import
android.view.View;


07.
import
android.widget.Button;


08.


09.


10.
/**


11.
*
发送广播的Activity


12.
*/


13.
public
class
MainActivity
extends
ActionBarActivity
implements
View.OnClickListener
{


14.


15.
private
Button
btnSend;


16.


17.


18.
private
final
static
String
ACTION =
"com.xjp.mybroadcast.BroadCastReceive1"
;


19.
private
final
static
String
ACTION1 =
"com.xjp.mybroadcast.BroadCastReceive2"
;


20.


21.
@Override


22.
protected
void
onCreate(Bundle
savedInstanceState) {


23.
super
.onCreate(savedInstanceState);


24.
setContentView(R.layout.activity_main);


25.


26.
btnSend
= (Button) findViewById(R.id.button);


27.
btnSend.setOnClickListener(
this
);


28.
}


29.


30.


31.
@Override


32.
public
void
onClick(View
v) {


33.
switch
(v.getId())
{


34.
case
R.id.button:


35.
sendBraodCast();


36.
break
;


37.
}


38.
}


39.


40.
private
void
sendBraodCast()
{


41.


42.
/**


43.
*
申明广播的 action 行为


44.
*/


45.
Intent
intent =
new
Intent(ACTION);


46.
intent.putExtra(
"key"
,
"普通广播测试"
);


47.
sendBroadcast(intent);


48.


49.
Intent
intent1 =
new
Intent(ACTION1);


50.
intent1.putExtra(
"key"
,
"粘性广播测试"
);


51.
sendStickyBroadcast(intent1);


52.
startActivity(
new
Intent(
this
,
RecevieActivity.
class
));


53.
}


54.
}


接受广播的Activity

view
sourceprint?

01.
package
com.xjp.mybroadcast;


02.


03.
import
android.app.Activity;


04.
import
android.content.BroadcastReceiver;


05.
import
android.content.Context;


06.
import
android.content.Intent;


07.
import
android.content.IntentFilter;


08.
import
android.os.Bundle;


09.


10.
/**


11.
*
Description:接受广播的Activity


12.
*
User: xjp


13.
*
Date: 2015/5/14


14.
*
Time: 17:03


15.
*/


16.


17.
public
class
RecevieActivity
extends
Activity
{


18.


19.
private
final
static
String
ACTION1 =
"com.xjp.mybroadcast.BroadCastReceive1"
;


20.
private
final
static
String
ACTION2 =
"com.xjp.mybroadcast.BroadCastReceive2"
;


21.


22.
private
Receive
receive;


23.


24.
private
IntentFilter
filter1;


25.


26.
@Override


27.
protected
void
onCreate(Bundle
savedInstanceState) {


28.
super
.onCreate(savedInstanceState);


29.


30.
receive
=
new
Receive();


31.


32.
filter1
=
new
IntentFilter();


33.
filter1.addAction(ACTION1);


34.
filter1.addAction(ACTION2);


35.


36.
}


37.


38.
@Override


39.
protected
void
onResume()
{


40.
super
.onResume();


41.
registerReceiver(receive,
filter1);


42.
}


43.


44.
@Override


45.
protected
void
onPause()
{


46.
super
.onPause();


47.
unregisterReceiver(receive);


48.
}


49.


50.
private
class
Receive
extends
BroadcastReceiver
{


51.
@Override


52.
public
void
onReceive(Context
context,Intent intent) {


53.
String
action = intent.getAction();


54.
String
result = intent.getStringExtra(
"key"
);


55.
MyLog.d(
"the
BroadCast action is "
+
action +
"
the BroadCast receive result is "
+
result);


56.
}


57.
}


58.
}


打印结果如下:


从结果来看,只有粘性广播才能接收到广播信息。

粘性广播特点:

1.需要在AndroidManifest.xml中添加权限

view
sourceprint?

1.
<uses-permission
android:name=
"android.permission.BROADCAST_STICKY"
></uses-permission>


2.粘性广播发送除了调用方法不同sendStickyBroadcast(intent1),其他都一样。

3.一般广播都是先注册广播,才能接收到广播,而粘性广播可以做到先发送广播,哪里需要接收该广播就哪里注册,可以后注册广播拿到广播的结果。这就是 普通广播和粘性广播的区别。从示例中也看出了普通广播在跳转到ReceiveActivity中是接受不到广播发送者发出的广播的,只有粘性广播才能接收到。

有人会奇怪,平时也没看到哪里使用粘性广播??其实我也是看到Android 系统中 监测电池电量部分发现的。贴上代码如下:

view
sourceprint?

01.
//
Register for the battery changed event


02.
IntentFilter
filter =
new
IntentFilter(Intent.ACTION_BATTERY_CHANGED);


03.


04.
/
Intent is sticky so using
null
as
receiver works fine


05.
//
return value contains the status


06.
Intent
batteryStatus =
this
.registerReceiver(
null
,
filter);


07.


08.
//
Are we charging / charged?


09.
int
status
= batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS,-
1
);


10.
boolean
isCharging
= status == BatteryManager.BATTERY_STATUS_CHARGING


11.
||
status == BatteryManager.BATTERY_STATUS_FULL;


12.


13.
boolean
isFull
= status == BatteryManager.BATTERY_STATUS_FULL;


14.


15.
//
How are we charging?


16.
int
chargePlug
= batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED,-
1
);


17.
boolean
usbCharge
= chargePlug == BatteryManager.BATTERY_PLUGGED_USB;


18.
boolean
acCharge
= chargePlug == BatteryManager.BATTERY_PLUGGED_AC;


广播的生命周期:

当广播接收者接收到广播调用完onReceive()方法之后,广播的生命周期就结束了。

因此广播接收器不能执行超过10s耗时任务,也不能在onReceive()方法中创建Thread 来执行耗时任务,你可以开启一个Service来执行后台耗时任务,具体可以参考Android 四大组件之Service 的生命周期和使用。

广播的大概原理:

广播是怎么发送的?又是怎么接收的?

我们知道,只有先注册了某个广播之后,广播接收者才能收到该广播。广播注册的一个行为是将自己感兴趣的IntentFilter注册到Android系统的AMS(ActivityManagerService)中,里面保存了一个IntentFilter列表。广播发送者将自己的IntentFilter 的action行为发送到AMS中,然后遍历AMS中的IntentFilter列表,看谁订阅了该广播,然后将消息遍历发送到注册了相应IntentFilter的Activity或者Service中-----也就是会调用抽象方法onReceive()方法。其中AMS起到了中间桥梁作用。

系统广播:

Android系统中有很多系统广播,比如:

EventDescription
Intent.ACTION_BOOT_COMPLETEDBoot completed. Requires the
android.permission.RECEIVE_BOOT_COMPLETEDpermission.
Intent.ACTION_POWER_CONNECTEDPower got connected to the device.
Intent.ACTION_POWER_DISCONNECTEDPower got disconnected to the device.
Intent.ACTION_BATTERY_LOWTriggered on low battery. Typically used to reduce activities in your app which consume power.
Intent.ACTION_BATTERY_OKAYBattery status good again.
系统广播具体怎么用?网络上一搜一大把,这里就不讲了。和我们写的广播使用都差不多。


延伸阅读:

1、Intent方式调用系统蓝牙组件传输文件

2、android四大组件之Intent(意图)

3、android第三方组件实现总结

4、Android四大组件之Activity

5、Android中更新View组件

6、Android组件间通信机制对面向对象特性的影响

7、seekbar组件实现android三档自定义滑动开关,禁止点击功能的实现

8、Android常用组件之RadoiButton
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: