Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android : Broadcast

Android : Broadcast

編輯:關於Android編程

Broadcast是Application之間交換數據最簡單的一種方法。

Broadcast組成部分

Broadcast 功能,由發送Broadcast的Sender和接收的Receiver組成。
Sendor和Receiver沒有直接的聯系,所以這兩個部分可以在一個Application內,也可以不再一個Application內。然後可以從Broadcast字面字面意思上也可以知道,Sendor和Receiver不一定是一對一,也可以是1對N。
Broadcast的傳遞是用Binder傳遞的,其傳遞的數據放在Intent裡邊傳遞。

Broadcast發送

Broadcast可以使用Context class的sendBroadcast() 和 sendOrderedBroadcast() API進行發送。

Intent intent = new Intent("com.example.helloworld.TEST");
intent.putExtra("number", 7);
intent.putExtra("text", "hello");

sendBroadcast(intent);

sendBroadcast(Intent)是最為一般的發送方式。上面可以看到,Intent對象指定了Action name為com.example.helloworld.TEST。所以接收這個Broadcast的Receiver必須加上Intent-filter,其action name也必須指定為com.example.helloworld.TEST才能接收到Broadcast。
sendBroadcast(intent, permission)和上面相同,只不過後面多了一個permission,指定接收這個Broadcast所需的權限。如果Receiver所在的Package沒有指定這個permission,則收不到這個Broadcast。

sendOrderedBroadcast():一般的Broadcast都是aync,所以對很多Receiver的接收順序都不用太關心。
Ordered Broadcast雖然也是async,但是 Intent filer指定了android:priority屬性,根據android:priority來指定接收的順序,每次只發送一個。即,前面一個Receiver的 onReceive()函數返回才會發送給下一個。接收到Ordered Broadcast的Receiver可以指定Abort flash,然後可以Set/Get Result code,data,extras等。

Broadcast接收

繼承BroadcastReceiver,實現onReceiver(),然後在注冊Receiver之後,就可以接收Broadcast intent。

public class HelloReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (action.equals("com.example.helloworld.TEST")) {
            int num = intent.getIntExtra("number", -1);
            String str = intent.getStringExtra("text");

            Toast.makeText(context, "Broadcast : number=" + num 
                    + " text=" + str, Toast.LENGTH_LONG).show();
        }
    }
}

Broadcast Receiver一般使用在manifest file裡邊聲明的方式注冊。

    
        
            
        
    

也可以使用Context class的registerReceiver(), unregisterReceiver() API的方式注冊Receiver。
一個Receiver可以注冊很多Intent filter,可以接收Android platform發送的ACTION_LOCALE_CHANGED或者ACTION_TIME_CHANGED等Broadcast。

注意事項

Broadcast發送的Data大小是有限制的。Broadcast是先被發送到Android platform的一個process裡邊的Broadcast queue,所以會發生Binder transaction。然後從Android platform發送給Receiver的過程當中也是會發生Binder transaction。所以一對一發送的Broadcast的過程當中,會發生兩次的Binder transaction。

!!為了保存return值,會用到Binder transaction buffer,每個進程會分配分配這個buffer大小為1MB。
Intent會包含Extra內容但也包含其他的一些內容,所以Extra的大小不能大於1MB。而且一個Binder transaction buffer,會被一個Process內的所有Binder transaction所共享,所以發送的一個Extra小與1MB,但很多組合起來之後,其大小可能會超過1MB。這時候會有如下的log。這裡13314是Sendor Process ID。

E/JavaBinder(13314): !!! FAILED BINDER TRANSACTION !!!

Android的Broadcast queue的Process因為不單單只接收我們發送的Broadcast而且還會與其他服務頻繁發生Binder transaction。所以即使我們的發送給Broadcast queue成功了,但也有可能從Broadcast queue發送給Receiver的過程當中也有可能出現錯誤。

E/JavaBinder(690): !!! FAILED BINDER TRANSACTION !!!
 W/BroadcastQueue(690): Exception when sending broadcast to ComponentInfo{com.example.helloworld/com.example.helloworld.HelloReceiver}
 W/BroadcastQueue(690): android.os.TransactionTooLargeException
 W/BroadcastQueue(690):     at android.os.BinderProxy.transact(Native Method)
 W/BroadcastQueue(690):     at android.app.ApplicationThreadProxy.scheduleReceiver(ApplicationThreadNative.java:822)
 W/BroadcastQueue(690):     at com.android.server.am.BroadcastQueue.processCurBroadcastLocked(BroadcastQueue.java:236)
 W/BroadcastQueue(690):     at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:870)
 W/BroadcastQueue(690):     at com.android.server.am.BroadcastQueue$1.handleMessage(BroadcastQueue.java:145)
 W/BroadcastQueue(690):     at android.os.Handler.dispatchMessage(Handler.java:99)
 W/BroadcastQueue(690):     at android.os.Looper.loop(Looper.java:137)

所以,要盡量避免通過Broadcast Intent傳送接收大的數據。

Broadcast發送之後出現ANR,描述如下:
如下一個ANR,提示出現ANR的APP是com.sec.android.app.clockpackage。
原因是:MSG: Broadcast of Intent { act=android.intent.action.TIME_TICK flg=0x50000014 (has extras) }

01-08 15:05:10.606 26881 26975 E CrashAnrHandler: --------> APP NOT RESPONDING
01-08 15:05:10.606 26881 26975 E CrashAnrHandler: // ANR: com.sec.android.app.clockpackage (pid 4952)
01-08 15:05:10.606 26881 26975 E CrashAnrHandler: // MSG: Broadcast of Intent { act=android.intent.action.TIME_TICK flg=0x50000014 (has extras) }

當一個廣播10s內還沒處理完的時候,就會出現ANR。
你檢查下Androidmanifest.xml裡面有沒有注冊這個broadcast receiver, 再看看程序代碼裡,有沒有調用registerReceiver之內的方法。

關於ANR的描述:
ANR stands for “Application not responding”. This message means that your application isn’t responsive to the user any more. Normally this exception is thrown if the UI thread is blocked by an operation which takes more than 5 seconds

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved