1、首先,讓咱們確認下什麼是service?
service就是android系統中的服務,它有這麼幾個特色:它沒法與用戶直接進行交互、它必須由用戶或者其餘程序顯式的啓動、它的優先級比較高, 它比處於前臺的應用優先級低,可是比後臺的其餘應用優先級高,這就決定了當系統由於缺乏內存而銷燬某些沒被利用的資源時,它被銷燬的機率很小哦。
2、那麼,何時,咱們須要使用service呢?
咱們知道,service是運行在後臺的應用,對於用戶來講失去了被關注的焦點。這就跟咱們打開了音樂播放以後,便想去看看圖片,這時候咱們還不想音樂停 止,這裏就會用到service;又例如,咱們打開了一個下載連接以後,咱們確定不想瞪着眼睛等他下載完再去作別的事情,對吧?這時候若是咱們想手機一邊 在後臺下載,一邊可讓我去看看新聞啥的,就要用到service。
3、service分類:
通常咱們認爲service分爲兩類, <!-- service配置結束-->
第三步:在activity中進行啓動、綁定、解綁或者中止service。
(不少書上說,service與用戶是不能交互的,其實這話很不正確,咱們徹底能夠經過activity與service進行交互!我認爲,確切的說法應該是service與用戶不能進行直接的交互)。android
-----------------------------安全
1、bindService簡介app
bindService是綁定Service服務,執行service服務中的邏輯流程。ide
service經過Context.startService()方法開始,經過Context.stopService()方法中止;也能夠經過Service.stopSelf()方法或者Service.stopSelfResult()方法來中止本身。只要調用一次stopService()方法即可以中止服務,不管以前它被調用了多少次的啓動服務方法。工具
客戶端創建一個與Service的鏈接,並使用此鏈接與Service進行通話,經過Context.bindService()方法來綁定服務,Context.unbindService()方法來關閉服務。多個客戶端能夠綁定同一個服務,若是Service還未被啓動,bindService()方法能夠啓動服務。學習
上面startService()和bindService()兩種模式是徹底獨立的。你能夠綁定一個已經經過startService()方法啓動的服務。例如:一 個後臺播放音樂服務能夠經過startService(intend)對象來播放音樂。可能用戶在播放過程當中要執行一些操做好比獲取歌曲的一些信息,此時 activity能夠經過調用bindServices()方法與Service創建鏈接。這種狀況下,stopServices()方法實際上不會中止 服務,直到最後一次綁定關閉。this
若是沒有程序中止它或者它本身中止,service將一直運行。在這種模式 下,service開始於調用Context.startService() ,中止於Context.stopService(). service能夠經過調用Android Service 生命週期() 或 Service.stopSelfResult()中止本身。無論調用多少次startService() ,只須要調用一次 stopService() 就能夠中止service。spa
能夠經過接口被外部程序調用。外部程序創建到service的鏈接,經過 鏈接來操做service。創建鏈接調開始於Context.bindService(), 結束於Context.unbindService(). 多個客戶端能夠綁定到同一個service,若是service沒有啓動, bindService() 能夠選擇啓動它。線程
這2種模式不是徹底分離的。你能夠能夠綁定到一個經過startService()啓動的服務。如 一個intent想要播放音樂,經過startService() 方法啓動後臺播放音樂的service。而後,也許用戶想要操做播放器或者獲取當前正在播放的樂曲的信息,一個activity就會經過 bindService()創建一個到此service的鏈接. 這種狀況下 stopService() 在所有的鏈接關閉後纔會真正中止service。code
2、bindService啓動流程
context.bindService() ——> onCreate() ——> onBind() ——> Service running ——> onUnbind() ——> onDestroy() ——> Service stop
onBind()將返回給 客戶端一個IBind接口實例,IBind容許客戶端回調服務的方法,好比獲得Service的實例、運行狀態或其餘操做。這個時候把調用者 (Context,例如Activity)會和Service綁定在一塊兒,Context退出了,Srevice就會調用 onUnbind->onDestroy相應退出。
因此調用bindService的生命週期爲:onCreate --> onBind(只一次,不可屢次綁定) --> onUnbind --> onDestory。
在Service每一次的開啓關閉過程當中,只有onStart可被屢次調用(經過屢次startService調用),其餘onCreate,onBind,onUnbind,onDestory在一個生命週期中只能被調用一次。
3、bindService生命週期
像一個activity那樣,一個service有些能夠用來改變狀態的生命週期方法,可是比activity的方法少,service生命週期方法只有三個public
void onCreate()
void onStart(Intent intent)
void onDestroy()
經過實現這三個生命週期方法,你能夠監聽service的兩個嵌套循環的生命週期:
一、整個生命週期
service 的整個生命週期是在onCreate()和onDestroy()方法之間。和activity同樣,在onCreate()方法裏初始化,在 onDestroy()方法裏釋放資源。例如,一個背景音樂播放服務能夠在onCreate()方法裏播放,在onDestroy()方法裏中止。
二、活動的生命週期
service 的活動生命週期是在onStart()以後,這個方法會處理經過startServices()方法傳遞來的Intent對象。音樂service能夠通 過開打intent對象來找到要播放的音樂,而後開始後臺播放。注: service中止時沒有相應的回調方法,即沒有onStop()方法,只有onDestroy()銷燬方法。
任何服務不管它怎樣創建,默認客戶端均可以鏈接,因此任何service都可以接收onBind()和onUnbind()方法
onCreate()方法和onDestroy()方法是針對全部的services,不管它們是否啓動,經過Context.startService()和Context.bindService()方法均可以訪問執行。然而,只有經過startService()方法啓動service服務時纔會調用onStart()方法。
若是一個service容許別人綁定,那麼須要實現如下額外的方法:
IBinder onBind(Intent intent)
boolean onUnbind(Intent intent)
void onRebind(Intent intent)
onBind()回調方法會繼續傳遞經過bindService()傳遞來的intent對象
onUnbind()會處理傳遞給unbindService()的intent對象。若是service容許綁定,onBind()會返回客戶端與服務互相聯繫的通訊句柄(實例)。
若是創建了一個新的客戶端與服務的鏈接,onUnbind()方法能夠請求調用onRebind()方法。
4、bindService和startservice示例
(1)mainactivity
public class MainActivity extends Activity { Button startServiceButton;// 啓動服務按鈕 Button shutDownServiceButton;// 關閉服務按鈕 Button startBindServiceButton;// 啓動綁定服務按鈕 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getWidget(); regiestListener(); } /** 得到組件 */ public void getWidget() { startServiceButton = (Button) findViewById(R.id.startServerButton); startBindServiceButton = (Button) findViewById(R.id.startBindServerButton); shutDownServiceButton = (Button) findViewById(R.id.sutdownServerButton); } /** 爲按鈕添加監聽 */ public void regiestListener() { startServiceButton.setOnClickListener(startService); shutDownServiceButton.setOnClickListener(shutdownService); startBindServiceButton.setOnClickListener(startBinderService); } /** 啓動服務的事件監聽 */ public Button.OnClickListener startService = new Button.OnClickListener() { public void onClick(View view) { /** 單擊按鈕時啓動服務 */ Intent intent = new Intent(MainActivity.this, CountService.class); startService(intent); Log.v("MainStadyServics", "start Service"); } }; /** 關閉服務 */ public Button.OnClickListener shutdownService = new Button.OnClickListener() { public void onClick(View view) { /** 單擊按鈕時啓動服務 */ Intent intent = new Intent(MainActivity.this, CountService.class); /** 退出Activity是,中止服務 */ stopService(intent); Log.v("MainStadyServics", "shutDown serveice"); } }; /** 打開綁定服務的Activity */ public Button.OnClickListener startBinderService = new Button.OnClickListener() { public void onClick(View view) { /** 單擊按鈕時啓動服務 */ Intent intent = new Intent(MainActivity.this, UseBrider.class); startActivity(intent); Log.v("MainStadyServics", "start Binder Service"); } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }
(2)service
package com.example.testservice; /**引入包*/ import android.app.Service;// 服務的類 import android.os.IBinder; import android.os.Binder; import android.content.Intent; import android.util.Log; /** 計數的服務 */ public class CountService extends Service { /** 建立參數 */ boolean threadDisable; int count; public IBinder onBind(Intent intent) { return null; } public void onCreate() { super.onCreate(); /** 建立一個線程,每秒計數器加一,並在控制檯進行Log輸出 */ new Thread(new Runnable() { public void run() { while (!threadDisable) { try { Thread.sleep(1000); } catch (InterruptedException e) { } count++; Log.v("CountService", "Count is" + count); } } }).start(); } public void onDestroy() { super.onDestroy(); /** 服務中止時,終止計數進程 */ this.threadDisable = true; } public int getConunt() { return count; } //此方法是爲了能夠在Acitity中得到服務的實例 class ServiceBinder extends Binder { public CountService getService() { return CountService.this; } } }
(3)bindservice(必定要記着這個是要得到,連接的對象)
package com.example.testservice; /**引入包*/ import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; /** 經過bindService和unBindSerivce的方式啓動和結束服務 */ public class UseBrider extends Activity { /** 參數設置 */ CountService countService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new UseBriderFace(this)); Intent intent = new Intent(UseBrider.this, CountService.class); /** 進入Activity開始服務 */ bindService(intent, conn, Context.BIND_AUTO_CREATE); } private ServiceConnection conn = new ServiceConnection() { /** 獲取服務對象時的操做 */ public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub countService = ((CountService.ServiceBinder) service).getService(); } /** 沒法獲取到服務對象時的操做 */ public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub countService = null; } }; protected void onDestroy() { super.onDestroy(); this.unbindService(conn); Log.v("MainStadyServics", "out"); } }
注意:這個地方有朋友可能會出現onServiceConnected不調用的狀況。
這個問題當調用bindService方法後就會回調Activity的onServiceConnected,在這個方法中會向Activity中傳遞一個IBinder的實例,Acitity須要保存這個實例
在Service中須要建立一個實現IBinder的內部類(這個內部類不必定在Service中實現,但必須在Service中建立它)。
在OnBind()方法中需返回一個IBinder實例,否則onServiceConnected方法不會調用。
不過,我在這裏傳遞null也可以調用,你們根據狀況進行斷定吧,若是是返回一個ibinder實例的話,示例代碼以下:
public IBinder onBind(Intent intent) { // TODO Auto-generated method stub System.out.println("onBind....."); IBinder result = null; if ( null == result ) result = new MyBinder() ; Toast.makeText(this, "onBind",Toast.LENGTH_LONG); return result; }
至於startservice和bindservice的使用場景,有網友這麼說:
1.經過startservice開啓的服務.一旦服務開啓, 這個服務和開啓他的調用者之間就沒有任何的關係了.
調用者不能夠訪問 service裏面的方法. 調用者若是被系統回收了或者調用了ondestroy方法, service還會繼續存在
2.經過bindService開啓的服務,服務開啓以後,調用者和服務之間 還存在着聯繫 ,
一旦調用者掛掉了.service也會跟着掛掉 .
示例下載地址:http://pan.baidu.com/share/link?shareid=1614272126&uk=1428765741
還有一個多樣化的demo學習地址:http://pan.baidu.com/share/link?shareid=1616100229&uk=1428765741
內容來源於互聯網,感謝做者的無私提供