原創地址:http://write.blog.csdn.net/mdeditor#!postId=51420695
廣播接收器:
Android四大組件之一。
發送廣播一般用的是隱式意圖!
Broadcast是一種廣泛應用在應用程序之間傳輸信息的機制。
廣播是Android中跨進程通訊的一種機制。
組件與組件進行數據傳遞的時候用BroadcastReceiver(發廣播,寫廣播接收器)。
(數據傳遞)(數據傳遞)(數據傳遞)
普通廣播
context.sendBroadcast(intent);
發送普通廣播後,所有的廣播接收器的接收動作是異步的,互相沒有關係。
發送廣播一般用的是隱式意圖!
廣播傳遞的效率比較高。
有序廣播
context.sendOrderedBroadcast();
發送有序廣播後,所有可以接收該廣播的廣播接收器將會按照事先配置好的優先級順序執行。
廣播的傳遞效率較低。
普通廣播的發送與接收:
發送:
sendBroadcast();
接收
編寫廣播接收器:
(1)編寫一個類,繼承BroadcastReceiver()。
(2)重寫相關抽象方法:
//接收廣播後執行
onReceive()
(3)需要在清單文件中註冊/或者在代碼中註冊
就是告訴安卓操作系統可以接受什麼樣的廣播,就會運行你的廣播。
普通廣播案例1:
當MainActivity中點擊按鈕之後發廣播,在外邊寫一個廣播接收器類去接收,廣播接收器接收到之後就會Toast打印當前時間。
MainActivity類:發送時間的廣播
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
}
public void doClick(View view){
switch (view.getId()) {
case R.id.button1:
//發送 廣播 隱式意圖(自定義action)
Intent intent=new Intent("SHOW_TIME");
sendBroadcast(intent);
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
廣播接收器類:ShowTimeReceiver負責接收顯示時間的廣播接收器
/**
* 廣播接收器 接收SHOW_TIME廣播
*/
public class ShowTimeReceiver extends BroadcastReceiver{
/**
* 在接收到相應廣播時執行onReceive方法
*/
public void onReceive(Context context, Intent intent/*可以傳參*/) {
//直接處理一些業務處理的方案
String now=new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss").format(new Date());
Toast.makeText(context, now, Toast.LENGTH_SHORT).show();
}
}
清單文件中註冊:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- 告訴安卓系統我的這個接收顯示時間的receiver廣播在哪 -->
<receiver android:name="com.example.android_day07_broadcast.ShowTimeReceiver" >
<intent-filter>
<action android:name="SHOW_TIME" />
</intent-filter>
</receiver>
怎麼樣用廣播更新MainActivity上的UI界面?
注意:如果這個廣播接收器是單獨拿出來寫的,這個廣播接收器是不能直接更改當前Activity界面的Textview!
我們可以這樣操作:
這個receiver我們不單獨寫了,我們把這個廣播接收器receiver寫成MainActivity的一個內部類。這樣在廣播接收器中onReceiver()方法中就可以訪問MainActivity的成員變量Textview。
MainActivity的執行流程:
當MainActivity啓動的時候執行onCreate(),並且給textView賦值。
當MainActivity創建之後才能使用這個廣播接收器,所以在這個廣播接收器裏面我們可以直接執行MainActivity中的textView的。
因爲這是MainActivity的內部類,我們就不能用靜態註冊,要用動態註冊了。
動態註冊廣播接收器:
使用代碼註冊廣播接收器:
this.registReceiver(receiver, filter);//flater:清單文件的標籤可以配置action
在必要的時候取消廣播接收器的註冊釋放資源:
this.unRegistReceiver(receiver);
普通廣播案例2:
當MainActivity中點擊按鈕之後發廣播,還是我這個MainActivity接受廣播。(接受廣播的是MainActivity的一個內部類廣播接收器)接受完廣播之後,去更新當前Manacctivity的textView.
1、在MainActivity中編寫內部類廣播接收器
public class MainActivity extends Activity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
}
public void doClick(View view){
switch (view.getId()) {
case R.id.button1:
//發送 廣播 隱式意圖 (action)
Intent intent=new Intent("SHOW_TIME");
//發送普通廣播
sendBroadcast(intent);
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
//當前MainActivity內部類,繼承廣播接收器
//廣播接收器 接收SHOW_TIME廣播
//在廣播接收器onReceive()中做更新textView
class TimeReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
//修改activity的textView
String now=new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss").format(new Date());
textView.setText(now);
}
}
protected void onStart() {
super.onStart();
//註冊廣播接收器
receiver=new TimeReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction("SHOW_TIME");
this.registerReceiver(receiver, filter);
}
protected void onStop() {
super.onStop();
this.unregisterReceiver(receiver);
}
}
2、註冊及取消註冊:
(1) 代碼註冊onCreate()註冊onDestroy()取消註冊
當前Activity創建的時候註冊,銷燬的時候取消註冊
(2) 代碼註冊onStart()註冊onStop()取消註冊
開始onStart()的時候註冊,onStop的時候取消註冊。
用哪一套取決於你想不想當前Activity隱藏在後臺之後依然有效,想就在onCreate()中註冊,onDestory()中取消註冊
我們現在是爲了更新UI界面,當前Activity隱藏在後臺我們連UI界面都看不到了,所以我們用onStrat(),onStop()這一對。
注:IntentFiler是意圖過濾器,
有序廣播的使用:
區別:
在註冊廣播接收器的時候需要給廣播接收器設置一個執行的優先級,優先級高的先接受廣播。
有序廣播接收器案例:
我們寫三個廣播接收器,A、B、C,廣播接收器註冊的時候設置優先級,這三個廣播接收器都能同時接收同一個廣播。
我們在點擊按鈕的時候發送一個有序廣播,廣播接收器就會按照我們定義的優先級順序執行。
我們也可以在B廣播接收器中終止後續廣播。
有序廣播的發送方式:
context.sendOrderedBroadcast();
在MainActivity中再寫三個廣播接收器,用於測試有序廣播的接收器:
package com.example.android_day07_broadcast;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView textView;
private TimeReceiver receiver;
private AReceiver ra;
private BReceiver rb;
private BroadcastReceiver rc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
}
public void doClick(View view){
switch (view.getId()) {
case R.id.button2:
//發送有序廣播
Intent i=new Intent("ORDERED_BROADCAST");
sendOrderedBroadcast(i, null);
break;
case R.id.button1:
//發送 廣播 隱式意圖
Intent intent=new Intent("SHOW_TIME");
sendBroadcast(intent);
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
//廣播接收器 接收SHOW_TIME廣播
class TimeReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
//修改activity的textView
String now=new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss").format(new Date());
textView.setText(now);
}
}
//設置三個廣播接收器,接收AReceiver的時候打印AReceiver
class AReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
Log.i("info", "AReceiver..");
}
}
//設置三個廣播接收器,接收BReceiver的時候打印BReceiver
class BReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
Log.i("info", "BReceiver..");
//終止廣播的繼續傳播
abortBroadcast();
}
}
//設置三個廣播接收器,接收CReceiver的時候打印CReceiver
class CReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
Log.i("info", "CReceiver..");
}
}
protected void onStart() {
super.onStart();
//註冊廣播接收器
receiver=new TimeReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction("SHOW_TIME");
this.registerReceiver(receiver, filter);
//註冊有序廣播的廣播接收器
ra=new AReceiver();
IntentFilter fa=new IntentFilter("ORDERED_BROADCAST");
//定義優先級參數 數越小優先級越低,數字越大優先級越高,越先執行
fa.setPriority(100);
this.registerReceiver(ra, fa);
rb=new BReceiver();
IntentFilter fb=new IntentFilter("ORDERED_BROADCAST");
//定義優先級參數
fb.setPriority(200);
this.registerReceiver(rb, fb);
rc=new CReceiver();
IntentFilter fc=new IntentFilter("ORDERED_BROADCAST");
//定義優先級參數
fc.setPriority(300);
this.registerReceiver(rc, fc);
}
//取消註冊
protected void onStop() {
super.onStop();
this.unregisterReceiver(receiver);
this.unregisterReceiver(ra);
this.unregisterReceiver(rb);
this.unregisterReceiver(rc);
}
}
有序廣播中終止後續廣播:
abortBroadcast();
接上面案例,在MainActivity中,BReceiver中調用abortBroadcast();終止廣播繼續傳播傳播A不打印。