《Android實(shí)戰(zhàn)基礎(chǔ)教程》課件第六章_第1頁
《Android實(shí)戰(zhàn)基礎(chǔ)教程》課件第六章_第2頁
《Android實(shí)戰(zhàn)基礎(chǔ)教程》課件第六章_第3頁
《Android實(shí)戰(zhàn)基礎(chǔ)教程》課件第六章_第4頁
《Android實(shí)戰(zhàn)基礎(chǔ)教程》課件第六章_第5頁
已閱讀5頁,還剩50頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

目錄6.1創(chuàng)建配置Service6.2啟動(dòng)Service6.3IntentService的使用6.4遠(yuǎn)程服務(wù)(AIDL)

六、Service六、Service

開發(fā)Service的步驟如下:(1)定義一個(gè)繼承Service的子類。(2)在清單文件中配置該Service。

Service生命周期方法:IBinderonBind(Intentintent):該方法是Service子類必須實(shí)現(xiàn)的方法。該方法返回一個(gè)IBinder對(duì)象,應(yīng)用程序可通過該對(duì)象與Servcie組件通信。6.1創(chuàng)建配置Service六、ServicevoidonCreate():當(dāng)該Service第一次被創(chuàng)建后將立即回調(diào)該方法。voidonDestroty():當(dāng)該Service被關(guān)閉時(shí)會(huì)回調(diào)此方法。VoidonStartConmmand(Intentintent,intflags,intstartId):每次客戶端調(diào)用startService(Intent)方法啟動(dòng)該Service時(shí)都會(huì)調(diào)用該方法。BooleanonUnbind(Intentintent):當(dāng)該Service上綁定的所有客戶端都斷開連接時(shí)回調(diào)該方法。六、Service

通過Context的startService()方法啟動(dòng)的服務(wù),訪問者之間沒有關(guān)聯(lián),即使訪問者退出了,Service依然存在。1.創(chuàng)建項(xiàng)目

創(chuàng)建一個(gè)MyService類繼承Service:重寫onCreate(),onDestroy(),onStartCommand(Intentintent,intflags)方法。

6.2啟動(dòng)Service6.2.1使用startService()啟動(dòng)服務(wù)六、ServiceMyService.java文件:六、Service六、Service2.在清單文件中注冊(cè)Service:六、Service4.編寫MainActivity.java文件六、Service

在MainActivity.java類中,定義start(Viewview)方法,格式必須是publicvoidstart(Viewview),方法名必須與布局文件中綁定的方法名一樣。通過view.getId()方法得到觸發(fā)該點(diǎn)擊事件的控件。5.運(yùn)行程序

主界面如圖所示。圖6.1六、Service點(diǎn)擊界面上的開啟按鈕,我們可以看到如圖所示的log輸出:圖6.2六、Service

當(dāng)點(diǎn)擊開啟按鈕時(shí),通過startService(Intentintnent)方法創(chuàng)建服務(wù),可以看到當(dāng)?shù)谝淮伍_啟服務(wù)的時(shí)候,首先調(diào)用了onCreate()方法,然后是onStartCommand()方法。

點(diǎn)擊界面上的停止按鈕,如圖所示。

在此點(diǎn)擊事件中使用stopService()關(guān)閉服務(wù),服務(wù)將調(diào)用onDestroy()方法。圖6.3六、Service

如果Service與訪問者之間需要進(jìn)行方法調(diào)用或者數(shù)據(jù)交換,應(yīng)該使用BindService()方法啟動(dòng):BindService(Intentservice,ServiceConnectionconn,intflags):

參數(shù)service:該參數(shù)通過Intent指定要啟動(dòng)的Service。

參數(shù)flags:指定綁定時(shí)是否自動(dòng)創(chuàng)建Service(如果Service還未創(chuàng)建)。該參數(shù)可指定為0或者BIND_AUTO_CREATE(自動(dòng)創(chuàng)建)。6.2.2使用BindService()啟動(dòng)服務(wù)六、Service

