1. 程式人生 > >如何將service與activity繫結

如何將service與activity繫結

一、

service的簡單使用就不詳細展開了。只做一點兒討論以解釋為什麼要繫結activity。

service是不可見的,它的啟動、停止和其他控制操作都是通過其他應用程式元件來實現的。

比如最簡單的就是在activity中使用startService()來啟動一個服務,使其在後臺執行。但如果僅僅是這樣的話,我們啟動一個service後就只能看著它在後臺執行卻不能對其進行任何操作了。如果想在activity中能夠操作service(呼叫其中的某些方法,讓其完成某些動作),我們就必須先把activity和service繫結起來。

二、如何繫結activity和service?這需要我們實現service中的onBind()函式以返回service例項給activity

1、首先是建立service類和activity類。

2、在service類中   

定義一個內部類繼承自Binder類:

  1. publicclass MyBinder extends Binder{  
  2.         public Service1 getService(){  
  3.             return Service1.this;  
  4.         }  
  5.     }  

例項化onBind()方法:

privatefinal IBinder binder = new MyBinder();  

  1.  @Override
  2.     public IBinder onBind(Intent intent) {  
  3.         Log.i(LOG, "onBind............");  
  4.         return binder;  
  5.     } 

3、在activity中完成繫結

  1. Intent intent = new Intent(Activity1.this,Service1.class);  
  2.         bindService(intent, conn, Context.BIND_AUTO_CREATE);  

1)、    注意到bindService的第二個引數是一個ServiceConnection型別的引數。service和其他元件之間的連線都表示為一個ServiceConnection,要想將service和其他元件進行繫結,就需要實現一個新的ServiceConnection。

所以應該在activity中定義一個內部類

  1. public ServiceConnection conn= new ServiceConnection() {  
  2.         @Override
  3.         publicvoid onServiceDisconnected(ComponentName name) {  
  4. //當連線意外斷開時呼叫
  5.             Log.i(LOG, "onServiceDisconnected>>>>>>>>");  
  6.             myservice = null;  
  7.         }  
  8.         @Override
  9.         publicvoid onServiceConnected(ComponentName name, IBinder service) {  
  10. //當建立連線時呼叫
  11.             Log.i(LOG, "onServiceConnected>>>>>>>>");  
  12. myservice = ((Service1.MyBinder)service).getService();  
  13.         }  
  14.     };   

這裡的myservice就是我們獲取到的已經繫結的service的例項。

2)、  bindService的第三個引數是一個flag。

   可以使用的flag有:

BIND_AUTO_CREATE:繫結完成後就啟動目標service

BIND_DEBUG_UNBIND:這隻在debug時使用,跟unbind有關。

BIND_NOT_FOREGROUND:確保被繫結的service永遠不會有運行於前臺的優先順序,因為預設情況下,繫結一個service會提高它的優先順序

BIND_ABOVE_CLIENT:確保客戶端處於前臺時,繫結的service也變為前臺程序

BIND_ALLOW_OOM_MANAGEMENT:允許系統在低記憶體等狀態下刪除該service(這是自己對原始碼中註釋的理解)

BIND_WAIVE_PRIORITY:繫結service時不改變其優先順序

BIND_ADJUST_WITH_ACTIVITY:系統根據service所繫結的activity的重要程度來調整這個service的優先順序。

三、關於service的生命週期的討論(轉載,http://www.cnblogs.com/yydcdut/p/3961545.html)

1.    被啟動的服務(startService())的生命週期。
             如果一個Service被某個Activity 調用Context.startService() 方法啟動,那麼不管是否有Activity使用bindService()繫結或unbindService()解除繫結到該Service,該Service都在後臺執行。如果一個Service被多次執行startService(),它的onCreate()方法只會呼叫一次,也就是說該Service只會建立一個例項,而它的onStartCommand()將會被呼叫多次(對應呼叫startService()的次數)。該Service將會一直在後臺執行,直到被呼叫stopService(),或自身的stopSelf方法。當然如果系統資源不足,系統也可能結束服務。
2.    被繫結的服務(bindService())的生命週期。
             如果一個Service被呼叫 Context.bindService ()方法繫結啟動,不管呼叫bindService()呼叫幾次,onCreate()方法都只會呼叫一次,而onStartCommand()方法始終不會被呼叫,這時會呼叫onBind()方法。當連線建立之後,Service將會一直執行,除非呼叫Context.unbindService() 斷開連線或者之前呼叫bindService() 的 Context 不存在了(如該Activity被finish),系統將會自動停止Service,對應onDestroy()將被呼叫。
3.    被啟動又被繫結的服務的生命週期。
如果一個Service又被啟動又被繫結,則該Service將會一直在後臺執行。呼叫unbindService()將不會停止Service,而必須呼叫stopService()或Service的stopSelf()方法來停止服務。
4.   當服務被停止時清除服務。
            當一個Service被終止時,Service的onDestroy()方法將會被呼叫,在這裡應當做一些清除工作,如停止在Service中建立並執行的執行緒等。