編輯:關於android開發
Broadcast即廣播,在Android廣播是非常重要的功能。例如我們想在系統開機之後做某些事情、監控手機的電量、監控手機的網絡狀態等等,這些功能都需要用到廣播。當然我們也可以自定義廣播。
通常實現一個簡單的自定義廣播可以通過如下幾個步驟:
創建一個類繼承android.content.BroadcastReceiver,並實現onReceive方法 在AndroidManifest.xml中注冊廣播 通過Context的registerReceiver等方法注冊廣播 調用Context的sendBroadcast等方法發送廣播,在onReceive方法中處理廣播 調用Context的unregisterReceiver等方法注銷廣播我們通過代碼來解釋一下上面的步驟:
1.創建一個類繼承android.content.BroadcastReceiver,並實現onReceive方法
package com.mark.broadcastreciver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* 創建一個自定義廣播接收者需要繼承android.content.BroadcastReceiver,
* 並實現onReceive方法即可。
*/
public class MyReceiver extends BroadcastReceiver {
private final static String TAG = MyReceiver.class.getSimpleName();
public MyReceiver() {
}
/**
* 當接收到廣播之後會調用此方法
* @param context 上下文對象
* @param intent 調用sendBroadcast(intent)傳入的Intent實例,其中包含了action、和其他附帶信息
*/
@Override
public void onReceive(Context context, Intent intent) {
// 獲取msg對應的數據
String msg = intent.getStringExtra("msg");
// 打印msg數據
Log.i(TAG, "msg = " + msg);
// 打印action字符串
Log.i(TAG, "action = " + intent.getAction());
}
}
2.在AndroidManifest.xml中注冊廣播
3.通過Context的registerReceiver等方法注冊廣播
4.調用Context的sendBroadcast等方法發送廣播,在onReceive方法中處理廣播
5.調用Context的unregisterReceiver等方法注銷廣播
package com.mark.broadcastreciver;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class MainActivity extends AppCompatActivity {
BroadcastReceiver registerReceiver;
IntentFilter intentFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 創建BroadcastReceiver實例
registerReceiver = new MyReceiver();
// 創建IntentFilter,指定其action為com.mark.broadcast.receiver,這個可以自己定義
intentFilter = new IntentFilter("com.mark.broadcast.receiver");
// 注冊廣播將registerReceiver與intentFilter關聯,
// registerReceiver可以接收到action為com.mark.broadcast.receiver的廣播
registerReceiver(registerReceiver, intentFilter);
findViewById(R.id.btnRegister).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 發送廣播
// 創建Intent,指定其action為com.mark.broadcast.receiver,與registerReceiver關聯的action一致
Intent intent = new Intent("com.mark.broadcast.receiver");
// 指定要發送的信息
intent.putExtra("msg", "Hello, a new message.");
sendBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(registerReceiver);
}
}
通過上述的步驟我們就實現了一個自定義廣播,當我們點擊Button在控制台中可以看到如下信息:
04-13 17:12:28.591 16882-16882/com.mark.broadcastreciver I/MyReceiver: msg = Hello, a new message.
04-13 17:12:28.591 16882-16882/com.mark.broadcastreciver I/MyReceiver: action = com.mark.broadcast.receiver
注冊廣播的方式有兩種:靜態注冊和動態注冊。
這種方法是在配置AndroidManifest.xml配置文件中注冊,通過這種方式注冊的廣播為常駐型廣播,也就是說如果應用程序關閉了,有相應事件觸發,程序還是會被系統自動調用運行。例如:
這種方法是通過代碼在.Java文件中進行注冊。通過這種方式注冊的廣播為非常駐型廣播,即它會跟隨Activity的生命周期,所以在Activity結束前我們需要調用unregisterReceiver(receiver)方法移除它。例如:
// 創建BroadcastReceiver實例
registerReceiver = new MyReceiver();
// 創建IntentFilter,指定其action為com.mark.broadcast.receiver,這個可以自己定義
intentFilter = new IntentFilter("com.mark.broadcast.receiver");
// 注冊廣播將registerReceiver與intentFilter關聯,
// registerReceiver可以接收到action為com.mark.broadcast.receiver的廣播
registerReceiver(registerReceiver, intentFilter);
注意:如果我們在Activity中注冊了BroadcastReceiver,當這個Activity銷毀的時候要主動撤銷注冊否則會出現異常。方法如下:
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(registerReceiver);
}
Broadcast的類型有兩種:普通廣播和有序廣播。
Normal broadcasts是完全異步的可以同一時間被所有的接收者接收到。消息的傳遞效率比較高。但缺點是接收者不能講接收的消息的處理信息傳遞給下一個接收者也不能停止消息的傳播。多個普通廣播設置相同的IntentFilter,則先注冊的先收到廣播。
Ordered broadcasts的接收者按照一定的優先級進行消息的接收。如:A,B,C的優先級依次降低,那麼消息先傳遞給A,在傳遞給B,最後傳遞給C。優先級別聲明在中,取值為[-1000,1000]數值越大優先級別越高。優先級也可通過filter.setPriority(10)方式設置。
另外Ordered broadcasts的接收者可以通過abortBroadcast()的方式取消廣播的傳播,也可以通過setResultData和setResultExtras方法將處理的結果存入到Broadcast中,傳遞給下一個接收者。然後,下一個接收者通過getResultData()和getResultExtras(true)接收高優先級的接收者存入的數據。
例如:
如上兩個receiver我們分別設置為priority為999,和1000,及時MyReceiver是後注冊的,但是其優先級比FirstReceiver高,則MyReceiver會先處理廣播。
sendOrderedBroadcast(intent, receiverPermission)方法接收兩個參數,比普通廣播的發送方式多了一個receiverPermission參數,這是一個String類型的參數,代表具有這個權限的Receiver才能處理收到此廣播。如果為null則表明不要求接受者聲明指定權限。我們來看一下具體的操作。
首先我們要自定義一個權限,例如:
然後我們要是當前的程序具有此權限:例如:
這樣當前程序就擁有此權限了。
我們在發送有序廣播是指定其權限為com.permissions.MY_BROADCAST_RECEIVER,注意拼寫不要有錯誤,最好是復制過來。發送廣播如下:
// 創建Intent,指定其action為com.mark.broadcast.receiver,與registerReceiver關聯的action一致
Intent intent = new Intent("com.mark.broadcast.receiver");
// 指定要發送的信息
intent.putExtra("msg", "Hello, a new message.");
sendOrderedBroadcast(intent, "com.permissions.MY_BROADCAST_RECEIVER");
這樣我們發送廣播,並指定其權限為com.permissions.MY_BROADCAST_RECEIVER,因為當前的程序已經使用了此權限了,所以當前程序中的receiver是可以接收並處理此條廣播的。否則不能接收此條廣播。此處的權限體現了android對安全性的重視。
粘性廣播與其他的廣播方式最大的不同在於“異步”,也就是說當一個粘性廣播發出去後,可以沒有Receiver進行處理,但是這個廣播還會一直存在,假如過了一段時間之後有Receiver注冊了此廣播,則此Receiver還是可以處理這條廣播的。但是細心的朋友們可以看到sendStickyBroadcast的一系列重載方法的參數中並沒有上面提到的receiverPermission參數,這也將導致粘性廣播在安全性上存在問題。所以在API Level 21 上sendStickyBroadcast方法被標記為deprecated,也就是不建議我們使用粘性廣播了。因為在安全性和其他方面粘性廣播存在很多缺陷。這裡我們也就不在重點討論了。
這裡我們對廣播及廣播接收者進行一個簡單的總結以及在使用時的一些注意事項。
1.發送廣播的方法都是ContextWrapper中的方法,而Activity、Service都是ContextWrapper的子類,所以在它們中都可以發送和注冊廣播
2.onReceive方法中不能做耗時操作,否則也會導致ANR
3.根據實際開發需要,盡可能為廣播增加權限
4.盡可能避免使用粘性廣播
5.有序廣播的優先級為【-1000 ~ 1000】,數值越大,優先級越高
上述描述和某些觀點可能不是正解,僅供參考,歡迎大家指正、批評。
Linux內核基數樹應用分析Linux內核基數樹應用分析——lvyilong316基數樹(Radix tree)可看做是以二進制位串為關鍵字的trie樹,是一種多叉樹結構
解決Android Graphical Layout 界面效果不顯示,androidgraphical 解決Android Graphical Layout 界
Android中使用GridView和ImageViewSwitcher實現電子相冊簡單功能,gridviewimageview我們在手機上查看相冊時,首先看到的是網格狀
Android網絡編程(二)HttpClient與HttpURLConnection 前言 上一篇我們了解了HTTP協議原理,這一篇我們來講講Apache的HttpCli
The Genymotion Virtual device could