第7章Android后臺服務(wù)_第1頁
第7章Android后臺服務(wù)_第2頁
第7章Android后臺服務(wù)_第3頁
第7章Android后臺服務(wù)_第4頁
第7章Android后臺服務(wù)_第5頁
已閱讀5頁,還剩42頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、第第7章章 后臺服務(wù)后臺服務(wù)7.1 Service簡介 nServiceqService是Android系統(tǒng)的服務(wù)組件,適用于開發(fā)沒有用戶界面且長時間在后臺運行的應用功能。q因為手機硬件性能和屏幕尺寸的限制,通常Android系統(tǒng)僅允許一個應用程序處于激活狀態(tài)并顯示在手機屏幕上,而暫停其他處于未激活狀態(tài)的程序。q因此,Android系統(tǒng)提供了一種后臺服務(wù)機制,允許在沒有用戶界面的情況下,使程序能夠長時間在后臺運行,實現(xiàn)應用程序的后臺服務(wù)功能,并能夠處理事件或數(shù)據(jù)更新。7.1 Service簡介 nServiceqAndroid系統(tǒng)提供的Service(服務(wù))組件,不直接與用戶進行交互,能夠長期

2、在后臺運行。q在實際應用中,很多應用使用Service,如音頻播放器,軟件需要在關(guān)閉播放器界面后,仍能夠保持音樂持續(xù)播放,這就需要在Service組件中實現(xiàn)音樂播放功能7.1 Service簡介 nService qService適用于無需用戶干預,長期運行的后臺功能nService沒有用戶界面,有利于降低系統(tǒng)資源的消耗nService比Activity具有更高的優(yōu)先級,因此在系統(tǒng)資源緊張時,Service不會被Android系統(tǒng)優(yōu)先終止n即使Service被系統(tǒng)終止,在系統(tǒng)資源恢復后Service也將自動恢復運行狀態(tài),因此可以認為Service是在系統(tǒng)中永久運行的組件qService除了實現(xiàn)

3、后臺服務(wù)功能,還可以用于進程間通信(Inter Process Communication,IPC),解決不同Android應用程序進程之間的調(diào)用和通訊問題 7.1 Service簡介 nService生命周期qService生命周期包括n完全生命周期: onCreate()開始到OnDestroy()結(jié)束。n活動生命周期: onStartCommand()/onStart()開始到OnDestroy()結(jié)束。onCreate() : Service的生命周期開始,完成Service的初始化工作。onStartCommand()/onStart() :活動生命周期開始,執(zhí)行的操作。 (onSt

4、art() 在Android2之后已經(jīng)不再使用)onDestroy() :Service的生命周期結(jié)束,釋放Service所有占用的資源。7.1 Service簡介 nService生命周期nService的使用方式一般有兩種q啟動方式 :使用startService()方法啟用服務(wù)后,調(diào)調(diào)用者與服務(wù)之間沒有關(guān)連用者與服務(wù)之間沒有關(guān)連。調(diào)用者直接退出而沒有調(diào)用stopService的話,Service會一直在后臺運行。下次調(diào)用者啟動仍然可以繼續(xù)調(diào)用Service 。q綁定方式: 使用bindService()方法啟用服務(wù),調(diào)用者調(diào)用者與服務(wù)綁定在一起了與服務(wù)綁定在一起了,調(diào)用者一旦退出,服務(wù)也

5、就自動終止。7.1 Service簡介 n啟動方式q通過調(diào)用Context.startService()啟動Service,通過調(diào)用Context.stopService()或Service.stopSelf()停止Service。因此,Service一定是由其它的組件啟動的,但停止過程可以通過其它組件或自身完成q在啟動方式中,啟動在啟動方式中,啟動ServiceService的組件不能夠獲取到的組件不能夠獲取到ServiceService的對象實例,因此無法調(diào)用的對象實例,因此無法調(diào)用ServiceService中的任何函數(shù),也不能中的任何函數(shù),也不能夠獲取到夠獲取到ServiceServi

