BroadcastReceiver是android的四大组件之一,其本质上可看作是一种全局的监听器,用于监听全局的系统消息。
开发步骤
1>从BroadcastReceiver派生出一个子类,并实现onReceive()方法。
2>在manifest.xml文件中配置之(配置方法与配置activity,service类似)。
3>在需要发送广播的地方调用sendBroadcast(Intent intent)或sendOrderedBroadcast(Intent intent)方法。传入一个Intent对象,此对象的配置与启动activity及service的Intent的配置方法类似。
启动方式
广播的发送有两种方式:
1>通过sendBroadcast启动。
通过这种方式可以启动异步的广播,可以在同一时刻(逻辑上)被所有的接收者接收,消息传递效率比较高。但接收者不能将处理结果传递给下一个接收者,也无法中止广播的传递。
2>通过sendOrderedBroadcast启动。
通过这种方式可以启动有序广播,可以事先为此广播的接收者设定不同的优先级。广播将按照此优先级进行传播,高优先级的接收者先接收到广播事件,然后它可以往里面放入新的数据或者中止广播的继续传播。
示例
1 public class MainActivity extends Activity { 2 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.activity_main); 7 System.err.println("onCreate:" + Thread.currentThread().getName()); 8 } 9 10 public void sendNormal(View v) { 11 Intent intent = new Intent(this, FirstReceiver.class); 12 sendBroadcast(intent); 13 } 14 15 public void sendOrdered(View v) { 16 Intent intent = new Intent("com.test.brocast"); 17 intent.putExtra("isOrdered", true); 18 sendOrderedBroadcast(intent, null); 19 } 20 21 }
1 public class FirstReceiver extends BroadcastReceiver { 2 3 @Override 4 public void onReceive(Context context, Intent intent) { 5 System.err.println("FirstReceiver:"+Thread.currentThread().getName()); 6 Toast.makeText(context, "i am 1st Receiver", Toast.LENGTH_SHORT).show(); 7 boolean isOrdered = intent.getBooleanExtra("isOrdered", false); 8 if (isOrdered) { 9 10 Bundle extras = new Bundle(); 11 extras.putString("flag", "1st receiver 存入的消息"); 12 setResultExtras(extras); 13 // abortBroadcast(); 14 } 15 } 16 17 }
1 public class SecondReceiver extends BroadcastReceiver { 2 3 @Override 4 public void onReceive(Context context, Intent intent) { 5 System.err 6 .println("SecondReceiver:" + Thread.currentThread().getName()); 7 Bundle bundle = getResultExtras(true); 8 String str = bundle.getString("flag"); 9 Toast.makeText(context, "i am 2st Receiver | " + str, 10 Toast.LENGTH_SHORT).show(); 11 12 } 13 14 }
布局文件:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context=".MainActivity" > 7 8 <Button 9 android:id="@+id/btn1" 10 android:layout_width="fill_parent" 11 android:layout_height="wrap_content" 12 android:onClick="sendNormal" 13 android:text="普通广播" /> 14 15 <Button 16 android:id="@+id/btn2" 17 android:layout_width="fill_parent" 18 android:layout_height="wrap_content" 19 android:onClick="sendOrdered" 20 android:text="有序广播" /> 21 22 </LinearLayout>
如图:
注意点:
1>因为broadcast本质上是一种全局监听器,所以其可用来实现不同组件之间的信息传递。比如:我们通过startService启动的service就可以通过广播实现与其它组件(一般是Activity)间的信息交互。
2>BroadcastReceiver属于系统级的监听器,它拥有自己的进程,只要存在与之匹配的Intent被广播出来,BroadcastReceiver就会被激发出来。
3>每次Broadcast事件发生后,系统就会创建对应的BroadcastReceiver实例,并自动回调onReceive方法,此方法执行完后BroadcastReceiver的实例就会被销毁。若onReceive
方法不能在10秒内执行完成,Android系统就会认为此程序无响应。所以不要在BroadcastReceiver的onReceive()方法里执行一些耗时的操作,否则会弹出...
4>若的确需要在onReceive中来完成一项比较耗时的操作,则可以考虑通过Intent启动一个Service来处理。不应考虑在onReceive中开一个新线程去处理耗时操作。因为BroadcastReceiver的生命周期很短,可能出现的情况是子线程还没有结束,BroadcastReceiver就已经销毁。如果BroadcastReceiver所在的进程结束,虽然该进程内还有用户启动的新线程,但由于该进程内不包含任何活动组件,因此系统可能在内存紧张时优先结束该进程。这样就可能导致BroadcastReceiver启动的子线程不能执行完成。