編輯:Android開發實例
前言
Android四大組件,Activity、Service、ContentProvider、BroadcastReceiver,除了BroadcastReceiver之外,其他的在之前的文章中都有講解到。那麼,這篇文章主要講講BroadcastReceiver的內容。
本文主要涉及以下幾個內容:
什麼是BroadcastReceiver?
BroadcastReceiver,廣播接收者,它是一個系統全局的監聽器,用於監聽系統全局的Broadcast消息,所以它可以很方便的進行系統組件之間的通信。
BroadcastReceiver雖然是一個監聽器,但是它和之前用到的OnXxxListener不同,那些只是程序級別的監聽器,運行在指定程序的所在進程中,當程序退出的時候,OnXxxListener監聽器也就隨之關閉了,但是BroadcastReceiver屬於系統級的監聽器,它擁有自己的進程,只要存在與之匹配的Broadcast被以Intent的形式發送出來,BroadcastReceiver就會被激活。
雖然同屬Android的四大組件,BroadcastReceiver也有自己獨立的聲明周期,但是和Activity、Service又不同。當在系統注冊一個BroadcastReceiver之後,每次系統以一個Intent的形式發布Broadcast的時候,系統都會創建與之對應的BroadcastReceiver廣播接收者實例,並自動觸發它的onReceive()方法,當onReceive()方法被執行完成之後,BroadcastReceiver的實例就會被銷毀。雖然它獨自享用一個單獨的進程,但也不是沒有限制的,如果BroadcastReceiver.onReceive()方法不能在10秒內執行完成,Android系統就會認為該BroadcastReceiver對象無響應,然後彈出ANR(Application No Response)對話框,所以不要在BroadcastReceiver.onReceive()方法內執行一些耗時的操作。
如果需要根據廣播內容完成一些耗時的操作,一般考慮通過Intent啟動一個Service來完成該操作,而不應該在BroadcastReceiver中開啟一個新線程完成耗時的操作,因為BroadcastReceiver本身的生命周期很短,可能出現的情況是子線程還沒有結束,BroadcastReceiver就已經退出的情況,而如果BroadcastReceiver所在的進程結束了,該線程就會被標記為一個空線程,根據Android的內存管理策略,在系統內存緊張的時候,會按照優先級,結束優先級低的線程,而空線程無異是優先級最低的,這樣就可能導致BroadcastReceiver啟動的子線程不能執行完成。
BroadcastReceiver的種類
上面提到,當系統以一個Intent的形式發送一個Broadcast出去之後,所有與之匹配的BroadcastReceiver都會被實例化,但是這裡是有區別的,根據Broadcast的傳播方式區別,在系統中有如下兩種Broadcast:
雖然系統存在兩種類型的Broadcast,但是一般系統發送出來的Broadcast均是有序廣播,所以可以通過優先級的控制,在系統內置的程序響應前,對Broadcast提前進行響應。這就是市場上一些攔截器類(如:短信攔截器、電話攔截器)的軟件的原理。
如何發送一個廣播
上面已經介紹了系統中兩種不同的Broadcast,而根據Broadcast傳播的方式,Context提供了不同的方法來發布它們:
以上兩個方法都有多個重載方法,根據不同的場景使用,最簡單的莫過於直接傳遞一個Intent來發送一個廣播。
如何使用BroadcastReceiver
BroadcastReceiver本質上還是一個監聽器,所以使用BroadcastReceiver的方法也是非常簡單,只需要繼承BroadcastReceiver,在其中重寫onReceive(Context context,Intent intent)即可。一旦實現了BroadcastReceiver,並部署到系統中後,就可以在系統的任何位置,通過sendBroadcast、sendOrderedBroadcast方法發送Broadcast給這個BroadcastReceiver。
但是僅僅繼承BroadcastReceiver和實現onReceive()方法是不夠的,同為Android系統組件,它也必須在Android系統中注冊,注冊一個BroadcastReceiver有兩種方式:
雖然Android系統提供了兩種方式注冊BroadcastReceiver,但是一般在實際開發中,還是會使用清單文件進行注冊:
- <receiver android:name="cn.bgxt.Broadcastdemo.Basic.BasicBroadcast">
- <intent-filter android:priority="100">
- <action android:name="cn.bgxt.Broadcastdemo.Basic.broadcast"/>
- </intent-filter>
- </receiver>
下面通過一個簡單的示例,講解一下BroadcastReceiver的聲明,以及如何向這個BroadcastReceiver發送消息。
首先先聲明一個BroadcastReceiver,BasicBroadcast.java:
- package cn.bgxt.Broadcastdemo.Basic;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.widget.Toast;
- public class BasicBroadcast extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Toast.makeText(context,
- "接收到Broadcast,消息為:" + intent.getStringExtra("msg"),
- Toast.LENGTH_SHORT).show();
- }
- }
再聲明一個Activity,用於發送Broadcast:BasicActivity.java:
- package cn.bgxt.Broadcastdemo.Basic;
- import com.bgxt.datatimepickerdemo.R;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- public class BasicActivity extends Activity {
- Button btnBasicSendNormal, btnBasicSendOrdered;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_basic);
- btnBasicSendNormal = (Button) findViewById(R.id.btnBasicSendNormal);
- btnBasicSendOrdered = (Button) findViewById(R.id.btnBasicSendOrdered);
- btnBasicSendNormal.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent broadcast=new Intent();
- broadcast.setAction("cn.bgxt.Broadcastdemo.Basic.broadcast");
- broadcast.putExtra("msg", "這是一個普通廣播");
- sendBroadcast(broadcast);
- }
- });
- btnBasicSendOrdered.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent broadcast=new Intent();
- broadcast.setAction("cn.bgxt.Broadcastdemo.Basic.broadcast");
- broadcast.putExtra("msg", "這是一個有序廣播");
- sendOrderedBroadcast(broadcast, null);
- }
- });
- }
- }
效果展示:
源碼下載
總結
這篇文章已經簡要說明了BroadcastReceiver的使用以及需要注意的地方。但是一般實際項目中,很少自己定制Broadcast去使用,大多數情況下是去攔截系統發布的Broadcast,針對系統發布的Broadcast內容來做相應的操作。Android系統中原生定義了很多廣播的內容,如:開機、關機、來電、短信等等一些系統狀態的變化的Broadcast。但是關於系統Broadcast的內容,不在本文內,之後再慢慢詳細介紹。
Android提供的剪貼板框架,復制和粘貼不同類型的數據。數據可以是文本,圖像,二進制流數據或其它復雜的數據類型。Android提供ClipboardManager、Cl
最近在做一個項目涉及到將包含圖片的簡單網頁下載到本地,方便離線時觀看,在這裡分享一下,大家做下簡單修改就可以用到自己的項目中了。(這裡用到了AQuery庫) 代
在項目開發中,可能系統自帶的一些widget不能滿足我們的需求,這時就需要自定義View。 通過查看系統中的常用widget如Button,TextView,Ed
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放