1. 程式人生 > >android學習筆記之四:四大元件之BroadcastReceiver

android學習筆記之四:四大元件之BroadcastReceiver

1.定義廣播接收者

  • 定義一個類繼承BroadcastReceiver,並重寫onReceive()方法。
@Override
public class SMSBroadCastReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {

    }
}
  • 在清單檔案中配置該類(靜態註冊),指定接收的廣播種類
<receiver  android:name="com.example.broadcast.SMSBroadCastReceiver"
>
<intent-filter > <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>
  • 廣播是通過intent傳送的,intent中會攜帶一個action,系統會在所有清單檔案中尋找,看哪一個廣播接收者的intent-filter和廣播中的intent是匹配的,那麼這個廣播接收者就會收到這條廣播,它的onReceive方法就會執行。

  • BroadcastReceiver除了在清單檔案中宣告,也可以在程式碼中宣告,使用registerReceiver方法動態註冊Receiver

動態註冊時,無須在AndroidManifest中註冊receiver元件。直接在程式碼中通過呼叫Context的registerReceiver函式,可以在程式中動態註冊BroadcastReceiver。registerReceiver的定義形式如下:

SMSBroadcastReceiver receiver = new SMSBroadcastReceiver();
IntentFilter intentFilter= new IntentFilter();
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED"
); registerReceiver(receiver, intentFilter);

動態註冊的廣播接收者,還需要在onDestroy()回撥中取消註冊

unregisterReceiver(receiver)

2.傳送自定義廣播

  • 建立自定義廣播:
//建立一個傳遞訊息的意圖物件
Intent intent = new Intent();
//設定要廣播的事件型別
intent.setAction("com.example.broadcast.appointment");
//設定廣播的訊息資料
intent.putExtra("appointment", "明天天氣晴朗,是約會的好日子......");
//傳送一個廣播訊息
sendBroadcast(intent);
  • 接收自定義廣播:
public class MyBroadcastReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        String appointment = intent.getStringExtra("appointment");
        Toast.makeText(context, appointment , 1).show();
    }
}

在AndroidManifest.xml中配置廣播接收者:

<receiver android:name="com.example.broadcast.MyBroadcastReceiver">
    <intent-filter>
        <action android:name="com.example.broadcast.appointment">
    </intent-filter>
</receiver>

3.廣播的兩種型別

  • 無序廣播:所有跟廣播的intent匹配的廣播接收者都可以收到該廣播,並且是沒有先後順序(同時收到)

    • 接收者不能將處理結果傳遞給下一個接收者,並且無法終止廣播Intent的傳播。
    • Context.sendBroadcast(intent);
  • 有序廣播:所有跟廣播的intent匹配的廣播接收者都可以收到該廣播,但是會按照廣播接收者的優先順序來決定接收的先後順序,優先順序高的先收到,優先順序低的後收到。

    • 優先級別宣告在 intent-filter 元素的 android:priority 屬性中,取值範圍:-1000~1000,優先級別也可以呼叫IntentFilter物件的setPriority()進行設定 。
    • Context.sendOrderedBroadcast(intent);
    • 結果接收者:所有廣播接收者都接收到廣播之後,它才接收,並且一定會接收
    • abortBroadCast():阻止其他接收者接收這條廣播,類似攔截,只有有序廣播可以被攔截

4.使用本地廣播

  • 只在應用程式內部進行傳遞的廣播,傳送和接收都只在本應用程式有效。

  • 本地廣播是無法通過靜態註冊來實現的。因為靜態註冊是為了讓程式未啟動也能接收廣播。本地廣播是在本程式內進行
    傳遞,肯定是已經啟動了,因此也完全不需要靜態註冊。

  • 使用LocalBroadcastManager對廣播進行管理,程式碼如下。

public class MainActivity extends Activity {  
    private IntentFilter intentFilter;  
    private LocalReceiver localReceiver;  
    //本地廣播資料型別例項  
    private LocalBroadcastManager localBroadcastManager;  


    @Override  
    public void onCreate(Bundle savedInstanceState){  
        super.onCreate(savedInstanceState);  
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);  
        setContentView(R.layout.activity_main);  

        //獲取本地廣播例項  
        localBroadcastManager = LocalBroadcastManager.getInstance(this);  

        Button button = (Button)findViewById(R.id.button);  
        button.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Intent intent = new Intent("com.example.broadcast.LOCAL_BROADCAST");  
                //傳送本地廣播。  
                localBroadcastManager.sendBroadcast(intent);  
            }  
        });  
        //新建intentFilter並給其action標籤賦值。  
        intentFilter = new IntentFilter();  
        intentFilter.addAction("com.example.broadcast.LOCAL_BROADCAST");  

        //建立廣播接收器例項,並註冊。將其接收器與action標籤進行繫結。  
        localReceiver = new LocalReceiver();  
        localBroadcastManager.registerReceiver(localReceiver,intentFilter);  
    }  

    //在onDestroy()方法中取消註冊
    @Override  
    public void onDestroy(){ 
        super.onDestroy();  
        //取消註冊呼叫的是unregisterReceiver()方法,並傳入接收器例項。  
        localBroadcastManager.unregisterReceiver(localReceiver);  
    }  
    class  LocalReceiver extends BroadcastReceiver{  
        @Override  
        public void onReceive(Context context,Intent intent){  
            Toast.makeText(context,"這是本地廣播接收器",Toast.LENGTH_SHORT).show();  
        }  
    }  
}  
  • 本地廣播的優勢
    • 可以明確地知道正在傳送的廣播不會離開我們的程式, 因此不需要擔心機密資料洩漏的問題。
    • 其他的程式無法將廣播發送到我們程式的內部, 因此不需要擔心會有安全漏洞的隱患。
    • 傳送本地廣播比起傳送系統全域性廣播將會更加高效。

5.廣播的生命週期

  • 廣播接收者的生命週期是非常短暫的,在接收到廣播的時候建立,onReceive()方法結束之後銷燬

  • 廣播接收者中不要做一些耗時的工作,否則會彈出Application No Response錯誤對話方塊

  • 最好也不要在廣播接收者中建立子執行緒做耗時的工作,因為廣播接收者被銷燬後進程就成為了空程序,很容易被系統殺掉

  • 耗時的較長的工作最好放在服務中完成