廣播Intent的三種方式總結


1.android有序廣播和無序廣播的區別

BroadcastReceiver所對應的廣播分兩類:普通廣播和有序廣播。

普通廣播通過Context.sendBroadcast()方法來發送。它是完全異步的。

所有的receivers接收器的執行順序不確定。    因此,所有的receivers接收器接收broadcast的順序不確定。

這種方式效率更高。但是BroadcastReceiver無法使用setResult系列,getResult系列及abort系列API

有序廣播是通過Context.sendOrderedBroadcast來發送。所有的receiver依次執行。

BroadcastReceiver可以使用setResult系列函數來結果傳給下一個BroadcastReceiver,通過getResult系列函數來取得上個BroadcastReceiver返回的結果,並可以abort系列函數來讓系統丟棄該廣播讓,使用該廣播不再傳送到別的BroadcastReceiver。

可以通過在intent-filter中設置android:priority屬性來設置receiver的優先級。優先級相同的receiver其執行順序不確定。

如果BroadcastReceiver是代碼中注冊的話,且其intent-filter擁有相同android:priority屬性的話,先注冊的將先收到廣播。

有序廣播,即從優先級別最高的廣播接收器開始接收,接收完了如果沒有丟棄,就下傳給下一個次高優先級別的廣播接收器進行處理,依次類推,直到最后。

2.sendBroadcast和sendStickyBroadcast的區別

sendBroadcast中發出的intent在ReceverActivity不處於onResume狀態是無法接受到的,即使后面再次使其處於該狀態也無法接受到。

而sendStickyBroadcast發出的Intent當ReceverActivity重新處於onResume狀態之后就能重新接受到其Intent.這就是the Intent will be held to be re-broadcast to future receivers這句話的表現。就是說sendStickyBroadcast發出的最后一個Intent會被保留,下次當Recevier處於活躍的時候,又會接受到它。

3. FLAG的影響
1)FLAG_RECEIVER_REPLACE_PENDING
這個flag 將會將之前的Intent 替代掉。加了這個flag,在發送一系列的這樣的Intent 之后, 中間有些Intent 有可能在你還沒有來得及處理的時候,就被替代掉了。
2)FLAG_RECEIVER_REGISTERED_ONLY:
如果Intent 加了這個Flag, 那么在Androidmanifest.xml 里定義的Receiver 是接收不到這樣的Intent 的。
3)FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT:
如果Intent加了這個Flag,那么在啟動檢查時只能接受在代碼中注冊的Receiver。這個標志是唯一使用的系統服務作為一種方便避免實施更復雜的機制在啟動完成檢測。

sendStickyBroadcast 的理解和使用

要知道區別首先需要看一下Android Developers Reference, 它可是我們最好的老師了,sendBroadcast 大家應該都會用了我就不贅述了,下面來看看sendStickyBroadcast

google官方的解釋是:

Perform a sendBroadcast(Intent) that is "sticky," meaning the Intent you are sending stays around after the broadcast is complete, so that others can quickly retrieve that data through the return value ofregisterReceiver(BroadcastReceiver, IntentFilter). In all other ways, this behaves the same as sendBroadcast(Intent).

You must hold the BROADCAST_STICKY permission in order to use this API. If you do not hold that permission,SecurityException will be thrown.

大概的意思是說: 發出的廣播會一直滯留(等待),以便有人注冊這則廣播消息后能盡快的收到這條廣播。其他功能與sendBroadcast相同。但是使用sendStickyBroadcast 發送廣播需要獲得BROADCAST_STICKY permission,如果沒有這個permission則會拋出異常。

 