參數(shù)conn:該參數(shù)是一個(gè)ServiceConnection對(duì)象,該對(duì)象用于監(jiān)聽訪問者與Service之間的連接情況。當(dāng)訪問者與Service之間連接成功時(shí)將回調(diào)該ServiceConnection對(duì)象的onServiceConnected(ComponentNamename,IBinderservice)方法;當(dāng)Service所在的宿主進(jìn)程由于異常終止或由于其他原因終止,導(dǎo)致該Service與訪問者之間斷開連接時(shí)回調(diào)該對(duì)象的onServiceDisconnected(ComponentNamename)方法。六、Service

在ServiceConncetion對(duì)象的onServiceConnected方法中有一個(gè)IBinder對(duì)象,利用該對(duì)象可以實(shí)現(xiàn)與綁定的Service之間的通信。

當(dāng)開發(fā)Service類時(shí),該Service類必須提供一個(gè)IBinderonBind(Intentintent)方法,在綁定Service的情況下,onBind(Intentintent)方法返回的IBinder對(duì)象將會(huì)傳給ServiceConnection對(duì)象里的onServiceConnected()方法中的Service參數(shù),這樣訪問者就可通過該IBinder對(duì)象與Service進(jìn)行通信。

開發(fā)時(shí)通常會(huì)采用繼承Binder(IBinder的實(shí)現(xiàn)類)的方式來實(shí)現(xiàn)自己的IBinder對(duì)象。六、Service示例:如何在Activity中綁定本地服務(wù)Service,并獲取Service的運(yùn)行狀態(tài)。該程序的Service類需要“真正”實(shí)現(xiàn)OnBind()方法,并讓該方法返回一個(gè)有效的IBinder對(duì)象。MyBindService.java文件:六、Service六、Service六、Service

上面Service類實(shí)現(xiàn)了onBind()方法,該方法返回了一個(gè)可訪問該Service狀態(tài)數(shù)據(jù)(count)的IBinder對(duì)象,可以將該對(duì)象傳給Service的訪問者。

①號(hào)代碼通過繼承Binder類實(shí)現(xiàn)了一個(gè)IBinder對(duì)象,這個(gè)MyBinder對(duì)象是Service的內(nèi)部類,這對(duì)于綁定本地Service并與之通信的場(chǎng)景是一種常見的情形。六、Service

接下來用一個(gè)Activity來綁定該Service,并在該Activity中通過MyBinder對(duì)象訪問Service的內(nèi)部狀態(tài)。該Activity的界面上包含三個(gè)按鈕,第一個(gè)綁定Service,第二個(gè)解除綁定,第三個(gè)獲取Service的運(yùn)行狀態(tài)。在布局文件中給三個(gè)按鈕綁定事件監(jiān)聽:MainActivity文件:六、Service

六、Service

六、Service

①號(hào)代碼用于在該Activity與Service連接成功時(shí)獲取Service的onBind()方法所返回的MyBinder對(duì)象;程序的②號(hào)代碼即可通過MyBinder對(duì)象來訪問Service的運(yùn)行狀態(tài)。

運(yùn)行該程序,單擊程序界面中的“綁定”按鈕,即可看到所示LogCat的輸出。圖6.4六、Service

綁定Service時(shí),先啟動(dòng)onCreate方法,再調(diào)用onBind方法,最后是ServiceConncetion中的onServiceConnected方法。點(diǎn)擊解除按鈕,LogCat輸出如圖所示圖6.5六、Service

點(diǎn)擊解除按鈕時(shí),先調(diào)用onUnbind方法,然后是onDestroy方法。

再次點(diǎn)擊綁定后,綁定服務(wù),點(diǎn)擊獲取按鈕,即可得到Service中的count值,如圖所示。圖6.6六、Service

IntentService是Service的子類,使用隊(duì)列來管理請(qǐng)求Intent,每當(dāng)客戶端代碼通過Intent請(qǐng)求啟動(dòng)IntentService時(shí),IntentService會(huì)將該Intent加入隊(duì)列中,然后開啟一條新的工作線程來處理該Intent。處理異步的StartService()請(qǐng)求時(shí)IntentService會(huì)按次序依次處理隊(duì)列中的Intent,該線程保證同一時(shí)刻只處理一個(gè)Intent。由于IntentService使用新的工作線程處理Intent請(qǐng)求,因此IntentService不會(huì)阻塞主線程。

