編輯:關於Android編程
Android有一個非常重要的特性,就是廣播.也可以將廣播看做是通信機制. Android四大組件: Activity, service, broadcastReceiver 和contentProvider, 只有Activity和service有完整的生命周期, 其他 broadcastReceiver 和contentProvider 都沒有. broadcastReceiver 本質上是一個監聽器, 負責監聽系統應用發出的廣播(BroadCast).
broadcastReceiver 有個onReceive(Context context, Intent intent)方法, 這個方法是廣播接收器broadcastReceiver接收廣播的地方,Intent可以看做是特定的廣播介質.不同的intent會觸發不同的廣播接收器,然後怎麼處理就放在onReceive() (省略寫法) 中去實現.
上面說到intent是廣播介質, 將intent放到發廣播的方法中去就ok:
public class broadCastTest extends Activity { private Button btn_send; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.id.act_main); btn_send = (Button)findViewById(R.id.btn_send); btn_send.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 發送廣播 sendMyBroadCast(); } }); } private void sendMyBroadCast() { Intent intent = new Intent(); //設置intent的Action屬性,這個會使intent找到與之對應的廣播接收器 intent.setAction(com.test.action.My_Test_BroadCast); //給Intent設置可傳遞的消息 intent.putExtra(msgKey, 消息內容); //發送廣播 sendBroadcast(intent); } }
注冊廣播接收器這裡,配合上面發送廣播的例子來看,會好理解一些.
在代碼中調用BroadCastReceiver的registerReceiver( BroadCastReceiver receiver, IntentFilter filter )方法去指定特定的intent廣播對應特定的廣播接收器:
//裡面內容填寫上面發送廣播的Action內容 IntentFilter filter = new IntentFilter(com.test.action.My_Test_BroadCast); //MyReceiver 是繼承了BroadCastReceiver自定義實現的廣播接收器MyReceiver, //最好這樣做,因為這樣才能區分不同的廣播接收器用於對應不同的廣播 MyReceiver receiver = new MyReceiver(); //注冊完畢,MyReceiver廣播接收器現在是對應接收 Action為com.test.action.My_Test_BroadCast的intent廣播 registerReceiver(receiver, filter);
1, 很多人用在跳轉Activity的時候都使用過intent來傳遞一些內容,如果intent沒有找到對應的Activity.class 就會報錯 class can not be found之類的錯誤.但在廣播中,使用Intent傳遞廣播,即使intent沒有找到對應的廣播接收器, 卻不會報錯.過一段時間,這個廣播會被系統自行銷毀.
2, 每發送一次廣播,廣播每次找到廣播接收器BroadCastReceiver,都會新建一個BroadCastReceiver實例,並不會說之前已經使用過這個BroadCastReceiver實例了就繼續沿用舊的BroadCastReceiver實例.因為每次BroadCastReceiver實例在onReceive()中接收並處理完廣播後就會銷毀這個實例.既然都不存在了, 所以下次再發同樣的廣播,也會繼續創建新的BroadCastReceiver實例.
3, 不要把耗時的操作放在onReceive() 中,切記! BroadCastReceiver實例的onReceive()只適合進行一些非常輕量化的操作,比如彈框提示網絡中斷了,比如進行一些簡單的數據處理等等. 因為超過一定時間( 舊版本這個上限是10秒,新版貌似短一些 ),如果onReceive()方法還沒有結束,系統就會強制銷毀這個實例,甚至報錯.
4, 如果在Activity中注冊了廣播接收器,那麼在退出Activity前,要先取消注冊這些廣播接收器.在onDestroy()中類似的:
@Override public void onDestroy() { // 取消注冊 getApplicationContext().unregisterReceiver(receiver); super.onDestroy(); }
5, 區別普通廣播和有序廣播. 上面說的都是普通廣播, 普通在於, 發送廣播和接收廣播兩者並不是同步的, 也就是說是異步的.你怎麼發送是你的事,人家廣播接收器怎麼接收處理也和發送廣播無關,所以有同時發送幾個廣播出去, 先發的可能遲一些才被響應, 後發的廣播有可能會更早被響應. 而有序廣播比較特殊, 它對廣播接收器的權限區分了優先級, 廣播會先發送到優先級高的那裡去,依次直至最後一個優先級最低的廣播接收器.而且優先級高的接收器有能力結束廣播,使廣播不再往優先級比自己低的接收器那裡傳遞.
關於有序廣播,上個例子:
首先在AndroidManifest.xml加入權限:
定義3個廣播接收器:
public class A_Receiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = intent.getStringExtra(key); //此處Bundle可用於向優先級低的接收器傳遞一些信息 Bundle bundle = new Bundle(); bundle.putString(msgKey_A, msg); setResultExtras(bundle); //如果最後一行加入abortBroadcast(),則廣播不再往下一個接收器傳播 //abortBroadcast(); } } public class B_Receiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = getResultExtras(true).getString(msgKey_A); //同上理 Bundle bundle = new Bundle(); bundle.putString(msgKey_B, msg); setResultExtras(bundle); } } public class C_Receiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = getResultExtras(true).getString(msgKey_B); //進行其他處理... } }
下面注冊廣播接收器:
發送有序廣播:
private void sendBroadCast() { Intent intent = new Intent(android.intent.action.MY_TEST_BROADCAST); intent.putExtra(key, hello receiver.); sendOrderedBroadcast(intent, scott.permission.MY_BROADCAST_PERMISSION); }
廣播機制是Android系統非常核心非常重要的一部門,配合service一起使用,能夠實現強大的後台.使應用更加流暢和高效,
在上一篇Android RecylerView入門教程中提到,RecyclerView不再負責Item視圖的布局及顯示,所以RecyclerView也沒有為Item開放O
Toast的自定義使用原理與其類似。1.Toast源碼分析老規矩,我們先去看Toast的源碼。Toast有兩種顯示布局方式,一種最常見調用Toast.makeText()
一種使用OpenGL渲染文字的常用方法,是計算出一個包含了顯示文字的紋理圖片,這通常是使用相當復雜的打包算法來最小化紋理中的冗余部分,在創建這樣的圖片之前必須清楚應用運行
本文實例講述了Android編程入門之HelloWorld項目目錄結構。分享給大家供大家參考,具體如下:我們介紹了如何搭建Android開發環境及簡單地建立一個Hello