這個解釋看了后似懂非懂的,於是就寫了個例子試了下,下面把代碼貼出了,希望能還大家一起討論

  1. package com.android.test;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10.   
  11. public class StickyBroadcastTest extends Activity {  
  12.    
  13.  private Button mSendBroadcast;  
  14.  private Button mSendStickyBroadcast;  
  15.  private Button mNextActivity;  
  16.  private Context mContext;  
  17.    
  18.  private int mStickyBrcCount;  
  19.     
  20.     /** Called when the activity is first created. */  
  21.     @Override  
  22.     public void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.main);  
  25.         mContext = getApplicationContext();  
  26.         mSendBroadcast = (Button)findViewById(R.id.broadcast);  
  27.         mSendStickyBroadcast = (Button)findViewById(R.id.stickybroadcast);  
  28.         mNextActivity = (Button)findViewById(R.id.next_activity);  
  29.           
  30.         mSendBroadcast.setOnClickListener(new OnClickListener() {  
  31.      
  32.    @Override  
  33.    public void onClick(View v) {  
  34.       
  35.     Intent intent = new Intent("com.android.action.broadcast");  
  36.     mContext.sendBroadcast(intent);  
  37.    }  
  38.   });  
  39.           
  40.         mSendStickyBroadcast.setOnClickListener(new OnClickListener() {  
  41.      
  42.    @Override  
  43.    public void onClick(View v) {  
  44.     mStickyBrcCount++;  
  45.     Intent intent = new Intent("com.android.action.sticky.broadcast");  
  46.     intent.putExtra("sent_count", mStickyBrcCount);  
  47.     mContext.sendStickyBroadcast(intent);  
  48.       
  49.    }  
  50.   });    
  51.         mNextActivity.setOnClickListener(new OnClickListener() {  
  52.      
  53.    @Override  
  54.    public void onClick(View v) {  
  55.     Intent intent = new Intent(StickyBroadcastTest.this, MyReceiverActivity.class);  
  56.     startActivity(intent);     
  57.       
  58.    }  
  59.   });  
  60.     }  
  61.   
  62.  @Override  
  63.  protected void onResume() {  
  64.   // TODO Auto-generated method stub   
  65.   super.onResume();  
  66.   mStickyBrcCount = 0;  
  67.  }  
  68.      
  69. }  
  70.   
  71.    
  72. //MyReceiverActivity    
  73. package com.android.test;  
  74.   
  75. import android.app.Activity;  
  76. import android.content.BroadcastReceiver;  
  77. import android.content.Context;  
  78. import android.content.Intent;  
  79. import android.content.IntentFilter;  
  80. import android.os.Bundle;  
  81. import android.util.Log;  
  82.   
  83. public class MyReceiverActivity extends Activity {  
  84.   
  85.  private IntentFilter mIntentFilter;  
  86.  private final static String TAG = "MyReceiverActivity";  
  87.     /** Called when the activity is first created. */  
  88.     @Override  
  89.     public void onCreate(Bundle savedInstanceState) {  
  90.         super.onCreate(savedInstanceState);  
  91.         setContentView(R.layout.broadcast_receiver);  
  92.           
  93.         mIntentFilter = new IntentFilter();     
  94.         mIntentFilter.addAction("com.android.action.broadcast");     
  95.         mIntentFilter.addAction("com.android.action.sticky.broadcast");     
  96.   
  97.     }  
  98.        
  99.  private BroadcastReceiver  mReceiver = new BroadcastReceiver () {  
  100.   @Override  
  101.   public void onReceive(Context context, Intent intent) {  
  102.    final String action = intent.getAction();  
  103.    int count = intent.getIntExtra("sent_count", -1);  
  104.    Log.d(TAG, "action = " + action + "and count = " + count);  
  105.      
  106.    //context.removeStickyBroadcast(intent);   
  107.   }  
  108.  };  
  109.   
  110.  @Override  
  111.  protected void onPause() {  
  112.   // TODO Auto-generated method stub   
  113.   super.onPause();  
  114.   unregisterReceiver(mReceiver);     
  115.   
  116.  }   
  117.   
  118.  @Override  
  119.  protected void onResume() {  
  120.   // TODO Auto-generated method stub     
  121.   super.onResume();  
  122.   registerReceiver(mReceiver, mIntentFilter);   
  123.  }  
  124.      
  125. }  

運行結果如圖:

首先點擊next Activity從代碼中可以看到receiver已經注冊,但Log無輸出,這是當然的了~~~因為沒有廣播發出自然就不會有人響應了。

按back后退到上圖

下面分別點擊send broadcast 和 send stickybroadcast按鈕,隨便點擊幾次,此時對應的receiver並沒有注冊,所以是不會有人響應這兩條廣播的。然后點擊next activity,當打開新的activity后對應的receiver被注冊,此時從日志中就能看出已經收到了send stickybroadcast發出的廣播,但沒有send broadcast發出的廣播。這就是sendStickyBroadcast的特別之處,它將發出的廣播保存起來,一旦發現有人注冊這條廣播,則立即能接收到。

日志打印為: action = com.android.action.sticky.broadcastand count = 4

從上面的日志信息可以看出sendStickyBroadcast只保留最后一條廣播,並且一直保留下去,這樣即使已經處理了這條廣播但當再一次注冊這條廣播后依然可以收到它。