6.3IntentService的使用六、ServiceIntentService的特征:IntentService的內(nèi)部已經(jīng)創(chuàng)建了一個(gè)工作線程,服務(wù)一旦啟動(dòng),這個(gè)工作線程就會(huì)執(zhí)行。IntentService內(nèi)部會(huì)有一個(gè)任務(wù)隊(duì)列,任務(wù)隊(duì)列的每一個(gè)任務(wù)會(huì)保存這次任務(wù)的intent對(duì)象,然后工作線程會(huì)依次從隊(duì)列中取出任務(wù),并且調(diào)用IntentService中的onHandleIntent方法執(zhí)行該任務(wù)。

當(dāng)任務(wù)隊(duì)列中所有的任務(wù)全部執(zhí)行完畢后,任務(wù)就會(huì)自然終止,不需要自己去終止服務(wù)。

如果主動(dòng)去停止這個(gè)服務(wù),那么IntentService會(huì)立即銷毀,但是他的工作線程不會(huì)立即退出,而是要把當(dāng)前正在執(zhí)行的任務(wù)做完后自動(dòng)退出,隊(duì)列中未執(zhí)行的任務(wù)不再執(zhí)行。六、Service示例:包含了兩個(gè)文本框、兩個(gè)按鈕。兩個(gè)按鈕分別啟動(dòng)Service和IntentService,兩個(gè)Service都需要執(zhí)行耗時(shí)任務(wù);兩個(gè)文本框用于顯示耗時(shí)任務(wù)所在的線程。六、Service

在MainActivity.java中,單擊相應(yīng)按鈕時(shí),LogCat會(huì)輸出相應(yīng)的線程名以及執(zhí)行結(jié)果:六、Service六、Service

Activity的兩個(gè)事件處理方法中分別啟動(dòng)MyService以及MyIntentService,其中MyService是繼承Service的子類,而MyIntentService是繼承了IntentService的子類。MyService類的代碼:六、Service六、ServiceMyService在onStartCommand方法中使用線程睡眠的方式模擬了耗時(shí)任務(wù),睡眠了20秒,由于普通Service的執(zhí)行會(huì)阻塞主線程,因此啟動(dòng)該服務(wù)將會(huì)導(dǎo)致程序出現(xiàn)ANR異常。

六、Service當(dāng)點(diǎn)擊“打開Service”按鈕時(shí),Logcat出現(xiàn)如圖所示日志:圖6.7六、ServiceMyService運(yùn)行的線程Id與主線程運(yùn)行的Id是相同,也就是說打開的Service是運(yùn)行在主線程中,在主線程中執(zhí)行耗時(shí)任務(wù)將會(huì)出現(xiàn)ANR異常,執(zhí)行結(jié)果:圖6.8六、Service

點(diǎn)擊“打開IntentService”按鈕,查看LogCat輸出:

主線程Id與Service運(yùn)行的線程Id是不一樣的,證明利用IntentService給耗時(shí)任務(wù)開設(shè)了新的線程,從而正常執(zhí)行耗時(shí)任務(wù)。當(dāng)自定義的類繼承IntentService時(shí),會(huì)自動(dòng)增加帶參數(shù)的構(gòu)造方法,當(dāng)程序執(zhí)行時(shí),會(huì)出現(xiàn)初始化錯(cuò)誤,需要修改有參構(gòu)造為無參構(gòu)造。在構(gòu)造方法中調(diào)用super(“servicename”),servicename即為開設(shè)的線程名。圖6.9六、Service

服務(wù)的分類:

本地服務(wù):服務(wù)和啟動(dòng)它的組件在同一個(gè)進(jìn)程中。

遠(yuǎn)程服務(wù):服務(wù)和啟動(dòng)它的組件在不同的進(jìn)程中。

