Service

Service的生命週期

  • void onCreate(),當service第一次被創建後調用的方法
  • void onStartCommand(Intent intent, int flags, int startId),每次調用startService(Intent )啓動service時都會調用該方法
  • IBinder onBind(Intent intent),service子類必須實現的方法,應用程序通過該方法返回的IBinder對象與service通信
  • boolean onUnbind(Intent intent),當service上綁定的所有客戶端都斷開連接時該方法被調用
  • void onDestroy(),當service被關閉前調用該方法

Service的配置

<service android:name=".ServiceClassName">
    <intent-filter>
            <action..../>
    </intent-filter>
</service>



啓動Service的方式

  • 通過Context的startService(Intent )啓動service
  1. 該啓動方式service與任何客戶端無關聯,service將獨立運行(無法調用服務中的方法)
  2. 多次啓動service會重複調用onStartCommand()方法
  3. 關閉service應該調用Context.stopService(Intent )
  4. 該方法下的生命週期:onCreate()->onStartCommand()->onDestroy()
  5. 只要服務被啓動了,無論調用多少次startService()都不會再創建新服務

  • 通過Context的bindService(Intent, ServiceConnetction, int )綁定客戶端與service,並啓動service
  1. 該啓動方式service將與客戶端綁定,當所有客戶端斷開綁定時,service將調用onUnbind()方法,之後將銷燬service(onDestroy()方法被調用)
  2. 多次綁定service不會重複調用onBind(),onBind()只會執行一次
  3. 關閉service應該調用Context.unbindService(ServiceConnection )
  4. 該方法下的生命週期:onCreate()->onBind()->onUnbind()->onDestroy()

  • 特殊情況:
  1. 當程序通過startService()啓動service,其它客戶端通過bindService()調用service時,使用unbindService()解除綁定後再重新綁定可以觸發以下的生命週期:
  2. onCreate->onStartCommand()->onBind()->onUnbind()->onRebind()
  3. 以上方式並不會銷燬service,因爲service是通過startService()啓動的,必須通過stopService()關閉(unbindService()只是取消應用程序與service中的IBinder對象的關聯而已)
  4. 如果要觸發onRebind(),必須是startService()方式啓動,而且onUnbind()的返回值必須爲true

綁定service調用服務

繼承並創建相關的service類,重寫onBind()方法(返回IBinder對象)實現ServiceConnection接口,並重寫onServiceConnected()與onServiceDisconnected()方法調用Context.bindService(Intent, ServiceConnection, int )方法,指定service啓動的模式,綁定客戶端與服務
//創建service類,class MyService extends Service{};
//創建serviceConnection類,class MyServiceConnection implements ServiceConnection{};
//綁定服務
Intent service=new Intent(this, MyService.Class);
//指定啓動模式爲綁定時自動創建新service對象
bindService(service, new MyServiceConnection, Service.BIND_AUTO_CREATE);



Service與IntentService

  • Service的特點:
  1. service不會專門啓動一條單獨的進程,所在的進程與應用位於同一進程中
  2. service不是新線程,在service中進行耗時處理跟在主線程中處理一樣(可能產生ANR錯誤)

  • IntentService(只需要重寫onHandleIntent())的特點:
  1. intentService會創建單獨的worker線程處理所有的intent請求
  2. intentService會創建單獨的worker線程來處理onHandleIntent()方法實現的代碼
  3. 處理完所有的請求後intentService會自動停止
  4. 爲service的onBind()提供了默認的返回值null
  5. 爲service的onStartCommand()方法提供默認的實現,將請求的intent添加到隊列中

AIDL Service

  • AIDL Service用於調用遠程服務,進行不同進程之間的服務通信

  • 創建AIDL文件的注意點:
  1. AIDL文件的後綴必須以.aidl結尾,接口名與文件名應該相同
  2. AIDL文件中的接口與方法不應該添加修飾符(public/private/protected/final/static等)
  3. AIDL默認運行Java中的基本類型,使用這些類型不需要import聲明;使用List和Map中的元素必須是AIDL運行的類型
  4. 如果使用自定義類型,必須進行顯式import聲明,並且自定義類型必須實現Parcelable接口
  5. AIDL文件中所有非Java基本類型參數必須加上in/out/inout標記,用於指明參數是輸入參數,輸出參數還是輸入輸出參數
  6. Java基本類型默認標記爲in,不能使用其它標記

  • 服務端:
//創建AIDL文件(系統自動生成相應的類文件)
interface MyAIDLClass{};
//系統將自動生成MyAIDLClass.java
//服務繼承service實現相應的類
class MyService extends Service{};
//創建類內部的IBinder接口對象(繼承系統生成的AIDL類文件)
//必須繼承自Class.Stub,不能直接繼承AIDL類文件
class MyBinder extends MyAIDLClass.Stub{};



  • 客戶端:
//使用與服務端相同的AIDL文件(系統自動生成相應的類文件)
interface MyAIDLClass{};
//將service返回的IBinder對象轉換成對應的AIDL類對象
//必須使用系統生成的方法轉換實例Class.Stub.asInstance()
MyAIDLClass instance=MyAIDLClass.Stub.asInstance(IBinder );
//通過IBinder對象調用服務


發佈了49 篇原創文章 · 獲贊 14 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章