6、ce中的任何狀態(tài)和數(shù)據(jù)信息中的任何狀態(tài)和數(shù)據(jù)信息q能夠以啟動方式使用的Service,需要具備自管理的能力,而且不需要從通過函數(shù)調(diào)用獲取Service的功能和數(shù)據(jù) q啟動流程:n如果調(diào)用前服務(wù)沒有被創(chuàng)建,則會引起onCreate()- onStartCommand();n如果已被創(chuàng)建,則多次調(diào)用startService只會引起onStartCommand()被多次調(diào)用。7.1 Service簡介 n綁定方式q調(diào)用者調(diào)用者( (綁定綁定ServiceService的組件的組件) )可以調(diào)用可以調(diào)用ServiceService中實現(xiàn)的函數(shù),中實現(xiàn)的函數(shù),或直接獲取或直接獲取ServiceServi

7、ce中的狀態(tài)和數(shù)據(jù)信息中的狀態(tài)和數(shù)據(jù)信息q調(diào)用者通過Context.bindService()建立服務(wù)鏈接,通過Context.unbindService()停止服務(wù)鏈接。q如果在綁定過程中Service沒有啟動,Context.bindService()會自動啟動Service,而且同一個Service可以綁定多個服務(wù)鏈接,這樣可以同時為多個不同的組件提供服務(wù)。q啟動流程:n如果調(diào)用前服務(wù)沒被創(chuàng)建,則會引起onCreate()- onStartCommand();n如果已被創(chuàng)建,則多次調(diào)用startService只會只會引起onStartCommand()被多次調(diào)用。q結(jié)束方式:n只能調(diào)用C

8、ontext.stopService()結(jié)束服務(wù),系統(tǒng)會自動調(diào)用到onDestroy()方法。7.1 Service簡介 n啟動方式和綁定方式的結(jié)合q這兩種使用方法并不是完全獨立的,在某些情況下可以混合使用n如音樂播放器,后臺工作的Service通過Context.startService()啟動某個音樂播放,但在播放過程中如果用戶需要暫停音樂播放,則需要通過Context.bindService()獲取服務(wù)鏈接和Service對象實例,進而通過調(diào)用Service對象實例中的函數(shù),暫停音樂播放過程,并保存相關(guān)信息 n在這種情況下,如果調(diào)用Context.stopService()并不能夠停止S

9、ervice,需要在所有的服務(wù)鏈接關(guān)閉后,Service才能夠真正的停止。7.2 本地服務(wù)n本地服務(wù)的調(diào)用者和服務(wù)都在同一個程序中,是不需要跨進程就可以實現(xiàn)服務(wù)的調(diào)用n本地服務(wù)涉及服務(wù)的建立、啟動和停止,服務(wù)的綁定和取消綁定,以及如何在線程中實現(xiàn)服務(wù)n7.2.1 服務(wù)管理q服務(wù)管理主要指服務(wù)的啟動和停止qService是一段在后臺運行、沒有用戶界面的代碼:7.2 本地服務(wù)n7.2.1 服務(wù)管理1 import android.app.Service;2 import android.content.Intent;3 import android.os.IBinder;4 5 public cl

10、ass RandomService extends Service6 Override7 public IBinder onBind(Intent intent) 8 return null;9 10 7.2 本地服務(wù)n7.2.1 服務(wù)管理n使用Service需要導入的包:1 import android.app.Service;2 import android.content.Intent;3 import android.os.IBinder;n第5行:RandomService繼承了android.app.Service類n第7行重載onBind()函數(shù),onBind()函數(shù)是在Serv

