Service是安卓四大組件之一,先前講到了Service的生命週期,以及非綁定類型的生命週期的例子,這次來分享一下綁定形式的。 應用組件(用戶端)可以調用bindService()綁定到一個service。Android系統之後調用service的onBind()方法,它返回一個用來與service互動的IBinder。 綁定是非同步,bindService()會立即返回,它不會返回IBinder給用戶端。要接收IBinder,用戶端必須建立一個ServiceConnection的執行個體並傳給bindService()。ServiceConnection包含一個回調方法,系統調用這個方法來傳遞要返回的IBinder。 實現ServiceConnection 實現必須重寫兩個回調方法: onServiceConnected() 系統調用這個來傳送在service的onBind()中返回的IBinder。 OnServiceDisconnected() Android系統在同service的串連意外丟失時調用這個.比如當service崩潰了或被強殺了.當用戶端解除綁定時,這個方法不會被調用。 調用bindService(),傳給它ServiceConnection的實現。 當系統調用你的onServiceConnected()方法時,你就可以使用介面定義的方法們開始調用service了。 要與service中斷連線,調用unbindService()。 程式 複製代碼public class MainActivity extends Activity { private Button btn_start; private Button btn_stop; private Button btn_change; private Button btn_bind; private Button btn_unbind; private MyConn myConn; private IService myBinder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_start = (Button) findViewById(R.id.btn_start); btn_stop = (Button) findViewById(R.id.btn_stop); btn_change = (Button) findViewById(R.id.btn_change); btn_bind = (Button) findViewById(R.id.btn_bind); btn_unbind = (Button) findViewById(R.id.btn_unbind); buttonListener bl = new buttonListener(); btn_change.setOnClickListener(bl); btn_start.setOnClickListener(bl); btn_stop.setOnClickListener(bl); btn_bind.setOnClickListener(bl); btn_unbind.setOnClickListener(bl); } class buttonListener implements OnClickListener { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_start: Intent intent_start = new Intent(getApplicationContext(),BindService.class); startService(intent_start); break; case R.id.btn_stop: Intent intent_stop = new Intent(getApplicationContext(),BindService.class); stopService(intent_stop); break; case R.id.btn_change: if(myBinder != null) myBinder.doChange("啦啦啦"); break; case R.id.btn_bind: if(myConn == null) { myConn = new MyConn(); Intent intent_bind = new Intent(getApplicationContext(),BindService.class); bindService(intent_bind, myConn, BIND_AUTO_CREATE); } break; case R.id.btn_unbind: Intent intent_unbind = new Intent(getApplicationContext(),BindService.class); if(myConn != null && myBinder != null) { unbindService(myConn); myConn = null; myBinder = null; } break; default: break; } } } private class MyConn implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { System.out.println("代理人返回回來了,onServiceConnected"); myBinder = (IService) service; } @Override public void onServiceDisconnected(ComponentName name) { System.out.println("接觸綁定了,onServiceDisconnected"); } } }複製代碼Service類: 複製代碼public class BindService extends Service { @Override public IBinder onBind(Intent intent) { System.out.println("Service綁定成功,onBind"); //返回自訂的代理對象 return new MyBinder();//這裡的返回是返回到MainActivity裡面的綁定myConn } @Override public boolean onUnbind(Intent intent) { System.out.println("Service解除綁定成功,onUnbind"); return super.onUnbind(intent); } public class MyBinder extends Binder implements IService { //間接的利用代理人調用了changeServiceThing的方法 public void doChange(String what) { changeServiceThing(what); } } @Override public void onCreate() { System.out.println("Service開啟,onCreate"); super.onCreate(); } @Override public void onDestroy() { System.out.println("Service關閉,onDestroy"); super.onDestroy(); } public void changeServiceThing(String what) { Toast.makeText(getApplicationContext(), what+"變換了,changeServiceThing", Toast.LENGTH_LONG).show(); } }複製代碼IService: public interface IService { public void doChange(String what);}結果 點擊“開啟服務”之後,再“綁定服務”,這樣執行之後直接點“關閉服務”是沒用的,要先“解除服務”,再“關閉服務”。如果直接“綁定服務”,那麼點擊“關閉服務”沒有用,需要點擊“解除綁定服務”。 aidl 處理序間通訊->調用者和Service如果不在一個進程內,就需要使用android中的遠程Service調用機制。 android使用AIDL定義進程間的通訊介面。AIDL的文法與java介面類似,需要注意以下幾點: AIDL檔案必須以.aidl作為尾碼名。AIDL介面中用到的資料類型, 除了基本類型, String, List, Map, CharSequence之外, 其他類型都需要導包, 即使兩種在同一個包內. List和Map中的元素類型必須是AIDL支援的類型。介面名需要和檔案名稱相同。方法的參數或傳回值是自訂類型時, 該自訂的類型必須實現了Parcelable介面。所有非java基本型別參數都需要加上in, out, inout標記, 以表明參數是輸入參數, 輸出參數, 還是輸入輸出參數。介面和方法前不能使用存取修飾詞和static, final等修飾。處理序間通訊需要建立aidl檔案,IService.aidl: public interface IService { public void doChange(String what);}介面中有一個static的抽象內部類Stub,Stub類繼承了Binder類並實現了IRemoteService介面。 複製代碼public class MainActivity extends Activity { private Intent intent; private IService iService; private ServiceConnection myConn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void bind(View view) { intent = new Intent(); intent.setAction("com.yydcdut.alipay"); myConn = new MyConn(); boolean flag = bindService(intent, myConn, BIND_AUTO_CREATE); System.out.println("flag------>" + flag); } private class MyConn implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { iService = IService.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } } public void method(View view) { try { iService.callMethodInService(); } catch (RemoteException e) { // TODO 自動產生的 catch 塊 e.printStackTrace(); } } }