編輯:關於Android編程
1、什麼是安卓的Broadcast?
安卓的四大組件之一,是一種廣泛應用在應用程序之間傳輸信息的機制。
2、什麼是安卓的BroadcastReceiver?
是對發送出來的廣播進行過濾接收並響應的一類組件,它就是用來接收來自系統和應用中的廣播。例如系統的廣播有開機廣播: 系統在開機時候會發送開機廣播,程序接收到之後,能進行開機自啟動。 網絡狀態改變廣播: 3g變wifi、網絡斷開等。電量改變廣播等等。。。
3、Anroid為什麼要這樣設計?
大大減少開發工作量和開發周期
作為開發者,只需要掌握BroadcastReceiver
4、怎麼理解Broadcast和BroadcastReceiver ?
Broadcast就像現實中的廣播電台,他發廣播信號來,然後我們用收音機來接收,然後處理,並且播放出聲音, BroadcastReceiver就相當於那台收音機。
5、使用方法
發送:
把信息裝入一個Intent對象(如:Action、Category),通過調相應的方法將Intent對象以廣播的方式發送出去:
sendBroadcast();
sendOrederBroadcast();
sendStickyBroadcast();
接收:
當Intent發送之後,所有已經注冊vedBroadcastReceiver會檢查注冊時的IntentFilter是否與發送的Intent相匹配,若匹配則就會調用BroadcastReceiver的onReceiver()方法。所以當我們定義一個BroadcastReceiver的時候,都需要實現onReceiver()方法。
注意:
BroadcastReceiver需要注冊
靜態注冊
代碼動態注冊
6、注意!!!!
BroadReceiver生命周期只有十秒左右,不能直接執行耗時操作,不然會出現ANR(應用程序無響應),也不能用子線程來做,因為每次廣播來的時候都會創建一個Reveiver對象,並且調用onReceiver,執行完之後 ,對象會立刻被銷毀,子線程也沒了
要做耗時操作的話,應該通過發送Intent給Service,由Service來完成。
動態注冊廣播接受者的話要在Destory回調事件進行unregister
7、廣播的分類
普通廣播 (Normal broadcast)
- 所有監聽該廣播接受者都可以監聽到該廣播
- 同級別接收先後順序是隨機的(無序)
- 級別低的後收到廣播
- 接收器不能截斷廣播的繼續傳播,也不能處理廣播
- 同級別動態注冊高於靜態注冊
有序廣播 (Oredered broadcast)
- 按照接收者的優先順序來接收廣播,優先級別在intent-filter中的priority中聲明,-1000到1000之間,值越大優先級越高,可以終止廣播的繼續傳播,接受者可以修改intent的內容。
- 同級別接收順序是隨機的
- 級別低的後收到
- 能截斷廣播的繼續傳播,高級別的廣播接收器接收廣播後能決定時候截斷。
- 能處理廣播
- 同級別動態注冊高於靜態注冊
異步廣播 (粘滯性滯留廣播) ps:已被棄用
- 不能處理結果給下一個接收者,無法終止廣播。
- 一直存在
- 可以先發送廣播,再注冊接收器
- 需要在清單文件添加android.permission.BROADCAST_STICKY權限
8、Demo
布局actibity_main三個按鈕:
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btOne;
private Button btTwo;
private Button btThree;
MyReiceiverThree myReiceiver = new MyReiceiverThree();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btOne = (Button) findViewById(R.id.bt_one);
btTwo = (Button) findViewById(R.id.bt_two);
btThree = (Button) findViewById(R.id.bt_three);
btOne.setOnClickListener(this);
btTwo.setOnClickListener(this);
btThree.setOnClickListener(this);
//動態注冊,在當前activity的生命周期內運行
/*IntentFilter filter= new IntentFilter(Config.BC_ONE_ACTION);
MyReiceiver myReiceiver = new MyReiceiver();
registerReceiver(myReiceiver,filter);*/
}
@Override
public void onClick(View view) {
Intent intent = new Intent();
switch (view.getId()){
case R.id.bt_one: //發送普通廣播
intent.setAction(Config.BC_ONE_ACTION);
intent.putExtra("msg","這是普通廣播");
sendBroadcast(intent);
break;
case R.id.bt_two: //有序廣播
intent.setAction(Config.BC_TWO_ACTION);
intent.putExtra("msg","這是有序廣播");
sendOrderedBroadcast(intent,null); //其中第二個參數是設置權限,即接收器必須具有相應的權限才能正常接收到廣播。
break;
case R.id.bt_three: //異步廣播
intent.setAction(Config.BC_THREE_ACTION);
intent.putExtra("msg","這是異步廣播");
sendStickyBroadcast(intent);
//可以先發送 後注冊
IntentFilter filter = new IntentFilter(Config.BC_THREE_ACTION);
registerReceiver(myReiceiver, filter);
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReiceiver);
}
}
MyReceiver.java
public class MyReiceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//獲取處理的的廣播,普通廣播不能獲取處理
//true代表如果前面的接收器沒有存放數據,則自動創建一個空的Bundle對象,false則表示如果前面的接收器如果沒有存放任何數據則返回null。
Bundle bundle= getResultExtras(true);
System.out.println("接收器1接收到處理的值:"+bundle.getString("msg"));
System.out.println("接收器1:"+intent.getStringExtra("msg"));
}
}
MyReceiverTwo.java
public class MyReiceiverTwo extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Toast.makeText(context,intent.getStringExtra("msg"),Toast.LENGTH_SHORT).show();
System.out.println("接收器2:"+intent.getStringExtra("msg"));
abortBroadcast(); //截斷廣播,不讓別的接收器繼續接收,有序廣播才能成功攔截
//處理廣播
Bundle bundle = new Bundle();
bundle.putString("msg","處理過後的廣播");
setResultExtras(bundle); //
}
}
MyReceiverThree.java
public class MyReiceiverThree extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Toast.makeText(context,intent.getStringExtra("msg"),Toast.LENGTH_SHORT).show();
System.out.println("接收器3:"+intent.getStringExtra("msg"));
}
}
Config.java
public class Config {
public static final String BC_ONE_ACTION = "com.example.testbroadcasetwo.bcone";
public static final String BC_TWO_ACTION = "com.example.testbroadcasetwo.bctwo";
public static final String BC_THREE_ACTION = "com.example.testbroadcasetwo.bcthree";
}
Androidmanifest.xml
//異步廣播需要 一個權限
//靜態注冊,全局有效
//第一個接收器
//添加級別
//第二個接收器
//添加級別
9、onReceiver回調更新ui
注意: 必須使用動態注冊才能實現回調更新ui
目錄結構:
Confiug.java 定義一個常量作為action<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
public class Config {
public static String BC_ONE = "com.example.testbroadcast.bcone";
}
TYPE.java 枚舉類,集合,沒用了,用來判斷是什麼廣播的
public enum TYPE {
NORMAL
}
HandleBroadcas.java p層的處理數據類
public class HandleBroadcast {
private IShowView iShowView;
private Context context;
public HandleBroadcast(final IShowView iShowView, Context context) {
this.iShowView = iShowView;
this.context = context;
//必須動態注冊才能實現回調
MyBroadcastReceiver broadcast = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Config.BC_ONE);
context.registerReceiver(broadcast, intentFilter);
broadcast.setiShowView(new IShowView() {
@Override
public void updateText(String msg) {
iShowView.updateText(msg);
}
});
}
public void sendMyBroadcast(TYPE type) {
Intent intent = new Intent();
switch (type) {
case NORMAL: //普通廣播
intent.putExtra("msg", "普通廣播發送成功");
intent.setAction(Config.BC_ONE);
context.sendBroadcast(intent);
break;
}
}
}
MyBroadcast.java 廣播接收器
public class MyBroadcastReceiver extends BroadcastReceiver {
private IShowView iShowView;
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
String msg = intent.getStringExtra("msg");
iShowView = (MainActivity) context;
if (action.equals(Config.BC_ONE)) { //接收到普通廣播
iShowView.updateText(msg); //回調給HandleBroadcast
}
}
public void setiShowView(IShowView iShowView) {
this.iShowView = iShowView;
}
}
IShowView.java 回調到activity更新ui的接口
public interface IShowView {
void updateText(String msg);
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener,IShowView{
private Button btOne;
private TextView mTvResult;
//p層,處理數據
private HandleBroadcast handleBroadcast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handleBroadcast = new HandleBroadcast(this,this);
btOne = (Button) findViewById(R.id.bt_one);
mTvResult = (TextView) findViewById(R.id.tv_result);
btOne.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bt_one:
handleBroadcast.sendMyBroadcast(TYPE.NORMAL);
break;
}
}
/**
* 廣播接收處理完畢之後回調更新ui
* @param msg 要顯示的文字
*/
@Override
public void updateText(String msg) {
mTvResult.setText(msg);
}
}
activity_main.xml
昨天給大家粗略的介紹了一下我那個簡單的項目:Android之基於XMPP協議即時通訊軟件(一) 從今天開始,就詳細展開的介紹設計思路,一是給自己做個總結,二
ViewFlipper和ViewPager挺像的,都是一個view容器。內部可以添加多個view,只是viewpager可以通過左右滑動來切換view,而viewFlip
好吧,終於要開始講解Activity的啟動流程了,Activity的啟動流程相對復雜一下,涉及到了Activity中的生命周期方法,涉及到了Android體系的CS模式,
想使用藍牙呢,首先得看手機是否支持,有些低配手機,可能就沒有內置藍牙模塊。當然,一般都會有,我們可以得到唯一的藍牙適配器,進行其他操作。 bluetoothAd