Android四大组件之BroadcastReceiver
什么是BroadcastReceiver?
BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。
在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度,等等。
为什么要用BroadcastReceiver?
Android中的广播机制设计的非常出色,很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。而作为应用开发者,就需要数练掌握Android系统提供的一个开发利器,那就是BroadcastReceiver。
BroadcastReceiver的生命周期:
广播接收器只有一个回调方法:
void onReceive(Context curContext, Intent broadcastMsg)
当广播消息抵达接收器时,Android调用它的onReceive() 方法并将包含消息的Intent对象传递给它。广播接收器仅在它执行这个方法时处于活跃状态。当onReceive()返回后,它即为失活状态。
拥有一个活跃状态的广播接收器的进程被保护起来而不会被杀死。但仅拥有失活状态组件的进程则会在其它进程需要它所占有的内存的时候随时被杀掉。
这种方式引出了一个问题:如果响应一个广播信息需要很长的一段时间,我们一般会将其纳入一个衍生的线程中去完成,而不是在主线程内完成它,从而保证用户交互过程的流畅。如果onReceive()衍生了一个线程并且返回,则包涵新线程在内的整个进程都被会判为失活状态(除非进程内的其它应用程序组件仍处于活跃状态),于是它就有可能被杀掉。这个问题的解决方法是令onReceive()启动一个新服务,并用其完成任务,于是系统就会知道进程中仍然在处理着工作。
发送和接收BroadcastReceiver:
发送广播的方式有两种,一种是同步广播,另一种是异步广播。前者接收器是顺序执行,每执行一个Receiver,待该Receiver返回后再执行下一个,执行的顺序是按照Receiver的优先级,通过清单文件中的Android:priority可以配置Receiver的优先级。异步广播使用sendBroadcast()发送消息,此时接收器会同步执行,彼此独立,系统内部的消息广播采用的就是此种方式。
sendBroadcast():这种方式不严格保证执行顺序。
sendOrderBroadcast():这种方式保证执行顺序,根据优先级的高低排序。
例如:
Intent intent = new Intent("MessageReceiver"); String str=et.getEditableText().toString(); intent.putExtra("msg", str); sendBroadcast(intent);
接收广播需继承BroadcastReceiver,并覆盖其onReceiver方法。例如:
public class MessageReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = intent.getStringExtra("msg"); Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); } }
注册BroadcastReceiver:
注册BroadcastReceiver有两种方式:
静态注册:
在AndroidManifest.xml中用标签生命注册,并在标签内用标签设置过滤器。
<receiver android:name="myRecevice"> //继承BroadcastReceiver,重写onReceiver方法 <intent-filter> <action android:name="com.dragon.net"></action> //使用过滤器,接收指定action广播 </intent-filter> </receiver>
动态注册:
IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(String); //为BroadcastReceiver指定action,使之用于接收同action的广播 registerReceiver(BroadcastReceiver,intentFilter);
一般:在onResume中注册,onPause()中取消unregisterReceiver
注销BroadcastReceiver:
// 代码中注销广播
unregisterReceiver(mBatteryInfoReceiver);
在 Activity 中代码注销广播建议在: onPuase() 中注销;
不要这这里面注销 Activity.onSaveInstanceState(), 因为这个方法是保存 Intent 状态的。
小实例:
main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/et" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" > <requestFocus /> </EditText> <Button android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发送广播" /> </LinearLayout>
MainActivity.java:
public class MainActivity extends Activity { private EditText et; // 初始化操作 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); System.out.println("onCreate"); et = (EditText) findViewById(R.id.et); Button btn1 = (Button) findViewById(R.id.btn1); btn1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("MessageReceiver"); String str = et.getEditableText().toString(); intent.putExtra("msg", str); sendBroadcast(intent); } }); } }
广播接收者:
public class MessageReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = intent.getStringExtra("msg"); Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); } }
清单文件注册:
<receiver android:name="com.topcsa.test_android.MessageReceiver" > <intent-filter> <action android:name="MessageReceiver" /> </intent-filter> </receiver>
Demo下载:http://download.csdn.net/detail/af74776/7809453(因为我经常用一个工程做很多测试性的小例子,因此代码中会有不需要的代码,请见谅。)
推荐文章:http://yangguangfu.iteye.com/blog/1063732
http://www.cnblogs.com/sardine/archive/2010/11/19/1881766.html
http://www.cnblogs.com/cowboybusy/archive/2012/07/09/2718902.html
文章出处:http://www.cnblogs.com/scetopcsa/
欢迎关注微信公众号:yilu_yiyou(一路一游),一个不仅仅是代码的世界!
如果文中有什么错误,欢迎指出。以免更多的人被误导。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。