案例:跨進(jìn)程通信,在一個(gè)進(jìn)程中打開其他進(jìn)程中的服務(wù)。該案例中用到了2個(gè)項(xiàng)目,一個(gè)是遠(yuǎn)程服務(wù)的服務(wù)端,另一個(gè)是返回遠(yuǎn)程服務(wù)的客服端。在客服端中,定義一個(gè)MyRemoteService類以及一個(gè)PublishFind接口。

MyRemoteService的代碼:

6.4遠(yuǎn)程服務(wù)(AIDL)六、Service六、Service六、Service

在清單文件中注冊(cè)該service并且指定它的action:PublicFind.java:提供了一個(gè)find()方法。六、Service

客服端:新建一個(gè)項(xiàng)目,項(xiàng)目名為“開啟服務(wù)”。MainActivity的布局文件有5個(gè)按鈕,依次為開啟服務(wù)、關(guān)閉服務(wù)、綁定服務(wù)、解除綁定和遠(yuǎn)程調(diào)用。布局文件如下:六、Service六、ServiceMainActivty中,當(dāng)點(diǎn)擊開啟服務(wù)和關(guān)閉服務(wù)時(shí)代碼如下。其他幾個(gè)按鈕的點(diǎn)擊事件暫不處理,先觀察是否能遠(yuǎn)程打開另外一個(gè)程序的服務(wù):六、Service

上面代碼中使用隱式啟動(dòng)服務(wù)(加粗部分所示)。先運(yùn)行遠(yuǎn)程服務(wù)端,運(yùn)行后,再啟動(dòng)客戶端??头诉\(yùn)行如圖,依次點(diǎn)擊開啟服務(wù)和關(guān)閉服務(wù)。圖6.10六、Service點(diǎn)擊按鈕,觀察LogCat輸出,如圖:圖6.11六、ServiceAIDL:AndroidInterfaceDefinitionLanguage(安卓接口定義語言)。

作用:跨進(jìn)程通信。

應(yīng)用場(chǎng)景:遠(yuǎn)程服務(wù)中的“代理”對(duì)象,其他應(yīng)用是拿不到的,那么在通過綁定服務(wù)獲取“代理”對(duì)象時(shí),就無法強(qiáng)制轉(zhuǎn)換。使用AIDL,就可以在其他應(yīng)用中拿到“代理”類所實(shí)現(xiàn)的接口。

使用AIDL的步驟:(1)把遠(yuǎn)程服務(wù)需要用到的遠(yuǎn)程方法抽成一個(gè)單獨(dú)的接口java文件。(2)把接口java文件的后綴名改成aidl。六、Service

(3)在gen文件下一個(gè)自動(dòng)生成的文件里,有一個(gè)靜態(tài)抽象類Stub,它已經(jīng)繼承了Binder和實(shí)現(xiàn)“代理”接口,這個(gè)類就是新的“代理”類,繼承這個(gè)“代理”類即可。(4)把a(bǔ)idl文件復(fù)制粘貼到新的項(xiàng)目里面,aidl文件所在的包名必須跟遠(yuǎn)程服務(wù)AIDL的包名完全一致,在新的項(xiàng)目也會(huì)自動(dòng)生成Stub靜態(tài)類。(5)在客戶端的ServiceConncetion實(shí)現(xiàn)類中,直接使用Stub.asInterface(service)得到“代理”對(duì)象,通過“代理”對(duì)象調(diào)用遠(yuǎn)程服務(wù)中的方法。

根據(jù)這5步來修改上一案例:

修改PublicFind.java類,改變后綴名為aidl,注意去掉接口的public修飾符,修改完成后,在gen文件夾下會(huì)自動(dòng)生成一個(gè)PublicFind.java類,如圖所示。六、Service圖6.12六、Service

改變PublicFind的后綴名后,MyRemoteService將會(huì)報(bào)錯(cuò),修改后如圖:圖6.13六、Service

此時(shí),“代理”對(duì)象不再繼承Binder實(shí)現(xiàn)PublicFind

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論