Broadcast相關總結

個人對廣播使用得不多,在目前接觸的項目開發中暫時沒有使用到廣播作爲組件間交流工具,僅僅是在做應用復活的時候,接觸過利用系統廣播拉活的機制(現在已經不那麼靈驗了)。不過廣播接收者作爲Android四大組件之一,其重要性自然不言而喻 ,也是各類面試的常客,還是得好好總結一番。


定義

廣播是一種廣泛應用的在應用程序之間傳輸信息的機制,Android中我們要發送的廣播內容是一個Intent,這個Intent中可以攜帶我們要傳送的數據。


使用場景

A、同一個app不同組件之間的消息通信(可以同進程或者不同進程)。
B、不同的app之間的組件之間進行通信。


種類與使用方式

  1. 普通廣播(Normal Broadcast)
  2. 系統廣播(System Broadcast)
  3. 有序廣播(Ordered Broadcast)
  4. 粘性廣播(Sticky Boradcast),在Android 5.0即API 21已經被廢棄
  5. 本地廣播(Local Broadcast)

1. 普通廣播

普通廣播就是我們最常使用的一種廣播,使用方法如下:
* 發送:我們在代碼中通過創建Intent,設置action,再通過Context調用sendBroadcast(Intent)方法發送。
* 接收
* 自定義一個廣播接收者類繼承自BroadcastReceiver,重寫裏面的onReceive(…)方法。
* 通過靜態或者動態方式註冊廣播接收者:
* 靜態:
在AndroidManifest.xml文件中的application標籤內註冊
java
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="123"/>
</intent-filter>
</receiver>

* 動態:
“` java
@Override
protected void onResume() {
super.onResume();
mReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter(“123”);
registerReceiver(mReceiver, intentFilter);
}

            @Override
            protected void onPause() {
                super.onPause();
                unregisterReceiver(mReceiver);
            }
        ```
        要注意的是通過動態註冊時,一定要記得註銷。Activity的聲明週期是成對出現的,因此在onResume方法中註冊,在onPause方法中註銷。因爲當Activity由於內存不足被回收時,只能保證onPause方法被調用,在onPause方法中進行註銷從而能避免內存泄漏。

2. 系統廣播

系統廣播是Android系統內置的廣播。當手機狀態發生改變時,系統會發出相應的預設的廣播。具體有哪些系統廣播請隨時搜索,不同版本谷歌會增刪一些廣播。要注意的是不要總是期望能接收到系統廣播,一些國產ROM出於安全考慮可能會屏蔽掉某些系統廣播。


3. 有序廣播

有序廣播與普通廣播類似,差別只在於發送時調用的是sendOrderedBroadcast(Intent)方法。有序廣播發出去後,會根據廣播接收者的優先級,按序傳遞,優先級高的廣播接收者先接收到廣播,可以對廣播進行修改後再傳遞給優先級較低的廣播接收者。也可以通過abortBroadcast()方法將廣播攔截,這樣優先級較低的廣播接收者將無法再接收到這條廣播。
至於廣播接收者的優先級,可以通過IntentFilter的setPriority(int)方法設置。


4. 粘性廣播

在Android 5.0 / Api 21中已被廢棄


5. 本地廣播

爲了解決其他應用通過註冊與當前應用一致的IntentFilter來接收一些敏感的廣播的安全問題,可以使用本地廣播。顧名思義,本地廣播是隻發往同個應用內的廣播,其他應用無法收到。發送本地廣播需要使用LocalBroadcastManager來進行,使用方法如下:

public class MainActivity extends AppCompatActivity {
    private final String TAG = getClass().getSimpleName();
    private BroadcastReceiver mReceiver;
    private LocalBroadcastManager mLbm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    public void onClick(View view) {
        Intent intent = new Intent("123");
        mLbm.sendBroadcast(intent);
        sendBroadcast(intent);
        Log.i(TAG, "發送廣播了");
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mReceiver == null) {
            mReceiver = new MyBroadcastReceiver();
        }
        if (mLbm == null) {
            IntentFilter intentFilter = new IntentFilter("123");
            mLbm = LocalBroadcastManager.getInstance(this);
            mLbm.registerReceiver(mReceiver, intentFilter);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mLbm != null && mReceiver != null) {
            mLbm.unregisterReceiver(mReceiver);
        }
    }
}

除了通過這種方法來保證廣播的安全性之外,我們還可以在發送普通廣播的時候,利用Intent指定接收的應用的包名,避免發送給其他應用,如下:

intent.setPackage(String packageName);

上面兩種方式能保證我們發送的廣播只被自身應用接收到。而要使應用內自定義的廣播接收者不接受其他應用的廣播,只需要在註冊廣播接收者的時候指定exported屬性爲false就可以了:

        <receiver android:name=".MyBroadcastReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="123"/>
            </intent-filter>
        </receiver>

exported屬性如果沒有設置,默認有intent-filter時爲true,否則爲false

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章