標籤:
Android的另外兩大組件:BroadcastReceiver和Service。
一、BroadcastReceiver廣播接收者,廣播是Android中傳遞事件的方式,有兩個方面:廣播寄件者和廣播接收者。
1、廣播寄件者可以發送兩種廣播:同步廣播和有序廣播,兩者的區別是
①接收順序的區別:同步廣播同步接收,有序廣播可以通過指定優先順序來設定接收順序
②是否可以中斷的區別:由於有序廣播有順序,才有可能將廣播進行中斷,不讓後來者進行接收;而同步廣播則不能中斷。
2、廣播接收者:廣播發送的具體內容就是一個隱式意圖對象(因為通常是給另外的應用使用的),接收者通過兩步來實現
①在資訊清單檔中進行配置,
②繼承BroadcastReceiver對象,並重寫onReceive方法,在其中實現功能即可。
有序廣播通過指定優先順序來確定接收順序,優先順序從-1000~1000,
①如果同一個應用中的優先順序相同,則在資訊清單檔中前面的先接收
②如果不同應用中的優先順序相同,則先安裝的應用先接收
參考:http://blog.csdn.net/xiazdong/article/details/7768807,
二、Service,服務是沒有介面而在後台長期啟動並執行程式。
1、在Android中按返回鍵退出一個應用並不會(記憶體充足時)直接銷毀一個進程,所以其中的子線程也可以在後台運行,這種線程和服務的區別是優先順序不同,如果記憶體不足,被銷毀的順序不同。而且即使服務所在進程被銷毀,如果記憶體充足會自動重新運行。有關Android進程內容參考:http://mobile.51cto.com/aprogram-459724.htm。
作為Android四大組件之一,Service只要繼承Service類,並在資訊清單檔中配置即可使用。
2、有兩種方式開啟Service,①使用startService();②使用bindService()。兩者的區別在於
①前者建立一個服務之後,就與這個服務沒有關聯了,因為沒有方法可以在擷取這個服務的執行個體了。但是進行聯絡還需要複雜的操作,並且還要區分進程內綁定本地服務和進程外綁定遠程服務
②通過綁定開啟的service,一旦調用這個服務的activity被銷毀則這個服務也被銷毀。即服務不能長期存在。
1 import android.app.Activity; 2 import android.content.ComponentName; 3 import android.content.Intent; 4 import android.content.ServiceConnection; 5 import android.os.Bundle; 6 import android.os.IBinder; 7 import android.view.View; 8 9 public class MainActivity extends Activity {10 private MyConn conn ;11 private IMiddlePerson mp;12 13 @Override14 protected void onCreate(Bundle savedInstanceState) {15 super.onCreate(savedInstanceState);16 setContentView(R.layout.activity_main);17 }18 19 @Override20 protected void onDestroy() {21 System.out.println("啊啊啊,我是activity,我掛了");22 super.onDestroy();23 }24 25 //綁定服務26 public void bind(View view){27 //3.activity採用綁定的方式去開啟服務。28 //啟用一個服務的意圖29 Intent intent = new Intent(this,MyService.class);30 //保持聯絡的連線物件31 conn = new MyConn();32 bindService(intent, conn, BIND_AUTO_CREATE);33 34 }35 //解除綁定服務36 public void unbind(View view){37 unbindService(conn);38 }39 40 private class MyConn implements ServiceConnection{41 //4. 當服務被串連的時候調用,服務被成功綁定的時候調用。IBinder就是綁定的Service的onBind()的傳回值,42 //!!!這就是聯絡所在43 @Override44 public void onServiceConnected(ComponentName name, IBinder service) {45 System.out.println("在activity裡面成功得到了中間人");46 mp = (IMiddlePerson) service;47 }48 //當服務失去串連的時候調用(一般進程掛了,服務被異常殺死)49 @Override50 public void onServiceDisconnected(ComponentName name) {51 52 }53 }54 55 //調用服務裡面的方法。56 public void call(View view){57 //5.通過中間人調用服務裡面的方法。58 mp.callMethodInService(55);59 }60 }調用方
1 import android.app.Service; 2 import android.content.Intent; 3 import android.os.Binder; 4 import android.os.IBinder; 5 import android.widget.Toast; 6 7 public class MyService extends Service { 8 9 //2.實現服務成功綁定的代碼 ,返回一個中間人(一個符合IBinder要求的類,這裡就是下面的內部類)。10 @Override11 public IBinder onBind(Intent arg0) {12 System.out.println("服務被成功綁定了。。。。");13 return new MiddlePerson();14 }15 16 @Override17 public boolean onUnbind(Intent intent) {18 System.out.println("onunbind");19 return super.onUnbind(intent);20 }21 22 @Override23 public void onCreate() {24 System.out.println("oncreate");25 super.onCreate();26 }27 28 @Override29 public int onStartCommand(Intent intent, int flags, int startId) {30 System.out.println("onstartcommand");31 return super.onStartCommand(intent, flags, startId);32 }33 34 @Override35 public void onDestroy() {36 System.out.println("ondestory");37 super.onDestroy();38 }39 40 /**41 * 這是服務裡面的一個方法42 */43 public void methodInService(){44 Toast.makeText(this, "哈哈,服務給你辦好了暫住證。", 0).show();45 }46 47 //1.第一步服務要暴露方法 必須要有一個中間人48 private class MiddlePerson extends Binder implements IMiddlePerson{49 /**50 * 代辦暫住證51 * @param money 給錢 50塊錢以上才給辦。52 */53 public void callMethodInService(int money){54 if(money>=50){55 methodInService();56 }else{57 Toast.makeText(getApplicationContext(), "多準備點錢。", 0).show();58 }59 }60 /**61 * 陪領導打麻將62 */63 public void playMajiang(){64 System.out.println("陪領導打麻將。");65 }66 }67 }service方
注意:上面的service方的中間人內部類是私人的,所以向外傳遞時不能直接將其拋出,所以在這裡使用了一個介面作為中轉,將需要暴露的方法通過介面暴露。
參考:http://blog.csdn.net/ryantang03/article/details/7770939。
3、除了可以綁定(這裡強調綁定是指有資料共用的情況,如果僅僅是啟用一個服務則不需要)自己寫的服務(同一個進程中),還可以繫結系統/他人寫的service。這就涉及到進程間通訊,在Android中的使用的是Binder方式實現的,而且提供了一個AIDL的輕量級實現方法。使用過程和上面類似,區別有2點:
①service方:對外暴露方法使用AIDL(Android介面定義語言)而不是java中的介面,區別是沒有修飾符,eclipse可以自動產生一個可用於進程間通訊的介面類(在/gen目錄下)
②調用方:在調用方的應用中也需要以同樣的方式建立AIDL檔案,然後通過 類名.Stub.asInterface(service) 來擷取中間對象。
4、混合調用服務:即同時使用綁定和start方式調用服務。這是為瞭解決兩種方式的缺點(start方式不能通訊,綁定方式不能長期存在)
三、Intent:可以理解為一種請求或意願,可以用來啟用Activity,Service和Broadcast Receiver,相應組件只要在配置中添加intent-filter即可擷取指定意圖。
意圖分兩種:顯,隱式意圖。區別在於前者通過建構函式的參數指定了具體的接收者,使用意圖過濾器過濾的就是隱式意圖,顯通常用於啟用自己的組件,而隱式意圖通常用於啟用他人的/系統的組件。
一個Intent可以設定動作(Action),資料(Data-->uri),類型(Type-->MIME),分類(Category),附加資訊(Extras),而通過過濾器匹配意圖就是需要進行三個匹配,一個是action,一個是category,一個是data,可以是全部或部分匹配。
參考:http://blog.csdn.net/think_soft/article/details/7330095,
http://blog.csdn.net/t12x3456/article/details/7688154,
http://fenglingdangyang.blog.sohu.com/231856618.html,
android學習筆記五