11、ice被綁定后調(diào)用的函數(shù),返回Service的對象實例7.2 本地服務(wù)n7.2.1 服務(wù)管理qService一般需要重載onCreate()、 onStartCommand()和onDestroy()。qAndroid系統(tǒng)在創(chuàng)建Service時,會自動調(diào)用onCreate(),用戶一般在onCreate()完成必要的初始化工作,例如創(chuàng)建線程、建立數(shù)據(jù)庫鏈接等q在Service關(guān)閉前,系統(tǒng)會自動調(diào)用onDestroy()函數(shù)釋放所有占用的資源。q通過Context.startService(Intent)啟動Service, onStartCommand()/onStart()則會被調(diào)用,重要的

12、參數(shù)通過參數(shù)Intent傳遞給Service7.2 本地服務(wù)n7.2.1 服務(wù)管理1 public class RandomService extends Service2 Override3 public void onCreate() 4 super.onCreate(); 5 6 Override7 public int onStartCommand(Intent intent, int flags, int startId) 8 return super.onStartCommand(intent, flags, startId);9 10 Override11 public void

13、 onDestroy() 12 super.onDestroy();13 14 7.2 本地服務(wù)n7.2.1 服務(wù)管理q完成Service類后,需要在AndroidManifest.xml文件中注冊這個Serviceq注冊Service非常重要,如果開發(fā)人員不對Service進行注冊,則Service根本無法啟動qAndroidManifest.xml文件注冊Service: n使用標簽聲明服務(wù),其中的android:name表示Service類的名稱,一定要與建立的Service類名稱一致7.2 本地服務(wù)n7.2.1 服務(wù)管理q在完成Service代碼和在AndroidManifest.xm

14、l文件中注冊后。有兩種方法啟動Service,顯式啟動和隱式啟動q顯式啟動需要在Intent中指明Service所在的類,并調(diào)用startService(Intent)啟動Service final Intent serviceIntent = new Intent(this, RandomService.class); startService(serviceIntent); /Intent指明了啟動的Service所在類為RandomSerevice7.2 本地服務(wù)n7.2.1 服務(wù)管理q停止Service: 將啟動Service的Intent傳遞給stopService()函數(shù): sto

15、pService(serviceIntent);q在首次調(diào)用startService(Intent)函數(shù)啟動Service后,系統(tǒng)會先后調(diào)用onCreate()和onStartCommand()。q如果是第二次調(diào)用startService(Intent)函數(shù),系統(tǒng)則僅調(diào)用onStartCommand(),而不再調(diào)用onCreate()q在調(diào)用stopService(Intent)函數(shù)停止Service時,系統(tǒng)會調(diào)用onDestroy() q無論調(diào)用過多少次startService(Intent),在調(diào)用stopService(Intent)函數(shù)時,系統(tǒng)僅調(diào)用一次onDestroy()7.2 本

16、地服務(wù)n7.2.1 服務(wù)管理qSimpleRandomServiceDemo是在應用程序中使用Service的示例,這個示例使用顯式啟動的方式啟動Serviceq在工程中創(chuàng)建了RandomService服務(wù),該服務(wù)啟動后會產(chǎn)生一個隨機數(shù),并使用Toast顯示在屏幕上,如右圖所示 7.2 本地服務(wù)n7.2.1 服務(wù)管理q示例n通過界面上的“啟動Service”按鈕調(diào)用startService(Intent)函數(shù),啟動RandomService服務(wù) n“停止Service”按鈕調(diào)用stopService(Intent)函數(shù),停止RandomService服務(wù)n為了能夠清晰的觀察Service中on

17、Create()、 onStartCommand()和onDestroy()三個函數(shù)的調(diào)用順序,在每個函數(shù)中都使用Toast在界面上產(chǎn)生提示信息nRandomService.java文件的代碼如下7.2 本地服務(wù)n7.2.1 服務(wù)管理nRandomService.java文件的代碼1 package edu.hrbeu.SimpleRandomServiceDemo;2 3 import android.app.Service;4 import android.content.Intent;5 import android.os.IBinder;6 import android.widget.

18、Toast;7 8 public class RandomService extends Service9 10 Override11 public void onCreate() 12 super.onCreate();13 Toast.makeText(this, (1) 調(diào)用onCreate(),7.2 本地服務(wù)n7.2.1 服務(wù)管理nRandomService.java文件的代碼14 Toast.LENGTH_LONG).show();15 16 17 Override18 public int onStartCommand(Intent intent, int flags, int

19、startId) 20 Toast.makeText(this, (2) 調(diào)用onStartCommand (), 21 Toast.LENGTH_SHORT).show();22 23 double randomDouble = Math.random();24 String msg = 隨機數(shù) :+ String.valueOf(randomDouble);25 Toast.makeText(this,msg, Toast.LENGTH_SHORT).show();26 return super.onStartCommand(intent, flags, startId);27 7.2 本

20、地服務(wù)n7.2.1 服務(wù)管理nRandomService.java文件的代碼27 28 Override29 public void onDestroy() 30 super.onDestroy();31 Toast.makeText(this, (3) 調(diào)用onDestroy(), 32 Toast.LENGTH_SHORT).show();33 34 35 Override36 public IBinder onBind(Intent intent) 37 return null;38 39 7.2 本地服務(wù)n7.2.1 服務(wù)管理nAndroidManifest.xml文件的代碼如下 1

21、2 6 7 9 10 11 12 13 14 15 16 17 7.2 本地服務(wù)n7.2.1 服務(wù)管理q示例nSimpleRandomServiceDemoActivity.java文件的代碼如下1 package edu.hrbeu.SimpleRandomServiceDemo;2 3 import android.app.Activity;4 import android.content.Intent;5 import android.os.Bundle;6 import android.view.View;7 import android.widget.Button;7.2 本地服務(wù)n

22、7.2.1 服務(wù)管理nSimpleRandomServiceDemoActivity.java文件的代碼8 9 public class SimpleRandomServiceDemoActivity extends Activity 10 Override11 public void onCreate(Bundle savedInstanceState) 12 super.onCreate(savedInstanceState);13 setContentView(R.layout.main);14 15 Button startButton = (Button)findViewById(R

23、.id.start);16 Button stopButton = (Button)findViewById(R.id.stop);17 final Intent serviceIntent = new Intent(this, RandomService.class);18 startButton.setOnClickListener(new Button.OnClickListener()19 public void onClick(View view)20 startService(serviceIntent);7.2 本地服務(wù)n7.2.1 服務(wù)管理nSimpleRandomServic

24、eDemoActivity.java文件的代碼21 22 );23 stopButton.setOnClickListener(new Button.OnClickListener()24 public void onClick(View view)25 stopService(serviceIntent);26 27 );28 29 7.2 本地服務(wù)n7.2.3 服務(wù)綁定q當程序通過startService()和stopService()啟動、關(guān)閉Service時,Service與訪問者之間基本上不存在關(guān)聯(lián),因此Service和訪問者之間無法進行通信、數(shù)據(jù)交換。q如果Service和訪問者之

25、間需要進行方法調(diào)用或數(shù)據(jù)交換時,則應該使用bindService()和unbindService方法啟動、關(guān)閉服務(wù)。q以綁定方式使用Service,能夠獲取到Service實例,不僅能夠正常啟動Service,還能夠調(diào)用Service中的公有方法和屬性q為了使Service支持綁定,需要在Service類中重載onBind()方法,并在onBind()方法中返回Service實例:7.2 本地服務(wù)n7.2.3 服務(wù)綁定1 public class MathService extends Service2 private final IBinder mBinder = new LocalBind

26、er();3 4 public class LocalBinder extends Binder5 MathService getService() 6 return MathService.this;7 8 9 10 Override11 public IBinder onBind(Intent intent) 12 return mBinder;13 14 7.2 本地服務(wù)n7.2.3 服務(wù)綁定n當Service被綁定時,系統(tǒng)會調(diào)用onBind()函數(shù),通過onBind()函數(shù)的返回值,將Service實例返回給調(diào)用者n從第11行代碼中可以看出,onBind()函數(shù)的返回值必須符合IBin

27、der接口,因此在代碼的第2行聲明一個接口變量mBinder,mBinder符合onBind()函數(shù)返回值的要求,因此可將mBinder傳遞給調(diào)用者nIBinder是用于進程內(nèi)部和進程間過程調(diào)用的輕量級接口,定義了與遠程對象交互的抽象協(xié)議,使用時通過繼承Binder的方法來實現(xiàn)n繼承Binder的代碼在第4行,LocalBinder是繼承Binder的一個內(nèi)部類,并在代碼第5行實現(xiàn)了getService()函數(shù),當調(diào)用者獲取到mBinder后,通過調(diào)用getService()即可獲取到Service實例7.2 本地服務(wù)n7.2.3 服務(wù)綁定q調(diào)用者通過bindService()函數(shù)綁定服務(wù)n調(diào)

28、用者通過bindService()函數(shù)綁定服務(wù),并在第1個參數(shù)中將Intent傳遞給bindService()函數(shù),聲明需要啟動的Servicen第3個參數(shù)Context.BIND_AUTO_CREATE表明只要綁定存在,就自動建立Service n同時也告知Android系統(tǒng),這個Service的重要程度與調(diào)用者相同,除非考慮終止調(diào)用者,否則不要關(guān)閉這個Service1 final Intent serviceIntent = new Intent(this,MathService.class);2 bindService(serviceIntent,mConnection,Context.

29、BIND_AUTO_CREATE);7.2 本地服務(wù)n7.2.3 服務(wù)綁定qbindService()函數(shù)的第2個參數(shù)是ServiceConnnectionn當綁定成功后,系統(tǒng)將調(diào)用ServiceConnnection的onServiceConnected()方法n當綁定意外斷開后,系統(tǒng)將調(diào)用ServiceConnnection中的onServiceDisconnected方法n因此,以綁定方式使用Service,調(diào)用者需要聲明一個ServiceConnnection,并重載內(nèi)部的onServiceConnected()方法和onServiceDisconnected方法,兩個方法的重載代碼如

30、下7.2 本地服務(wù)n7.2.3 服務(wù)綁定1 private ServiceConnection mConnection = new ServiceConnection() 2 Override3 public void onServiceConnected(ComponentName name, IBinder service) 4 mathService = (MathService.LocalBinder)service).getService();5 6 Override7 public void onServiceDisconnected(ComponentName name) 8 m

31、athService = null; 9 10 ;7.2 本地服務(wù)n7.2.3 服務(wù)綁定n在代碼的第4行中,綁定成功后通過getService()獲取Service實例,這樣便可以調(diào)用Service中的方法和屬性n代碼第8行將Service實例指為null,表示綁定意外失效時,Service實例不再可用q取消綁定僅需要使用unbindService()方法,并將ServiceConnnection傳遞給unbindService()方法q但需要注意的是,unbindService()方法成功后,系統(tǒng)并不會調(diào)用onServiceConnected(),因為onServiceConnected()

32、僅在意外斷開綁定時才被調(diào)用1 unbindService(mConnection);7.2 本地服務(wù)n7.2.3 服務(wù)綁定q綁定方式中,當調(diào)用者通過bindService()函數(shù)綁定Servcie時,onCreate()函數(shù)和onBinde()函數(shù)將被先后調(diào)用q當調(diào)用者通過unbindService()函數(shù)取消綁定Servcie時,onUnbind()函數(shù)將被調(diào)用。如果onUnbind()函數(shù)返回true,則表示重新綁定服務(wù)時,onRebind()函數(shù)將被調(diào)用。綁定方式的函數(shù)調(diào)用順序如下圖所示7.2 本地服務(wù)n7.2.3 服務(wù)綁定qSimpleMathServiceDemo是綁定方式使用Ser

