服務 服務的生命周期 --- 1 開啟服務的生命周期 完整的生命周期:onCreate()-->onStartCommand()-->onDestroy() * 開啟服務:onCreate()-->onStartCommand() * 停止服務:onDestroy() * 特點: 1. 服務可以被多
服務
服務的生命周期
---
1 開啟服務的生命周期
完整的生命周期:onCreate()-->onStartCommand()-->onDestroy()
* 開啟服務:onCreate()-->onStartCommand()
* 停止服務:onDestroy()
* 特點:
1. 服務可以被多次開啟,每次開啟都執行onStartCommand()方法
2. 服務只能被停止一次,多次停止服務
3. 長期運行在後臺
2 bind綁定服務的生命周期
完整的生命周期:onCreate()-->onBind()-->onUnbind()-->onDestroy()
* 綁定服務:onCreate()-->onBind()
* 解綁服務:onUnbind()-->onDestroy()
* 特點:
1. 服務只能被綁定一次,多次綁定無效
2. 服務只能被解綁一次,多次解綁會拋出異常
3. 不可以長期運行在後臺
4. Activity和綁定他的服務同生共死
5. 可以調用服務里的方法
* 區別: 1. 能不能長期運行在後臺
2. 能不能調用服務里的方法
綁定服務調用方法
---
3 綁定服務調用服務里的方法
服務被綁定成功後,拿到服務返回的中間人,用中間人間接調用服務里的方法
Activity:
1 /** 2 * bind方式綁定服務 3 */ 4 public void bind(View v) { 5 /** 6 * service :意圖 ServiceConnection:Activity和service連接通道 7 * BIND_AUTO_CREATE:綁定服務時,如果服務不存在,則創建 8 */ 9 Log.d(TAG, "bind:1. 綁定服務"); 10 conn = new MyConn(); 11 bindService(intent, conn, BIND_AUTO_CREATE); 12 } 13 14 /** 15 * 解綁服務 16 */ 17 public void unbind(View v) { 18 19 Log.d(TAG, "unbind:服務被解綁啦。。。"); 20 unbindService(conn); 21 } 22 23 /** 24 * 調用服務里的方法 25 * 26 */ 27 public void diao(View v) { 28 29 xiaowu.qianShouMM(99999); 30 Log.d(TAG, "diao:6. 用服務的內部類間接調用服務里的方法"); 31 } 32 33 class MyConn implements ServiceConnection { 34 35 // Activity和service已經連接成功嘍 36 @Override 37 public void onServiceConnected(ComponentName name, IBinder service) { 38 39 Log.d(TAG, "onServiceConnected:4. 服務連接成功了"); 40 xiaowu = (WuMiShu) service; 41 Log.d(TAG, "onServiceConnected:5. 在Activity中拿到了服務里的內部類"); 42 } 43 44 // 失去連接了 45 @Override 46 public void onServiceDisconnected(ComponentName name) { 47 48 Log.d(TAG, "onServiceDisconnected: 失去連接了..."); 49 } 50 } 51 52 @Override 53 protected void onDestroy() { 54 55 unbindService(conn); 56 super.onDestroy(); 57 }
Service:
1 /** 2 * 服務里的方法 3 */ 4 public void methodInService() { 5 6 Toast.makeText(this, "我是服務里的方法,來弔我啊。。。", 0).show(); 7 } 8 9 @Override 10 public IBinder onBind(Intent intent) { 11 12 Log.d(TAG, "onBind:2. 服務被綁定成功嘍"); 13 Log.d(TAG, "onBind 3. 服務綁定成功後,返回WuMiShu"); 14 return new WuMiShu(); 15 } 16 17 /** 18 * 服務里的內部類, 內部類調用外部類的方法 中間人 小蜜 19 */ 20 public class WuMiShu extends Binder { 21 22 /** 23 * 調用外部類的方法 24 * 25 * @param money 26 */ 27 public void qianShouMM(int money) { 28 29 if (money > 5000) { 30 methodInService(); 31 } else { 32 Toast.makeText(MyService.this, "屌絲註定單身", 0) 33 .show(); 34 } 35 } 36 } 37 38 @Override 39 public boolean onUnbind(Intent intent) { 40 41 Log.d(TAG, "onUnbind:"); 42 return super.onUnbind(intent); 43 } 44 45 @Override 46 public void onCreate() { 47 48 super.onCreate(); 49 Log.d(TAG, "onCreate:"); 50 } 51 52 @Override 53 public int onStartCommand(Intent intent, int flags, int startId) { 54 55 Log.d(TAG, "onStartCommand:"); 56 return super.onStartCommand(intent, flags, startId); 57 } 58 59 @Override 60 public void onDestroy() { 61 62 super.onDestroy(); 63 Log.d(TAG, "onDestroy:"); 64 }
4 綁定服務抽取介面
隱藏具體的實現細節,只暴露程式員想暴露的方法
1. 寫一個介面,介面里寫一個方法
2. 讓服務的內部類ChenMiShu實現IService介面
3. 當Activity這邊連接成功後,Binder強轉成IService介面類型
4. 用IService介面間接調用服務里的方法
5 混合方式開啟服務
為什麼要用混合方式啟動服務:即想服務長期運行在後臺,又想調用服務里的方法
開發中推薦的步驟:startService()保證服務長期運行在後臺
bindService()可以調用服務里的方法
unBindService()解除綁定服務
*** stopService()後臺是沒有這個服務了
遠程服務
---
6 本地服務和遠程服務
* 本地服務:服務組件在自己的應用程式里
* 遠程服務:服務組件不在自己的應用程式里
7 本地應用調用遠程服務中的方法
AIDL:android interface defination language 安卓介面定義語言
編寫步驟:
遠程服務工程:
1. 把IService.java改成.aidl文件
2. 去掉public 修飾符
3. 讓服務里的內部類繼承IService.Stub
Service:
1 @Override 2 public IBinder onBind(Intent intent) { 3 Log.d(TAG, "onBind"); 4 return new ChenMiShu(); 5 } 6 /** 7 * 陳秘書 8 */ 9 class ChenMiShu extends IService.Stub{ 10 11 @Override 12 public void callMethodInRemoteService() { 13 qianShouYangNiu(); 14 } 15 16 } 17 18 /** 19 * 遠程服務里的方法 20 */ 21 public void qianShouYangNiu(){ 22 Log.e(TAG, "qianShouYangNiu:我來了,你在哪?我在美國,咱們中間隔著一個太平洋...."); 23 }
IService.aidl
1 interface IService { 2 3 /** 4 * 調用遠程服務里 的方法 5 */ 6 void callMethodInRemoteService(); 7 }
本地應用:
4. 創建一個和遠程服務.aidl文件所在的一樣包
5. 吧06工程里的IService.aidl文件複製到這個包里
6. 用IService.Stub.asInterface(service)強轉成IService
7. 間接調用遠程服務了的方法,處理RemoteException
Activity:
1 /** 2 * start開啟服務 3 * 4 * @param v 5 */ 6 public void start(View v) { 7 intent = new Intent(); 8 // 設置動作 9 intent.setAction("wo.kan.dai.ma.ru.chu.lian"); 10 // 可選,設置數據 11 // 預設是DEFAULT,可以不寫 12 startService(intent); 13 } 14 15 /** 16 * stop停止服務 17 * 18 * @param v 19 */ 20 public void stop(View v) { 21 stopService(intent); 22 } 23 24 /** 25 * bind綁定服務 26 * 27 * @param v 28 */ 29 public void bind(View v) { 30 Intent service = new Intent(); 31 // 設置動作 32 service.setAction("wo.kan.dai.ma.ru.chu.lian"); 33 34 mConn = new MyConn(); 35 bindService(service, mConn, BIND_AUTO_CREATE); 36 } 37 38 /** 39 * Activity和遠程服務里的連接通道 40 */ 41 class MyConn implements ServiceConnection { 42 @Override 43 public void onServiceConnected(ComponentName name, IBinder service) { 44 Log.d(TAG, "onServiceConnected:連接成功"); 45 // service強轉成 IService介面類型 46 mService = IService.Stub.asInterface(service); 47 } 48 49 @Override 50 public void onServiceDisconnected(ComponentName name) { 51 } 52 53 } 54 55 /** 56 * 解綁服務 57 * 58 * @param v 59 */ 60 public void unbind(View v) { 61 unbindService(mConn);