如果你只想處理一遍,removeStickyBroadcast方法可以幫你,處理完了后就將它刪除吧。

 

相似的例子:

  1. package com.android.testbroadcast;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10.   
  11. public class MainActivity extends Activity {  
  12.     Button btnSendi;  
  13.     Button btnSends;  
  14.     Button btnStart;  
  15.     Context mContext;  
  16.     /** Called when the activity is first created. */  
  17.     @Override  
  18.     public void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.main);  
  21.         btnSendi=(Button) findViewById(R.id.sendi);  
  22.         btnSends=(Button) findViewById(R.id.sends);  
  23.         btnStart=(Button) findViewById(R.id.start);  
  24.         mContext=getApplicationContext();  
  25.         btnSendi.setOnClickListener(new OnClickListener(){  
  26.   
  27.             @Override  
  28.             public void onClick(View v) {  
  29.                 // TODO Auto-generated method stub  
  30.                 Intent intent = new Intent();  
  31.                 intent.setAction("com.android.my.action");  
  32.                 intent.setFlags(1);  
  33.                 mContext.sendBroadcast(intent);  
  34.             }  
  35.               
  36.         });  
  37.           
  38.         btnStart.setOnClickListener(new OnClickListener(){  
  39.   
  40.             @Override  
  41.             public void onClick(View v) {  
  42.                 // TODO Auto-generated method stub  
  43.                 Intent intent = new Intent(MainActivity.this,ReceiverActivity.class);  
  44.                  
  45.                 startActivity(intent);  
  46.             }  
  47.               
  48.         });  
  49.           
  50.         btnSends.setOnClickListener(new OnClickListener(){  
  51.   
  52.             @Override  
  53.             public void onClick(View v) {  
  54.                 // TODO Auto-generated method stub  
  55.                 Intent intent = new Intent();  
  56.                 intent.setAction("com.android.my.action.sticky");  
  57.                 intent.setFlags(2);  
  58.                 mContext.sendStickyBroadcast(intent);  
  59.             }  
  60.               
  61.         });  
  62.     }  
  63. }  

 

Java代碼   收藏代碼
  1. package com.android.testbroadcast;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.BroadcastReceiver;  
  5. import android.content.Context;  
  6. import android.content.Intent;  
  7. import android.content.IntentFilter;  
  8. import android.net.wifi.WifiManager;  
  9. import android.os.Bundle;  
  10. import android.view.View;  
  11. import android.view.View.OnClickListener;  
  12. import android.widget.Button;  
  13.   
  14. public class ReceiverActivity extends Activity {  
  15.      private IntentFilter mIntentFilter;  
  16.       
  17.     /** Called when the activity is first created. */  
  18.     @Override  
  19.     public void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.main);  
  22.         mIntentFilter = new IntentFilter();  
  23.         mIntentFilter.addAction("com.android.my.action");  
  24.         mIntentFilter.addAction("com.android.my.action.sticky");  
  25.   
  26.               
  27.     }  
  28.     private BroadcastReceiver mReceiver = new BroadcastReceiver() {  
  29.   
  30.         @Override  
  31.         public void onReceive(Context context, Intent intent) {  
  32.             final String action = intent.getAction();  
  33.             System.out.println("action"+action);  
  34.               
  35.         }  
  36.     };  
  37.       
  38.     @Override  
  39.     protected void onResume() {  
  40.         // TODO Auto-generated method stub  
  41.         super.onResume();  
  42.         registerReceiver(mReceiver, mIntentFilter);  
  43.     }  
  44.       
  45.     @Override  
  46.     protected void onPause() {  
  47.         // TODO Auto-generated method stub  
  48.         super.onPause();  
  49.         unregisterReceiver(mReceiver);  
  50.     }  
  51.       
  52.       
  53. }  



在MainActivity里面會有sendBroadcast和sendStickyBroacat.在ReceverActivity里面通 過BroadcastReceiver來接收這兩個消息,在ReceiverActivity里是通過代碼來注冊Recevier而不是在 Manifest里面注冊的。所以通過sendBroadcast中發出的intent在ReceverActivity不處於onResume狀態是無 法接受到的,即使后面再次使其處於該狀態也無法接受到。而sendStickyBroadcast發出的Intent當ReceverActivity重 新處於onResume狀態之后就能重新接受到其Intent.這就是the Intent will be held to be re-broadcast to future receivers這句話的表現。就是說sendStickyBroadcast發出的最后一個Intent會被保留,下次當Recevier處於活躍的 時候,又會接受到它。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM