安卓編程技術(shù)-第7章_第1頁
安卓編程技術(shù)-第7章_第2頁
安卓編程技術(shù)-第7章_第3頁
安卓編程技術(shù)-第7章_第4頁
安卓編程技術(shù)-第7章_第5頁
已閱讀5頁,還剩111頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第第7章章 后臺服務(wù)后臺服務(wù)本章學(xué)習(xí)目標(biāo)n了解Service的原理和用途n掌握進(jìn)程內(nèi)服務(wù)的管理方法n掌握服務(wù)的隱式啟動和顯式啟動方法n了解線程的啟動、掛起和停止方法n了解跨線程的界面更新方法n掌握跨進(jìn)程服務(wù)的綁定和調(diào)用方法n了解AIDL語言的用途和語法 7.1 Service簡介 nServiceqService是Android系統(tǒng)的后臺服務(wù)組件,適用于開發(fā)無界面、長時間運行的應(yīng)用功能q 特點n沒有用戶界面n比Activity 的優(yōu)先級高,不會輕易被Android系統(tǒng)終止n即使Service被系統(tǒng)終止,在系統(tǒng)資源恢復(fù)后Service也將自動恢復(fù)運行狀態(tài)n用于進(jìn)程間通信(Inter Proces

2、s Communication,IPC),解決兩個不同Android應(yīng)用程序進(jìn)程之間的調(diào)用和通訊問題7.1 Service簡介 nService生命周期qService生命周期包括n全生命周期n活動生命周期nonCreate()事件回調(diào)函數(shù): Service的生命周期開始,完成Service的初始化工作nonStart()事件回調(diào)函數(shù):活動生命周期開始,但沒有與之對應(yīng)的“停止”函數(shù),因此可以近似認(rèn)為活動生命周期也是以onDestroy()標(biāo)志結(jié)束nonDestroy()事件回調(diào)函數(shù): Service的生命周期結(jié)束,釋放Service所有占用的資源7.1 Service簡介 nService使用

3、方法q啟動方式q綁定方式n啟動方式q通過調(diào)用Context.startService()啟動Service,通過調(diào)用Context.stopService()或Service.stopSefl()停止ServicenService是由其他的組件啟動的,但停止過程可以通過其他組件或自身完成n如果僅以啟動方式使用的Service,這個Service需要具備自管理的能力,且不需要通過函數(shù)調(diào)用向外部組件提供數(shù)據(jù)或功能7.1 Service簡介 n綁定方式q通過服務(wù)鏈接(Connection)或直接獲取Service中狀態(tài)和數(shù)據(jù)信息n服務(wù)鏈接能夠獲取Service的對象,因此綁定Service的組件可以

4、調(diào)用Service中的實現(xiàn)的函數(shù)n使用Service的組件通過Context.bindService()建立服務(wù)鏈接,通過Context.unbindService()停止服務(wù)鏈接n如果在綁定過程中Service沒有啟動,Context.bindService()會自動啟動Servicen同一個Service可以綁定多個服務(wù)鏈接,這樣可以同時為多個不同的組件提供服務(wù)7.1 Service簡介 n啟動方式和綁定方式的結(jié)合q這兩種使用方法并不是完全獨立的,在某些情況下可以混合使用n以MP3播放器為例,在后臺的工作的Service通過Context.startService()啟動某個特定音樂播放,

5、但在播放過程中如果用戶需要暫停音樂播放,則需要通過Context.bindService()獲取服務(wù)鏈接和Service對象,進(jìn)而通過調(diào)用Service的對象中的函數(shù),暫停音樂播放過程,并保存相關(guān)信息。在這種情況下,如果調(diào)用Context.stopService()并不能夠停止Service,需要在所有的服務(wù)鏈接關(guān)閉后,Service才能夠真正的停止7.2 本地服務(wù)n7.2.1 服務(wù)管理q服務(wù)管理主要指服務(wù)的啟動和停止q首先介紹實現(xiàn)Service的最小代碼集n第1行到第3行引入必要包n第5行聲明了RandomService繼承android.app.Service類n在第7行到第9行重載了on

6、Bind()函數(shù)1.import android.app.Service;2.import android.content.Intent;3.import android.os.IBinder;4. 5.public class RandomService extends Service6.Override7.public IBinder onBind(Intent intent) 8.return null;9.10. 7.2 本地服務(wù)n7.2.1 服務(wù)管理qonBind()函數(shù)是在Service被綁定后調(diào)用的函數(shù),能夠返回Service的對象,在后面的內(nèi)容中會詳細(xì)介紹qService的最小

7、代碼集并不能完成任何實際的功能,需要重載onCreate()、onStart()和onDestroy(),才使Service具有實際意義nAndroid系統(tǒng)在創(chuàng)建Service時,會自動調(diào)用onCreate() 完成必要的初始化工作n在Service沒有必要再存在時,系統(tǒng)會自動調(diào)用onDestroy(),釋放所有占用的資源n通過Context.startService(Intent)啟動Service時,onStart()則會被系統(tǒng)調(diào)用,Intent會傳遞給Service一些重要的參數(shù)qService會根據(jù)實際情況選擇需要重載上面的三個函數(shù)7.2 本地服務(wù)n7.2.1 服務(wù)管理n第4行、第8行

8、和第12行的代碼重載onCreate()、onStart()和onDestroy()三個函數(shù)時,必須要在代碼中調(diào)用父函數(shù)1.public class RandomService extends Service2.Override3.public void onCreate() 4. super.onCreate(); 5.6.Override7.public void onStart(Intent intent, int startId) 8. super.onStart(intent, startId);9.10.Override11.public void onDestroy() 12.

9、super.onDestroy();13.14. 7.2 本地服務(wù)n7.2.1 服務(wù)管理q注冊Servicen在AndroidManifest.xml文件中注冊,否則,這個Service根本無法啟動nAndroidManifest.xml文件中注冊Service的代碼如下n使用標(biāo)簽聲明服務(wù),其中的android:name表示的是Service的類名稱,一定要與用戶建立的Service類名稱一致1.7.2 本地服務(wù)n7.2.1 服務(wù)管理q啟動Servicen啟動方式q顯示啟動q隱式啟動n顯示啟動:在Intent中指明Service所在的類,并調(diào)用startService(Intent)函數(shù)啟動S

10、ervice,示例代碼如下q在Intent中指明啟動的Service在RandomSerevice.class中1.final Intent serviceIntent = new Intent(this, RandomService.class);2.startService(serviceIntent);7.2 本地服務(wù)n7.2.1 服務(wù)管理q啟動Servicen隱式啟動:在注冊Service時,聲明Intent-filter的action屬性q設(shè)置Intent的action屬性,可以在不聲明Service所在類的情況下啟動服務(wù)n隱式啟動的代碼如下.5.1.final Int

11、ent serviceIntent = new Intent();2.serviceIntent.setAction(edu.hrbeu.RandomService);7.2 本地服務(wù)n7.2.1 服務(wù)管理q啟動Servicen若Service和調(diào)用服務(wù)的組件在同一個應(yīng)用程序中,可以使用顯式啟動或隱式啟動,顯式啟動更加易于使用,且代碼簡潔n若服務(wù)和調(diào)用服務(wù)的組件在不同的應(yīng)用程序中,則只能使用隱式啟動7.2 本地服務(wù)n7.2.1 服務(wù)管理q停止Servicen將啟動Service的Intent傳遞給stopService(Intent)函數(shù)即可,示例代碼如下q在調(diào)用startService(In

12、tent)函數(shù)首次啟動Service后,系統(tǒng)會先后調(diào)用onCreate()和onStart()q再次調(diào)用startService(Intent)函數(shù),系統(tǒng)則僅調(diào)用onStart(),而不再調(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()一次1.stopService(serviceIntent);7.2 本地服務(wù)n7.2.1 服務(wù)管理q示例SimpleRandomServ

13、iceDemo以顯式啟動服務(wù)在應(yīng)用程序中建立Servicen在工程中創(chuàng)建RandomService服務(wù),該服務(wù)啟動后會產(chǎn)生一個隨機數(shù),使用Toast顯示在屏幕上n“啟動Service”按鈕調(diào)用startService(Intent)函數(shù),啟動RandomService服務(wù)n“停止Service”按鈕調(diào)用stopService(Intent)函數(shù),停止RandomService服務(wù)7.2 本地服務(wù)n7.2.1 服務(wù)管理qRandomService.java文件的代碼如下1.package edu.hrbeu.SimpleRandomServiceDemo;2. 3.import android.

14、app.Service;4.import android.content.Intent;5.import android.os.IBinder;6.import android.widget.Toast;7. 8.public class RandomService extends Service9.10.Override11.public void onCreate() 12.super.onCreate();13.Toast.makeText(this, (1) 調(diào)用onCreate(),14.Toast.LENGTH_LONG).show(); 本地服務(wù)n7.2.1 服

15、務(wù)管理17. Override18. public void onStart(Intent intent, int startId) 19. super.onStart(intent, startId);20. Toast.makeText(this, (2) 調(diào)用onStart(), 21. Toast.LENGTH_SHORT).show();22. 23. double randomDouble = Math.random();24. String msg = 隨機數(shù):+ String.valueOf(randomDouble);25. Toast.makeText(this,msg,

16、Toast.LENGTH_SHORT).show();26. 27. 28. Override29. public void onDestroy() 30. super.onDestroy();31. Toast.makeText(this, (3) 調(diào)用onDestroy(), 32. Toast.LENGTH_SHORT).show();33. 7.2 本地服務(wù)n7.2.1 服務(wù)管理n在onStart()函數(shù)中添加生產(chǎn)隨機數(shù)的代碼,第23行生產(chǎn)一個介于0和1之間的隨機數(shù)n第24行代碼構(gòu)造供Toast顯示的消息34.35. Override36. public IBinder onBind(

17、Intent intent) 37. return null;38. 39. 7.2 本地服務(wù)n7.2.1 服務(wù)管理qAndroidManifest.xml文件的代碼如下1.2.6. 7. 9. 10. 11. 12. 13. 7.2 本地服務(wù)n7.2.1 服務(wù)管理n在調(diào)用AndroidManifest.xml文件中,在標(biāo)簽下,包含一個標(biāo)簽和一個標(biāo)簽,在標(biāo)簽中,聲明了RandomService所在的類14. 15. 16. 17. 7.2 本地服務(wù)n7.2.1 服務(wù)管理qSimpleRandomServiceDemo.java文件的代碼如下1.package edu.hrbeu.SimpleR

18、andomServiceDemo;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;8. 9.public class SimpleRandomServiceDemo extends Activity 10.Override11.public void onCreate(Bundle savedInstanceState) 12.super.onC

19、reate(savedInstanceState);13.setContentView(R.layout.main);14. 7.2 本地服務(wù)n7.2.1 服務(wù)管理n第20行和第25行分別是啟動和停止Service的代碼15. Button startButton = (Button)findViewById(R.id.start);16. Button stopButton = (Button)findViewById(R.id.stop);17. final Intent serviceIntent = new Intent(this, RandomService.class);18. s

20、tartButton.setOnClickListener(new Button.OnClickListener()19. public void onClick(View view)20. startService(serviceIntent);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.2 使用線程q任

21、何耗時的處理過程都會降低用戶界面的響應(yīng)速度,甚至導(dǎo)致用戶界面失去響應(yīng),當(dāng)用戶界面失去響應(yīng)超過5秒鐘,Android系統(tǒng)會允許用戶強行關(guān)閉應(yīng)用程序q較好的解決方法是將耗時的處理過程轉(zhuǎn)移到子線程上,這樣可以避免負(fù)責(zé)界面更新的主線程無法處理界面事件,從而避免用戶界面長時間失去響應(yīng)7.2 本地服務(wù)n7.2.2 使用線程q線程是獨立的程序單元,多個線程可以并行工作q在多處理器系統(tǒng)中,每個中央處理器(CPU)單獨運行一個線程,因此線程是并行工作的q在單處理器系統(tǒng)中,處理器會給每個線程一小段時間,在這個時間內(nèi)線程是被執(zhí)行的,然后處理器執(zhí)行下一個線程,這樣就產(chǎn)生了線程并行運行的假象q無論線程是否真的并行工作,

22、在宏觀上可以認(rèn)為子線程是獨立于主線程,且能與主線程并行工作的程序單元7.2 本地服務(wù)n7.2.2 使用線程q使用線程n實現(xiàn)Java的Runnable接口,并重載run()方法。在run()中放置代碼的主體部分1.private Runnable backgroudWork = new Runnable()2.Override3.public void run() 4./過程代碼5.6.;7.2 本地服務(wù)n7.2.2 使用線程q使用線程n創(chuàng)建Thread對象,并將上面實現(xiàn)的Runnable對象作為參數(shù)傳遞給Thread對象qThread的構(gòu)造函數(shù)中,第1個參數(shù)用來表示線程組q第2個參數(shù)是需要執(zhí)行

23、的Runnable對象q第3個參數(shù)是線程的名稱n調(diào)用start()方法啟動線程1.private Thread workThread;2.workThread = new Thread(null,backgroudWork,WorkThread);1.workThread.start();7.2 本地服務(wù)n7.2.2 使用線程q線程在run()方法返回后,線程就自動終止了;不推薦使用調(diào)用stop()方法在外部終止線程q最好的方法是通知線程自行終止,一般調(diào)用interrupt()方法通告線程準(zhǔn)備終止,線程會釋放它正在使用的資源,在完成所有的清理工作后自行關(guān)閉ninterrupt()方法并不能直接

24、終止線程,僅是改變了線程內(nèi)部的一個布爾字段,run()方法能夠檢測到這個布爾字段,從而知道何時應(yīng)該釋放資源和終止線程n在run()方法的代碼,一般通過Terrupted()方法查詢線程是否被中斷1.workTerrupt();7.2 本地服務(wù)n7.2.2 使用線程q下面的代碼是以1秒為間隔循環(huán)檢測斷線程是否被中斷n第4行代碼使線程休眠1000毫秒n當(dāng)線程在休眠過程中被中斷,則會產(chǎn)生InterruptedExceptionn在中斷的線程上調(diào)用sleep()方法,同樣會產(chǎn)生InterruptedException1.public void run() 2.whi

25、le(!Terrupted()3./過程代碼4.Thread.sleep(1000); 本地服務(wù)n7.2.2 使用線程qTerrupted()方法功能n判斷線程是否應(yīng)被中斷n通過捕獲InterruptedException判斷線程是否應(yīng)被中斷,并且在捕獲到InterruptedException后,安全終止線程1.public void run() 2.try 3.while(true)4./過程代碼5.Thread.sleep(1000);6.7. catch (InterruptedException e) 8.e.printStackTr

26、ace();9.10. 7.2 本地服務(wù)n7.2.2 使用線程q使用Handler更新用戶界面nHandler允許將Runnable對象發(fā)送到線程的消息隊列中,每個Handler對象綁定到一個單獨的線程和消息隊列上n當(dāng)用戶建立一個新的Handler對象,通過post()方法將Runnable對象從后臺線程發(fā)送到GUI線程的消息隊列中,當(dāng)Runnable對象通過消息隊列后,這個Runnable對象將被運行7.2 本地服務(wù)n7.2.2 使用線程n第1行代碼建立了一個靜態(tài)的Handler對象,但這個對象是私有的,因此外部代碼并不能直接調(diào)用這個Handler對象1.private static Han

27、dler handler = new Handler();2. 3.public static void UpdateGUI(double refreshDouble)4.handler.post(RefreshLable);5.6.private static Runnable RefreshLable = new Runnable()7.Override8.public void run() 9./過程代碼10.11. ;7.2 本地服務(wù)n7.2.2 使用線程n第3行UpdateGUI()是公有的界面更新函數(shù),后臺線程通過調(diào)用該函數(shù),將后臺產(chǎn)生的數(shù)據(jù)refreshDouble傳遞到Upda

28、teGUI()函數(shù)內(nèi)部,然后并直接調(diào)用post()方法,將第6行的創(chuàng)建的Runnable對象傳遞給界面線程(主線程)的消息隊列中n第7行到第10行代碼是Runnable對象中需要重載的run()函數(shù),一般將界面更新代碼放置在run()函數(shù)中7.2 本地服務(wù)n7.2.2 使用線程q示例ThreadRandomServiceDemo使用線程持續(xù)產(chǎn)生隨機數(shù)n點擊“啟動Service”后,將啟動后臺線程n點擊“停止Service”后,將關(guān)閉后臺線程n后臺線程每1秒鐘產(chǎn)生一個0到1之間的隨機數(shù),并通過Handler將產(chǎn)生的隨機數(shù)顯示在用戶界面上7.2 本地服務(wù)n7.2.2 使用線程q在ThreadRan

29、domServiceDemo示例中,RandomService.java文件是描述Service的文件,用來創(chuàng)建線程、產(chǎn)生隨機數(shù)和調(diào)用界面更新函數(shù)qRandomService.java文件的完整代碼如下1.package edu.hrbeu.ThreadRandomServiceDemo;2. 3.import android.app.Service;4.import android.content.Intent;5.import android.os.IBinder;6.import android.widget.Toast;7. 8.public class RandomService e

30、xtends Service9.10.private Thread workThread;11.7.2 本地服務(wù)n7.2.2 使用線程12. Override13. public void onCreate() 14. super.onCreate();15. Toast.makeText(this, (1) 調(diào)用onCreate(), 16. Toast.LENGTH_LONG).show(); 17. workThread = new Thread(null,backgroudWork,WorkThread);18. 19. 20. Override21. public void onSt

31、art(Intent intent, int startId) 22. super.onStart(intent, startId);23. Toast.makeText(this, (2) 調(diào)用onStart(), 24. Toast.LENGTH_SHORT).show();25. if (!workThread.isAlive()26. workThread.start();27. 28. 29. 7.2 本地服務(wù)n7.2.2 使用線程30. Override31. public void onDestroy() 32. super.onDestroy();33. Toast.makeT

32、ext(this, (3) 調(diào)用onDestroy(), 34. Toast.LENGTH_SHORT).show(); 35. workTerrupt();36. 37. 38. Override39. public IBinder onBind(Intent intent) 40. return null;41. 42. 7.2 本地服務(wù)n7.2.2 使用線程43. private Runnable backgroudWork = new Runnable()44. Override45. public void run() 46. try 47. while(!Thre

33、errupted()48. double randomDouble = Math.random();49. ThreadRandomServiceDemo.UpdateGUI(randomDouble);50. Thread.sleep(1000);51. 52. catch (InterruptedException e) 53. e.printStackTrace();54. 55. 56. ;57. 7.2 本地服務(wù)n7.2.2 使用線程qThreadRandomServiceDemo.java文件是界面的Activity文件,封裝Handler的界面更新函數(shù)就在這個文件中q

34、ThreadRandomServiceDemo.java文件的完整代碼1.package edu.hrbeu.ThreadRandomServiceDemo;2. 3.import android.app.Activity;4.import android.content.Intent;5.import android.os.Bundle;6.import android.os.Handler;7.import android.view.View;8.import android.widget.Button;9.import android.widget.TextView;10. 7.2 本地

35、服務(wù)n7.2.2 使用線程11. public class ThreadRandomServiceDemo extends Activity 12. 13. private static Handler handler = new Handler();14. private static TextView labelView = null;15. private static double randomDouble ;16. 17. public static void UpdateGUI(double refreshDouble)18. randomDouble = refreshDoubl

36、e;19. handler.post(RefreshLable);20. 21. 22. private static Runnable RefreshLable = new Runnable()23. Override24. public void run() 25. labelView.setText(String.valueOf(randomDouble);26. 27. ;28. 7.2 本地服務(wù)n7.2.2 使用線程29. Override30. public void onCreate(Bundle savedInstanceState) 31. super.onCreate(sa

37、vedInstanceState);32. setContentView(R.layout.main);33. labelView = (TextView)findViewById(R.id.label);34. Button startButton = (Button)findViewById(R.id.start);35. Button stopButton = (Button)findViewById(R.id.stop);36. final Intent serviceIntent = new Intent(this, RandomService.class); 37. 38. sta

38、rtButton.setOnClickListener(new Button.OnClickListener()39. public void onClick(View view)40. startService(serviceIntent);41. 42. );43. 7.2 本地服務(wù)n7.2.2 使用線程44.stopButton.setOnClickListener(new Button.OnClickListener()45. public void onClick(View view)46. stopService(serviceIntent);47.48.);49. 50. 7.2

39、 本地服務(wù)n7.2.3 服務(wù)綁定q以綁定方式使用Service,能夠獲取到Service對象,不僅能夠正常啟動Service,而且能夠調(diào)用正在運行中的Service實現(xiàn)的公有方法和屬性q為了使Service支持綁定,需要在Service類中重載onBind()方法,并在onBind()方法中返回Service對象,示例代碼如下7.2 本地服務(wù)n7.2.3 服務(wù)綁定n當(dāng)Service被綁定時,系統(tǒng)會調(diào)用onBind()函數(shù),通過onBind()函數(shù)的返回值,將Service對象返回給調(diào)用者1.public class MathService extends Service2.private fi

40、nal IBinder mBinder = new LocalBinder();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第11行代碼中可以看出,onBind()函數(shù)的返回值必須是符合IBinder接口,因此在代碼的第2行聲明一個接口變量mB

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

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

43、個參數(shù)是ServiceConnnectionn當(dāng)綁定成功后,系統(tǒng)將調(diào)用ServiceConnnection的onServiceConnected()方法n而當(dāng)綁定意外斷開后,系統(tǒng)將調(diào)用ServiceConnnection中的onServiceDisconnected方法n由上可知,以綁定方式使用Service,調(diào)用者需要聲明一個ServiceConnnection,并重載內(nèi)部的onServiceConnected()方法和onServiceDisconnected方法7.2 本地服務(wù)n7.2.3 服務(wù)綁定n在第4行代碼中,綁定成功后通過getService()獲取Service對象,這樣便可以

44、調(diào)用Service中的方法和屬性n第8行代碼將Service對象設(shè)置為null,表示綁定意外失效,Service實例不再可用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 onS

45、erviceDisconnected(ComponentName name) 8.mathService = null;9.10. ;7.2 本地服務(wù)n7.2.3 服務(wù)綁定q取消綁定僅需要使用unbindService()方法,并將ServiceConnnection傳遞給unbindService()方法n需注意的是,unbindService()方法成功后,系統(tǒng)并不會調(diào)用onServiceConnected(),因為onServiceConnected()僅在意外斷開綁定時才被調(diào)用unbindService(mConnection);7.2 本地服務(wù)n7.2.3 服務(wù)綁定q通過bindSe

46、rvice()函數(shù)綁定Servcie時, onCreate()函數(shù)和onBinde()函數(shù)將先后被調(diào)用q通過unbindService()函數(shù)取消綁定Servcie時,onUnbind()函數(shù)將被調(diào)用,如果onUnbind()函數(shù)的返回true,則表示在調(diào)用者綁定新服務(wù)時,onRebind()函數(shù)將被調(diào)用q綁定方式的函數(shù)調(diào)用順序7.2 本地服務(wù)n7.2.3 服務(wù)綁定q示例SimpleMathServiceDemo使用綁定方式使用Servicen創(chuàng)建了MathService服務(wù),用來完成簡單的數(shù)學(xué)運算但足以說明如何使用綁定方式調(diào)用Service實例中的公有方法7.2 本地服務(wù)n7.2.3 服務(wù)綁

47、定n在服務(wù)綁定后,用戶可以點擊“加法運算”,將兩個隨機產(chǎn)生的數(shù)值傳遞給MathService服務(wù),并從MathService對象中獲取到加法運算的結(jié)果,然后顯示在屏幕的上方n“取消綁定”按鈕可以解除與MathService的綁定關(guān)系,取消綁定后,無法通過“加法運算”按鈕獲取加法運算結(jié)果7.2 本地服務(wù)n7.2.3 服務(wù)綁定q在SimpleMathServiceDemo示例中,MathService.java文件是描述Service的文件qMathService.java文件的完整代碼如下1.package edu.hrbeu.SimpleMathServiceDemo;2. 3.import

48、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. 7.2 本地服務(wù)n7.2.3 服務(wù)綁定11. private final IBinder mBinder = new LocalBinder();12. 13. public class LocalBinder extends

49、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. 25. 7.2 本地服務(wù)n7.2.3 服務(wù)綁定26. Override27. public boolean onUnbind(Intent inten

50、t)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ù)綁定qSimpleMathServiceDemo.java文件是界面的Activity文件,綁定和取消綁定服務(wù)的代碼在這個文件中qSimpleMathServiceDemo.java文件的完整代碼如下1.package edu.

51、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. import android.view.View;11. impo

52、rt android.widget.Button;12. import android.widget.TextView;13. 7.2 本地服務(wù)n7.2.3 服務(wù)綁定14. public class SimpleMathServiceDemo extends Activity 15. private MathService mathService;16. private boolean isBound = false;17. TextView labelView;18. Override19. public void onCreate(Bundle savedInstanceState) 20

53、. super.onCreate(savedInstanceState);21. setContentView(R.layout.main);22. 23. labelView = (TextView)findViewById(R.id.label);24. Button bindButton = (Button)findViewById(R.id.bind);25. Button unbindButton = (Button)findViewById(R.id.unbind);26. Button computButton = (Button)findViewById(Rpute);27.

54、28. bindButton.setOnClickListener(new View.OnClickListener()29. Override30. public void onClick(View v) 31. if(!isBound)7.2 本地服務(wù)n7.2.3 服務(wù)綁定32. final Intent serviceIntent = new Intent(SimpleMathServiceDemo.this,MathService.class);33. bindService(serviceIntent,mConnection,Context.BIND_AUTO_CREATE);34.

55、 isBound = true;35. 36. 37. );38. 39. . unbindButton.setOnClickListener(new View.OnClickListener()40.Override41. public void onClick(View v) 42. if(isBound)43. isBound = false;44. unbindService(mConnection);45.mathService = null;46. 47. 48. );7.2 本地服務(wù)n7.2.3 服務(wù)綁定49.50. computButton.setOnClickListener

56、(new View.OnClickListener()51. Override52. public void onClick(View v) 53. if (mathService = null)54. labelView.setText(未綁定服務(wù));55. return;56. 57. long a = Math.round(Math.random()*100);58. long b = Math.round(Math.random()*100);59. long result = mathService.Add(a, b);60. String msg = String.valueOf(

57、a)+ + +String.valueOf(b)+61. = +String.valueOf(result);62. labelView.setText(msg);63. 64. );65. 66. 7.2 本地服務(wù)n7.2.3 服務(wù)綁定67. private ServiceConnection mConnection = new ServiceConnection() 68. Override69. public void onServiceConnected(ComponentName name, IBinder service) 70. mathService = (MathServic

58、e.LocalBinder)service).getService();71. 72. 73.Override74. public void onServiceDisconnected(ComponentName name) 75. mathService = null;76. 77. ;78. 7.3 遠(yuǎn)程服務(wù)n7.3.1 進(jìn)程間通信q在Android系統(tǒng)中,每個應(yīng)用程序在各自的進(jìn)程中運行,而且出于安全原因的考慮,這些進(jìn)程之間彼此是隔離的,進(jìn)程之間傳遞數(shù)據(jù)和對象,需要使用Android支持的進(jìn)程間通信(Inter-Process Communication,IPC)機制q進(jìn)程間通信采用Int

59、ent和跨進(jìn)程服務(wù)的方式實現(xiàn)IPC,使應(yīng)用程序具有更好的獨立性和魯棒性qIPC機制包含nIntent:承載數(shù)據(jù),是一種簡單、高效、且易于使用的IPC機制n遠(yuǎn)程服務(wù):服務(wù)和調(diào)用者在不同的兩個進(jìn)程中,調(diào)用過程需要跨越進(jìn)程才能實現(xiàn)7.3 遠(yuǎn)程服務(wù)n7.3.1 進(jìn)程間通信q實現(xiàn)遠(yuǎn)程服務(wù)的步驟n使用AIDL語言定義跨進(jìn)程服務(wù)的接口n根據(jù)AIDL語言定義的接口,在具體的Service類中實現(xiàn)接口中定義的方法和屬性n在需要調(diào)用跨進(jìn)程服務(wù)的組件中,通過相同的AIDL接口文件,調(diào)用跨進(jìn)程服務(wù)7.3 遠(yuǎn)程服務(wù)n7.3.2 服務(wù)創(chuàng)建與調(diào)用qAIDL(Android Interface Definition Lang

60、uage)是Android系統(tǒng)自定義的接口描述語言,可以簡化進(jìn)程間數(shù)據(jù)格式轉(zhuǎn)換和數(shù)據(jù)交換的代碼,通過定義Service內(nèi)部的公共方法,允許調(diào)用者和Service在不同進(jìn)程間相互傳遞數(shù)據(jù)qAIDL的IPC機制與COM和Corba非常相似,都是基于接口的輕量級進(jìn)程通信機制qAIDL語言的語法與Java語言的接口定義非常相似,唯一不同之處是:AIDL允許定義函數(shù)參數(shù)的傳遞方向7.3 遠(yuǎn)程服務(wù)n7.3.2 服務(wù)創(chuàng)建與調(diào)用qAIDL支持三種方向:in、out和inoutn標(biāo)識為in的參數(shù)將從調(diào)用者傳遞到跨進(jìn)程服務(wù)中n標(biāo)識為out的參數(shù)將從跨進(jìn)程服務(wù)傳遞到調(diào)用者中n標(biāo)識為inout的參數(shù)將先從調(diào)用者傳遞到

溫馨提示

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

評論

0/150

提交評論