33、vice的示例n在示例中創(chuàng)建了MathService服務(wù),用來完成簡單的數(shù)學運算,這里的數(shù)學運算僅指加法運算,雖然沒有實際意義,但可以說明如何使用綁定方式調(diào)用Service中的公有方法n在服務(wù)綁定后,用戶可以點擊“加法運算”,將兩個隨機產(chǎn)生的數(shù)值傳遞給MathService服務(wù),并從MathService實例中獲取到加法運算的結(jié)果,然后顯示在屏幕的上方n“取消綁定”按鈕可以解除與MathService的綁定關(guān)系,在取消綁定后,點擊“加法運算”按鈕將無法獲取運算結(jié)果7.2 本地服務(wù)n7.2.3 服務(wù)綁定qSimpleMathServiceDemo是綁定方式使用Service的示例nSimpleM

34、athServiceDemo的用戶界面如下圖所示7.2 本地服務(wù)n7.2.3 服務(wù)綁定qSimpleMathServiceDemo是綁定方式使用Service的示例n在SimpleMathServiceDemo示例中,MathService.java文件是Service的定義文件nSimpleMathServiceDemoActivity.java文件是界面的Activity文件,綁定服務(wù)和取消綁定服務(wù)的代碼在這個文件中n下面是MathService.java和SimpleMathServiceDemoActivity.java文件的完整代碼 7.2 本地服務(wù)n7.2.3 服務(wù)綁定nMathS

35、ervice.java文件代碼1 package edu.hrbeu.SimpleMathServiceDemo;2 3 import android.app.Service;4 import android.content.Intent;5 import android.os.Binder;6 import android.os.IBinder;7 import android.widget.Toast;8 9 public class MathService extends Service10 11 private final IBinder mBinder = new LocalBind

36、er();12 7.2 本地服務(wù)n7.2.3 服務(wù)綁定nMathService.java文件代碼13 public class LocalBinder extends Binder14 MathService getService() 15 return MathService.this;16 17 18 19 Override20 public IBinder onBind(Intent intent) 21 Toast.makeText(this, 本地綁定:MathService, 22 Toast.LENGTH_SHORT).show();23 return mBinder;24 7.

37、2 本地服務(wù)n7.2.3 服務(wù)綁定nMathService.java文件代碼25 26 Override27 public boolean onUnbind(Intent intent)28 Toast.makeText(this, 取消本地綁定:取消本地綁定:MathService, 29 Toast.LENGTH_SHORT).show(); 30 return false;31 32 33 34 public long Add(long a, long b)35 return a+b;36 37 38 7.2 本地服務(wù)n7.2.3 服務(wù)綁定nSimpleMathServiceDemoAc

38、tivity.java文件代碼 1 package edu.hrbeu.SimpleMathServiceDemo;2 3 import android.app.Activity;4 import android.content.ComponentName;5 import android.content.Context;6 import android.content.Intent;7 import android.content.ServiceConnection;8 import android.os.Bundle;9 import android.os.IBinder;10 impor

39、t android.view.View;11 import android.widget.Button;12 import android.widget.TextView;7.2 本地服務(wù)n7.2.3 服務(wù)綁定nSimpleMathServiceDemoActivity.java文件代碼 13 14 public class SimpleMathServiceDemoActivity extends Activity 15 private MathService mathService;16 private boolean isBound = false;17 TextView labelVi

40、ew;18 Override19 public void onCreate(Bundle savedInstanceState) 20 super.onCreate(savedInstanceState);21 setContentView(R.layout.main);22 23 labelView = (TextView)findViewById(R.id.label);24 Button bindButton = (Button)findViewById(R.id.bind);7.2 本地服務(wù)n7.2.3 服務(wù)綁定nSimpleMathServiceDemoActivity.java文件代碼 25 Button unbindButton = (Button)findViewById(R.id.unbind);26 Button computButton = (Button)findViewById(Rpute);27 28 bindButton.setOnClickListener(new View.OnClickListener()29 Override30 public void onClick(View v) 31 if(!isBound)32 final In

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論