鴻蒙應(yīng)用程序開發(fā) 課件 第8、9章 Service Ability、Data Ability_第1頁
鴻蒙應(yīng)用程序開發(fā) 課件 第8、9章 Service Ability、Data Ability_第2頁
鴻蒙應(yīng)用程序開發(fā) 課件 第8、9章 Service Ability、Data Ability_第3頁
鴻蒙應(yīng)用程序開發(fā) 課件 第8、9章 Service Ability、Data Ability_第4頁
鴻蒙應(yīng)用程序開發(fā) 課件 第8、9章 Service Ability、Data Ability_第5頁
已閱讀5頁,還剩94頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第8章ServiceAbility1引言本章學(xué)習(xí)目標(biāo)理解HarmonyOS應(yīng)用服務(wù)(ServiceAbility)的基本概念熟練掌握創(chuàng)建Service的步驟理解ServiceAbility的生命周期2掌握以不同方式啟動服務(wù)的方法了解前臺服務(wù)的使用第8章ServiceAbility8.1ServiceAbility概述8.2Service的創(chuàng)建及啟動8.3生命周期38.4前臺服務(wù)8.1ServiceAbility概述4HarmonyOS系統(tǒng)提供的ServiceAbility(以后簡稱“Service”)不提供用戶交互界面。Service可由其他應(yīng)用或Ability啟動,即使用戶切換到其他應(yīng)用,Service仍將在后臺繼續(xù)運(yùn)行。在實際應(yīng)用中,有很多應(yīng)用需要使用Service,如執(zhí)行音樂播放、文件下載等。Service適用于無須用戶干預(yù),且規(guī)則或長期運(yùn)行的后臺功能。首先,因為Service沒有用戶界面,所以其有利于降低系統(tǒng)資源消耗。即使Service被系統(tǒng)終止,在系統(tǒng)資源恢復(fù)后Service也將自動恢復(fù)運(yùn)行狀態(tài),因此可以認(rèn)為Service是在系統(tǒng)中永久運(yùn)行的組件。Service是單實例的。在一個設(shè)備上,相同的Service只會存在一個實例。如果多個Ability共用這個Service實例,只有當(dāng)與Service綁定的所有Ability都退出后,Service才能夠退出。由于Service是在主線程里執(zhí)行的,因此,如果在Service里面的操作時間過長,開發(fā)者必須在Service里創(chuàng)建新的線程來處理(詳見第7章線程管理與線程通信),防止造成主線程阻塞,應(yīng)用程序無響應(yīng)。8.1ServiceAbility概述5Service在應(yīng)用配置文件中需要注冊,注冊類型type為service,config.json文件中示例代碼如下:{ "name": "com.example.serviceabilitylifecycle.ServiceAbility", "description":"$string:serviceability_description", "type":"service", "backgroundModes":[], "icon":"$media:icon"}上述代碼中:backgroundModes:后臺模式屬性配置選項,這里只需要演示生命周期,所以數(shù)組里面為空。dataTransfer:數(shù)據(jù)上傳/下載、備份/恢復(fù)。audioPlayback:音頻播放。audioRecording:錄音。pictureInPicture:畫中畫。voip:IP語音/視頻通話。location:位置。bluetoothInteraction:藍(lán)牙通信。wifiInteraction:Wifi通信。multiDeviceConnection:多設(shè)備連接。第8章ServiceAbility8.3生命周期68.4前臺服務(wù)8.2Service的創(chuàng)建及啟動8.1ServiceAbility概述8.2.1Service的創(chuàng)建7創(chuàng)建一個名為ServiceCommandStartLifeCycle的應(yīng)用來演示創(chuàng)建Service及以命令方式啟動Service時的生命周期。在Project窗口中,打開“entry/src/main/java”,右鍵點(diǎn)擊包(com.example.servicecommandstartlifecycle),選擇“New/Ability/ServiceAbility”,然后進(jìn)入Service配置頁面,如下圖所示。8.2.1Service的創(chuàng)建8在配置頁面中,設(shè)置Abilityname:ServiceAbility,Packagename為包名,如下圖所示。8.2.1Service的創(chuàng)建9在上圖中,Enablebackgroundmode:是否啟用后臺模式。其下各種模式對應(yīng)config.json文件中“backgroundModes”配置選項中的屬性。因為只需要演示Service的生命周期,不涉及后臺模式中的功能,所以選擇不使用后臺模式,點(diǎn)擊Finish完成創(chuàng)建。新創(chuàng)建的Service示例代碼如下:publicclassServiceAbilityextendsAbility{privatestaticfinalHiLogLabelLABEL_LOG=newHiLogLabel(3,0xD001100,"Demo");@OverridepublicvoidonStart(Intentintent){HiLog.error(LABEL_LOG,"ServiceAbility::onStart");super.onStart(intent);}@OverridepublicvoidonBackground(){super.onBackground();HiL(LABEL_LOG,"ServiceAbility::onBackground");}8.2.1Service的創(chuàng)建10@OverridepublicvoidonBackground(){super.onBackground();HiL(LABEL_LOG,"ServiceAbility::onBackground");}@OverridepublicvoidonStop(){super.onStop();HiL(LABEL_LOG,"ServiceAbility::onStop");}@OverridepublicvoidonCommand(Intentintent,booleanrestart,intstartId){}@OverridepublicIRemoteObjectonConnect(Intentintent){returnnull;}@OverridepublicvoidonDisconnect(Intentintent){}}8.2.1Service的創(chuàng)建11下面介紹Service的各個生命周期方法:onStart():該方法在創(chuàng)建Service的時候調(diào)用,用于Service的初始化。在Service的整個生命周期中只會調(diào)用一次,調(diào)用時傳入的Intent應(yīng)為空。onCommand():在Service創(chuàng)建完成之后調(diào)用,該方法在客戶端每次啟動該Srvice時都會調(diào)用,讀者可以在該方法中做一些調(diào)用統(tǒng)計、初始化類的操作。onConnect():在Ability與Service連接時調(diào)用,該方法返回IRemoteObject對象,讀者可以在該回調(diào)函數(shù)中生成對應(yīng)Service的IPC通信通道,以便Ability與Service交互。Ability可以多次連接同一個Service,系統(tǒng)會緩存該Service的IPC通信對象,只有第一個客戶端連接Service時,系統(tǒng)才會調(diào)用Service的onConnect方法來生成IRemoteObject對象,而后系統(tǒng)會將同一個IRemoteObject對象傳遞至其他連接同一個Service的所有客戶端,而無需再次調(diào)用onConnect方法。onDisconnect():在Ability與綁定的Service斷開連接時調(diào)用。onStop():在Service銷毀時調(diào)用。Service應(yīng)通過實現(xiàn)此方法來清理任何資源,如關(guān)閉線程、注冊的偵聽器等。8.2.1Service的創(chuàng)建12同時,創(chuàng)建完Service后,在config.json文件中會自動生成Service相關(guān)的配置信息。{"name":"com.example.servicecommandstartlifecycle.ServiceAbility","description":"$string:serviceability_description","type":"service","backgroundModes":[],"icon":"$media:icon"}8.2.2Service的啟動與停止13啟動Service在HarmonyOS系統(tǒng)中,Ability為讀者提供了startAbility()方法來啟動另外一個Ability。因為Service也是Ability的一種,所以讀者同樣可以通過將Intent傳遞給該方法來啟動Service。HarmonyOS不僅支持啟動本地Service,還支持啟動遠(yuǎn)程Service。啟動本地設(shè)備Service的代碼示例如下:Intentintent=newIntent();Operationoperation=newIntent.OperationBuilder().withDeviceId("").withBundleName("com.example.serviceabilitylifecycle").withAbilityName("com.example.serviceabilitylifecycle.ServiceAbility").build();intent.setOperation(operation);startAbility(intent);8.2.2Service的啟動與停止14啟動遠(yuǎn)程設(shè)備Service的代碼示例如下:Intentintent=newIntent();Operationoperation=newIntent.OperationBuilder().withDeviceId("deviceId").withBundleName("com.example.serviceabilitylifecycle").withAbilityName("com.example.serviceabilitylifecycle.ServiceAbility")//設(shè)置支持分布式調(diào)度系統(tǒng)多設(shè)備啟動的標(biāo)識

.withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE).build();intent.setOperation(operation);startAbility(intent);8.2.2Service的啟動與停止15停止ServiceService一旦創(chuàng)建就會一直保持在后臺運(yùn)行,除非必須回收內(nèi)存資源,否則系統(tǒng)不會停止或銷毀Service。開發(fā)者可以在Service中通過terminateAbility()方法停止本Service或在其他Ability中調(diào)用stopAbility()來停止Service。停止Service同樣支持停止本地設(shè)備Service和停止遠(yuǎn)程設(shè)備Service,使用方法與啟動Service一樣。一旦調(diào)用停止Service的方法,系統(tǒng)便會盡快銷毀Service。執(zhí)行上述代碼后,Ability將通過startAbility()方法來啟動Service。如果Service尚未運(yùn)行,則系統(tǒng)會先調(diào)用onStart()來初始化Service,再回調(diào)Service的onCommand()方法來啟動Service。如果Service正在運(yùn)行,則系統(tǒng)會直接回調(diào)Service的onCommand()方法來啟動Service。8.2.3Service的連接與斷開連接16連接Service如果Service需要與Page或其他應(yīng)用的Service進(jìn)行交互,則需要創(chuàng)建用于連接的Connection。Service支持其他Ability通過connectAbility()方法與其進(jìn)行連接。創(chuàng)建連接Service回調(diào)實例的示例代碼如下://創(chuàng)建連接Service回調(diào)實例privateIAbilityConnectionconnection=newIAbilityConnection(){//連接到Service的回調(diào) @Override publicvoidonAbilityConnectDone(ElementNameelementName ,IRemoteObjectiRemoteObject ,intresultCode){//Client端需要定義與Service端相同的IRemoteObject實現(xiàn)類。 //Service異常死亡的回調(diào)

@Override publicvoidonAbilityDisconnectDone(ElementNameelementName ,intresultCode){}}8.2.3Service的連接與斷開連接17連接Service的代碼示例如下//連接ServiceIntentintent=newIntent();Operationoperation=newIntent.OperationBuilder().withDeviceId("deviceId").withBundleName("com.example.serviceabilitylifecycle").withAbilityName("com.example.serviceabilitylifecycle.ServiceAbility").build();intent.setOperation(operation);connectAbility(intent,connection);同時,Service端也需要在onConnect()方法執(zhí)行時返回IRemoteObject,從而定義與Service進(jìn)行通信的接口。onConnect()需要返回一個IRemoteObject對象,HarmonyOS提供了IRemoteObject的默認(rèn)實現(xiàn),用戶可以通過繼承LocalRemoteObject來創(chuàng)建自定義的實現(xiàn)類。8.2.3Service的連接與斷開連接18Service端把自身的實例返回給調(diào)用端的代碼示例如下://創(chuàng)建自定義IRemoteObject實現(xiàn)類privateclassMyRemoteObjectextendsLocalRemoteObject{MyRemoteObject(){}}//把IRemoteObject返回給客戶端@OverrideprotectedIRemoteObjectonConnect(Intentintent){returnnewMyRemoteObject();}斷開連接在其他Ability中只需要調(diào)用disconnectAbility()方法即可斷開與Service的連接。該方法的參數(shù)是用于連接的connection。示例代碼如下:disconnectAbility(connection);第8章ServiceAbility8.2Service的創(chuàng)建及啟動198.4前臺服務(wù)8.3生命周期8.1ServiceAbility概述8.3生命周期20生命周期與Page類似,Service也擁有生命周期。服務(wù)有兩種啟動方式,一是以命令方式啟動服務(wù),二是以連接方式啟動服務(wù)。根據(jù)啟動方式的不同,服務(wù)生命周期過程有兩種不同的情況。當(dāng)以命令方式啟動服務(wù)時,服務(wù)對象會在首次啟動時通過onStart()方法創(chuàng)建,緊接著服務(wù)會執(zhí)行onCommand()方法,之后服務(wù)開始進(jìn)入并保持活動態(tài)。處于活動態(tài)的服務(wù),再次以命令方式啟動時,即通過startAbility()方法啟動服務(wù)時,服務(wù)會直接執(zhí)行onCommand()方法,而不需要再次執(zhí)行onStart()方法。服務(wù)被停止時,服務(wù)會執(zhí)行onStop()方法,之后系統(tǒng)會將服務(wù)銷毀。以命令方式啟動非活動態(tài)的服務(wù)的生命周期過程如圖所示。8.3生命周期21當(dāng)以連接方式啟動Service時,其他Ability通過執(zhí)行connectAbility()方法啟動并創(chuàng)建Service,Service在首次被連接時,會執(zhí)行onStart()方法初始化Serivce。緊接著Service會執(zhí)行onConnect()方法,之后Service便進(jìn)入活動態(tài)。該方法會返回一個連接引用,供連接者訪問Service。多個請求者可以連接同一個以連接方式啟動的Service。請求端可通過disconnectAbility()方法斷開與Service的連接,而且當(dāng)所有連接全部斷開后,系統(tǒng)才會銷毀Service。當(dāng)請求者斷開與Service的連接時,Service會調(diào)用對應(yīng)的onDisconnect方法。以連接方式啟動非活動態(tài)的Service生命周期的過程如圖所示。8.3.1案例:命令啟動Service生命周期22為了更好地理解Service的生命周期,我們將繼續(xù)使用8.2.1節(jié)中創(chuàng)建的ServiceCommandStartLifeCycle應(yīng)用繼續(xù)來演示Service的生命周期。在ability_main.xml文件中,其內(nèi)容如下:<?xmlversion="1.0"encoding="utf-8"?><DirectionalLayoutxmlns:ohos="/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="top"ohos:orientation="vertical"><Textohos:height="match_content"ohos:width="match_content"ohos:background_element="$graphic:background_ability_main"ohos:layout_alignment="horizontal_center"ohos:margin="10vp"ohos:text="Service命令啟動生命周期案例"ohos:text_size="20fp"/>8.3.1案例:命令啟動Service生命周期23<Buttonohos:id="$+id:Btn_Start"ohos:height="match_content"ohos:width="match_parent"ohos:background_element="$graphic:background_ability_main_button"ohos:layout_alignment="horizontal_center"ohos:margin="20vp"ohos:padding="5vp"ohos:text="啟動服務(wù)"ohos:text_size="28fp"/><Buttonohos:id="$+id:Btn_Stop"ohos:height="match_content"ohos:width="match_parent"ohos:background_element="$graphic:background_ability_main_button"ohos:layout_alignment="horizontal_center"ohos:margin="20vp"ohos:padding="5vp"ohos:text="停止服務(wù)"ohos:text_size="28fp"/>8.3.1案例:命令啟動Service生命周期24<?xmlversion="1.0"encoding="UTF-8"?><shape xmlns:ohos="/res/ohos" ohos:shape="rectangle"> <solid ohos:color="#0aabbc"/> <cornersohos:radius="50vp"/></shape>Button組件引用了background_ability_main_button.xml文件,修飾了其背景,形狀,其內(nèi)容如下:8.3.1案例:命令啟動Service生命周期25修改ServiceAbility,其內(nèi)容如下:publicclassServiceAbilityextendsAbility{//定義日志標(biāo)簽

privatestaticfinalHiLogLabelLABEL_LOG=newHiLogLabel(HiLog.LOG_APP,0x00922,"ServiceAbility");//在創(chuàng)建Service時會調(diào)用該方法,用于Service的初始化

@OverridepublicvoidonStart(Intentintent){HiL(LABEL_LOG,"onStart");super.onStart(intent);}//當(dāng)Service進(jìn)入后臺時調(diào)用

@OverridepublicvoidonBackground(){HiL(LABEL_LOG,"onBackground");super.onBackground();}8.3.1案例:命令啟動Service生命周期26//在Service銷毀時調(diào)用,該方法將清空資源

@OverridepublicvoidonStop(){HiL(LABEL_LOG,"onStop");super.onStop();}//在Service創(chuàng)建完成之后調(diào)用

@OverridepublicvoidonCommand(Intentintent,booleanrestart,intstartId){HiL(LABEL_LOG,"onCommand");}//在Ability和Service連接時調(diào)用

@OverridepublicIRemoteObjectonConnect(Intentintent){HiL(LABEL_LOG,"onConnect");returnnull;}8.3.1案例:命令啟動Service生命周期27publicclassMainAbilitySliceextendsAbilitySlice{//定義日志標(biāo)簽

privatestaticfinalHiLogLabelLABEL_LOG=newHiLogLabel(HiLog.LOG_APP,0x00922,"MainAbilitySlice");@OverridepublicvoidonStart(Intentintent){super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);//找到組件

ButtonBtn_Start=findComponentById(ResourceTable.Id_Btn_Start);ButtonBtn_Stop=findComponentById(ResourceTable.Id_Btn_Stop);//給Btn_Start添加單擊事件,啟動ServiceBtn_Start.setClickedListener(component->{HiL(LABEL_LOG,"啟動服務(wù)按鈕被點(diǎn)擊!");//創(chuàng)建Intent對象

Intentintent1=newIntent();

修改MainAbilitySlice,其內(nèi)容如下:8.3.1案例:命令啟動Service生命周期28 //創(chuàng)建Operation對象,構(gòu)建操作方式

Operationoperation=newIntent.OperationBuilder().withDeviceId("")//包名稱

.withBundleName("com.example.servicecommandstartlifecycle")//待啟動的Ability名稱

.withAbilityName("com.example.servicecommandstartlifecycle"+".ServiceAbility").build();intent2.setOperation(operation);//停止ServicestopAbility(intent2);});}

8.3.1案例:命令啟動Service生命周期29@OverridepublicvoidonActive(){super.onActive();}@OverridepublicvoidonForeground(Intentintent){super.onForeground(intent);}}8.3.1案例:命令啟動Service生命周期30上述代碼在MainAbilitySlice的onStart()方法中找到各個按鈕組件,并為其添加單擊事件,以命令方式啟動Service。打開遠(yuǎn)程模擬器,運(yùn)行程序,應(yīng)用初始頁面如下圖所示。8.3.1案例:命令啟動Service生命周期31單擊“啟動服務(wù)”按鈕,控制臺輸出內(nèi)容如下: 07-0520:00:09.62611313-11313/com.example.servicecommandstartlifecycleI00922/MainAbilitySlice:啟動服務(wù)按鈕被點(diǎn)擊! 07-0520:00:09.65311313-11313/com.example.servicecommandstartlifecycleI00922/ServiceAbility:onStart 07-0520:00:09.65611313-11313/com.example.servicecommandstartlifecycleI00922/ServiceAbility:onCommand繼續(xù)單擊“停止服務(wù)”按鈕,控制臺輸出內(nèi)容如下: 07-0520:00:18.05111313-11313/com.example.servicecommandstartlifecycleI00922/MainAbilitySlice:啟動服務(wù)按鈕被點(diǎn)擊! 07-0520:00:18.06011313-11313/com.example.servicecommandstartlifecycleI00922/ServiceAbility:onBackground 07-0520:00:18.06111313-11313/com.example.servicecommandstartlifecycleI00922/ServiceAbility:onStop8.3.2案例:連接啟動Service生命周期32創(chuàng)建一個名為ServiceConnectionStartupLifeCycle的應(yīng)用來演示以連接方式啟動Service時的生命周期。頁面需要一個連接按鈕和一個斷開連接按鈕,XML文件中的內(nèi)容可參考8.3.1節(jié)案例。

與命令啟動Service相同,首先需要創(chuàng)建一個Service,對其做如下修改:publicclassServiceAbilityextendsAbility{//定義日志標(biāo)簽

privatestaticfinalHiLogLabelLABEL_LOG=newHiLogLabel(HiLog.LOG_APP,0x00922,"ServiceAbility");//在創(chuàng)建Service時會調(diào)用該方法,用于Service的初始化

@OverridepublicvoidonStart(Intentintent){HiL(LABEL_LOG,"onStart");super.onStart(intent);}//當(dāng)Service進(jìn)入后臺時調(diào)用

@OverridepublicvoidonBackground(){HiL(LABEL_LOG,"onBackground");super.onBackground();}8.3.2案例:連接啟動Service生命周期//在Service銷毀時調(diào)用,該方法將清空資源

@OverridepublicvoidonStop(){HiL(LABEL_LOG,"onStop");super.onStop();}//在Service創(chuàng)建完成之后調(diào)用

@OverridepublicvoidonCommand(Intentintent,booleanrestart,intstartId){HiL(LABEL_LOG,"onCommand");}//在Ability和Service連接時調(diào)用

@OverridepublicIRemoteObjectonConnect(Intentintent){HiL(LABEL_LOG,"onConnect");returnnewLocalRemoteObject(){};}//在Ability與綁定的Service斷開連接時調(diào)用

@OverridepublicvoidonDisconnect(Intentintent){HiL(LABEL_LOG,"onDisconnect");}}8.3.2案例:連接啟動Service生命周期在連接Service之前,需要先創(chuàng)建連接Service回調(diào)實例,創(chuàng)建用于連接的Connection,修改MainAbilitySlice,其內(nèi)容如下:publicclassMainAbilitySliceextendsAbilitySlice{//定義日志標(biāo)簽

privatestaticfinalHiLogLabelLABEL_LOG=newHiLogLabel(HiLog.LOG_APP,0x00922,"MainAbilitySlice");//創(chuàng)建連接Service回調(diào)實例

privatefinalIAbilityConnectionconnection=newIAbilityConnection(){//連接到Service的回調(diào)

@OverridepublicvoidonAbilityConnectDone(ElementNameelementName,IRemoteObjectiRemoteObject,intresultCode){HiL(LABEL_LOG,"連接成功!");}//Service異常死亡的回調(diào)

@OverridepublicvoidonAbilityDisconnectDone(ElementNameelementName,intresultCode){HiL(LABEL_LOG,"連接失敗!");}};8.3.2案例:連接啟動Service生命周期@OverridepublicvoidonStart(Intentintent){super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);//找到組件

ButtonBtn_Connect=findComponentById(ResourceTable.Id_Btn_Connect);ButtonBtn_Disconnect=findComponentById(ResourceTable.Id_Btn_Disconnect);//給Btn_Connect添加單擊事件,連接ServiceBtn_Connect.setClickedListener(component->{HiL(LABEL_LOG,"連接服務(wù)按鈕被點(diǎn)擊!");//創(chuàng)建Intent對象

Intentintent1=newIntent();//創(chuàng)建Operation對象,構(gòu)建操作方式

Operationoperation=newIntent.OperationBuilder().withDeviceId("").withBundleName("com.example"+".serviceconnectionstartuplifecycle").withAbilityName("com.example"+".serviceconnectionstartuplifecycle.ServiceAbility").build();intent1.setOperation(operation);//連接ServiceconnectAbility(intent1,connection);});8.3.2案例:連接啟動Service生命周期//給Btn_Disconnect添加單擊事件,斷開與Service連接

Btn_Disconnect.setClickedListener(component->{HiL(LABEL_LOG,"斷開連接服務(wù)按鈕被點(diǎn)擊!");//如果連接存在,則調(diào)用disconnectAbility()方法斷開連接

if(connection!=null){disconnectAbility(connection);}});}@OverridepublicvoidonActive(){super.onActive();}@OverridepublicvoidonForeground(Intentintent){super.onForeground(intent);}}8.3.2案例:連接啟動Service生命周期查看ServiceAbility中的onConnect()方法,其返回的IRemoteObject對象為LocalRemoteObject對象,沒有自定義實現(xiàn)類,這是因為演示Service的生命周期不需要做其它處理,所以直接使用LocalRemoteObject對象較為簡便。打開遠(yuǎn)程模擬器,運(yùn)行程序,應(yīng)用初始頁面如下圖所示:8.3.2案例:連接啟動Service生命周期38單擊“連接服務(wù)”按鈕,控制臺輸出內(nèi)容如下: 07-0613:01:21.92228861-28861/com.example.serviceconnectionstartuplifecycleI00922/MainAbilitySlice:連接服務(wù)按鈕被點(diǎn)擊! 07-0613:01:21.93528861-28861/com.example.serviceconnectionstartuplifecycleI00922/ServiceAbility:[ab5e274aa1e153d,3b6704a,30b0362]onStart 07-0613:01:21.93728861-28861/com.example.serviceconnectionstartuplifecycleI00922/ServiceAbility:[ab5e274aa1e153d,1fd0dc8,3a781f4]onConnect 07-0613:01:21.94028861-28861/com.example.serviceconnectionstartuplifecycleI00922/MainAbilitySlice:[ab5e274aa1e153d,1cac63b,a810db]連接成功!繼續(xù)單擊“斷開連接”按鈕,控制臺輸出內(nèi)容如下: 07-0613:01:51.53228861-28861/com.example.serviceconnectionstartuplifecycleI00922/MainAbilitySlice:斷開連接服務(wù)按鈕被點(diǎn)擊! 07-0613:01:51.53728861-28861/com.example.serviceconnectionstartuplifecycleI00922/ServiceAbility:[ab5e284abf823b9,2eed551,cbcc0f]onDisconnect 07-0613:01:51.54128861-28861/com.example.serviceconnectionstartuplifecycleI00922/ServiceAbility:[ab5e284abf823b9,35c8468,e94489]onBackground 07-0613:01:51.54128861-28861/com.example.serviceconnectionstartuplifecycleI00922/ServiceAbility:[ab5e284abf823b9,35c8468,e94489]onStop第8章ServiceAbility8.2Service的創(chuàng)建及啟動398.1ServiceAbility概述8.4前臺服務(wù)8.3生命周期8.4.1基本概念40通常情況下,一般情況下,服務(wù)在后臺運(yùn)行,具有低優(yōu)先級且可能被系統(tǒng)回收。后臺服務(wù)在界面不可見,難以感知。有時,用戶希望服務(wù)持續(xù)運(yùn)行且在前臺顯示相關(guān)信息,此時可使用前臺服務(wù)。前臺服務(wù)并非前臺實際運(yùn)行,而是在狀態(tài)欄展示運(yùn)行信息。通過綁定通知實現(xiàn)前臺服務(wù),創(chuàng)建時調(diào)用keepBackgroundRunning()方法連接服務(wù)與通知。前臺服務(wù)能在狀態(tài)欄展示運(yùn)行信息,需修改Service的onStart()方法。//創(chuàng)建通知請求對象,其中922為notificationIdNotificationRequestrequest=newNotificationRequest(922);//創(chuàng)建普通文本通知對象NotificationRequest.NotificationNormalContentcontent= newNotificationRequest.NotificationNormalContent();content.setTitle("音樂播放器").setText("后臺音樂正在播放中。");//創(chuàng)建NotificationContent通知內(nèi)容對象NotificationRequest.NotificationContentnotificationContent= newNotificationRequest.NotificationContent(content);//設(shè)置通知內(nèi)容request.setContent(notificationContent);//綁定通知,922為創(chuàng)建通知時傳入的notificationIdkeepBackgroundRunning(922,request);8.4.1基本概念41前臺服務(wù)必須在config.json配置文件中進(jìn)行后臺模式配置,假設(shè)前臺服務(wù)的Service名為MusicServiceAbility,其功能為一個可以在后臺播放音樂的音樂播放器,那么設(shè)置其后臺模式的相關(guān)代碼如下:{ "name":"com.example.serviceabilitydemo.MusicServiceAbility", "description":"$string:musicserviceability_description", "type":"service", "backgroundModes":[ "audioPlayback" ], "icon":"$media:icon"}8.4.1基本概念42使用前臺服務(wù)功能還需要進(jìn)行權(quán)限聲明,在config.json文件中聲明權(quán)限代碼如下:"reqPermissions":[ { "name":"ohos.permission.KEEP_BACKGROUND_RUNNING" }]當(dāng)前臺服務(wù)終止時,需要取消前臺服務(wù)的運(yùn)行狀態(tài),重寫服務(wù)的onStop()方法,并在其中調(diào)用cancelBackgroundRunning()方法,這樣在服務(wù)生命周期結(jié)束時,會自動取消服務(wù)的運(yùn)行狀態(tài)。前臺服務(wù)啟動后會顯示在系統(tǒng)的通知欄中,通知的內(nèi)容完全取決于創(chuàng)建前臺服務(wù)時設(shè)置的通知內(nèi)容。在服務(wù)運(yùn)行過程中,應(yīng)用可以根據(jù)通知ID更新通知內(nèi)容,反饋服務(wù)的運(yùn)行相關(guān)信息,使用戶可以實時感知到服務(wù)的運(yùn)行狀態(tài)。打開系統(tǒng)通知欄顯示的通知信息和非前臺服務(wù)的通知信息是類似的,不同的是前臺服務(wù)發(fā)出的通知和服務(wù)進(jìn)行了綁定,顯示的內(nèi)容和服務(wù)具有相關(guān)性。8.4.2案例:音樂播放器43創(chuàng)建一個名為MusicPlayerDemo的應(yīng)用作為演示,其功能為一個可以在后臺運(yùn)行的音樂播放器,并可以用命令啟動和連接啟動兩種啟動方式啟動服務(wù)。首先下載MP3歌曲資源,本例為“Music.flac”。歌曲資源文件后綴支持多種格式。將歌曲資源放入“resource/rawfile”文件夾中。如下圖所示。8.4.2案例:音樂播放器44在config.json文件中進(jìn)行前臺服務(wù)功能權(quán)限聲明,其內(nèi)容如下:"reqPermissions":[{"name":"ohos.permission.KEEP_BACKGROUND_RUNNING"}]創(chuàng)建一個名為“MusicServiceAbility”的Service,后臺模式選擇“Audioplayback”,修改其內(nèi)容如下:publicclassMusicServiceAbilityextendsAbility{//定義Player播放器

privatePlayerMyPlayer;//定義Player播放器1privatePlayerMyPlayer1;//定義日志標(biāo)簽

privatestaticfinalHiLogLabelLABEL_LOG=newHiLogLabel(HiLog.LOG_APP,0x00922,"MusicServiceAbility");8.4.2案例:音樂播放器45//在創(chuàng)建Service時會調(diào)用該方法,用于Service的初始化

@OverridepublicvoidonStart(Intentintent){HiL(LABEL_LOG,"onStart方法被調(diào)用");super.onStart(intent);//創(chuàng)建通知請求對象,其中922為notificationIdNotificationRequestrequest=newNotificationRequest(922);//創(chuàng)建普通文本通知對象

NotificationRequest.NotificationNormalContentcontent=newNotificationRequest.NotificationNormalContent();content.setTitle("音樂播放器").setText("后臺音樂正在播放中。");//創(chuàng)建NotificationContent通知內(nèi)容對象

NotificationRequest.NotificationContentnotificationContent=newNotificationRequest.NotificationContent(content);//設(shè)置通知內(nèi)容

request.setContent(notificationContent);//綁定通知,922為創(chuàng)建通知時傳入的notificationIdkeepBackgroundRunning(922,request);}8.4.2案例:音樂播放器46//當(dāng)Service即將進(jìn)入BACKGROUND狀態(tài)時調(diào)用

@OverridepublicvoidonBackground(){HiL(LABEL_LOG,"onBackground被調(diào)用");super.onBackground();}//在Service銷毀時調(diào)用,該方法將清空資源

@OverridepublicvoidonStop(){HiL(LABEL_LOG,"onStop被調(diào)用");//停止播放

MyPlayer.stop();//釋放緩存

MyPlayer.release();cancelBackgroundRunning();super.onStop();}8.4.2案例:音樂播放器47//在Service創(chuàng)建完成之后調(diào)用

@OverridepublicvoidonCommand(Intentintent,booleanrestart,intstartId){HiL(LABEL_LOG,"onCommand方法被調(diào)用");//初始化播放器

initPlayer();HiL(LABEL_LOG,"開始播放!");//開始播放

MyPlayer.play();}//在Ability和Service連接時調(diào)用

@OverridepublicIRemoteObjectonConnect(Intentintent){HiL(LABEL_LOG,"onConnect方法被調(diào)用");returnnewMusicWithPlayer();}

8.4.2案例:音樂播放器48//在Ability與綁定的Service斷開連接時調(diào)用

@OverridepublicvoidonDisconnect(Intentintent){HiL(LABEL_LOG,"onDisconnect方法被調(diào)用");MyPlayer1.stop();MyPlayer1.release();}//初始化Player對象

publicvoidinitPlayer(){HiL(LABEL_LOG,"initPlayer()方法被調(diào)用");//創(chuàng)建播放器對象

MyPlayer=newPlayer(this);try{//打開播放音頻源文件

RawFileDescriptorrawFileDescriptor=getResourceManager().getRawFileEntry("resources/rawfile/Music.flac").openRawFileDescriptor();Sourcesource=newSource(rawFileDescriptor.getFileDescriptor(),rawFileDescriptor.getStartPosition(),rawFileDescriptor.getFileSize());8.4.2案例:音樂播放器49 //設(shè)置音頻源

MyPlayer.setSource(source);}catch(Exceptione){HiL(LABEL_LOG,"Player初始化失敗!");}HiL(LABEL_LOG,"準(zhǔn)備播放!");//準(zhǔn)備播放

MyPlayer.prepare();}//自定義遠(yuǎn)程對象類MusicWithPlayerpublicclassMusicWithPlayerextendsLocalRemoteObject{//定義日志標(biāo)簽

privatefinalHiLogLabelLABEL_LOG=newHiLogLabel(HiLog.LOG_APP,0x00922,"MusicWithPlayer");publicMusicWithPlayer(){HiL(LABEL_LOG,"MusicWithPlayer類已創(chuàng)建!");}8.4.2案例:音樂播放器50 //初始化Player對象

publicvoidinitPlayer1(Contextcontext){ HiL(LABEL_LOG,"initPlayer()方法被調(diào)用"); //創(chuàng)建播放器對象

MyPlayer1=newPlayer(context); try{ //打開播放音頻源文件

RawFileDescriptorrawFileDescriptor=getResourceManager().getRawFileEntry("resources/rawfile/Music.flac").openRawFileDescriptor();Sourcesource=newSource(rawFileDescriptor.getFileDescriptor(),rawFileDescriptor.getStartPosition(),rawFileDescriptor.getFileSize());//設(shè)置音頻源

MyPlayer1.setSource(source);}catch(Exceptione){HiL(LABEL_LOG,"Player初始化失敗!");}HiL(LABEL_LOG,"準(zhǔn)備播放!");8.4.2案例:音樂播放器51 //準(zhǔn)備播放

MyPlayer1.prepare();//全局并發(fā)任務(wù)分發(fā)器,異步分發(fā)播放任務(wù)

TaskDispatchergloTaskDispatcher=getGlobalTaskDispatcher(TaskPriority.DEFAULT);Revocablerevocable=gloTaskDispatcher.asyncDispatch(newRunnable(){@Overridepublicvoidrun(){HiL(LABEL_LOG,"開始播放!");//開始播放

MyPlayer1.play();}});}}}上述代碼分別初始化了兩個音樂播放器,分別對應(yīng)命令方式啟動Service和連接方式啟動Service,并在onStart()方法中初始化了通知,并將通知與服務(wù)進(jìn)行綁定。該案例需要四個按鈕來執(zhí)行啟動,停止Service和連接、斷開Service,XML文件中的內(nèi)容這里不再贅述,可參考Service生命周期案例。修改MainAbilitySlice,詳細(xì)代碼請參考8.4.2節(jié)內(nèi)容。8.4.2案例:音樂播放器52啟動服務(wù)后,觀察遠(yuǎn)程模擬器通知欄,即可看到由Service發(fā)布的通知。如下圖所示。再點(diǎn)擊停止服務(wù)按鈕??刂婆_輸出內(nèi)容如下:05-2819:49:59.3887156-7156/com.example.serviceabilitydemoI00922/MainAbilitySlice:停止Service05-2819:49:59.3977156-7156/com.example.serviceabilitydemoI00922/MusicServiceAbility:onBackground被調(diào)用05-2819:49:59.3987156-7156/com.example.serviceabilitydemoI00922/MusicServiceAbility:onStop被調(diào)用ThankYou第9章DataAbility引言本章學(xué)習(xí)目標(biāo)理解HarmonyOS數(shù)據(jù)應(yīng)用(DataAbility)的基本概念熟悉創(chuàng)建DataAbility的步驟,理解DataAbility中各方法的含義55了解使用DataAbility訪問本地文件熟練對本地數(shù)據(jù)庫進(jìn)行增刪改查第9章DataAbility9.1DataAbility概述9.2Data的創(chuàng)建9.3Data的訪問569.1DataAbility概述57數(shù)據(jù)的存儲方式多種多樣,可以是傳統(tǒng)意義上的數(shù)據(jù)庫系統(tǒng),也可以是本地磁盤上的文件。Data對外提供對數(shù)據(jù)的增、刪、改、查,以及打開文件等接口,這些接口的具體實現(xiàn)由開發(fā)者提供。Data的提供方和使用方都通過URI(UniformResourceIdentifier,統(tǒng)一資源定位符)來標(biāo)識一個具體的數(shù)據(jù),例如數(shù)據(jù)庫中的某個表或磁盤上的某個文件。HarmonyOS的URI仍基于URI通用標(biāo)準(zhǔn)格式如圖所示。dataability:///com.example.addressbookdemo.UserDataAbility/usersdataability://device_id/com.example.addressbookdemo.UserDataAbility/usersURI示例代碼如下:第9章DataAbility9.1DataAbility概述9.2Data的創(chuàng)建9.3Data的訪問589.2Data的創(chuàng)建59創(chuàng)建Data時,首先需要確定數(shù)據(jù)的存儲方式,在Data中不同的數(shù)據(jù)存儲方式給出了不同的操作方法。Data支持以下兩種數(shù)據(jù)形式分別是:文件型數(shù)據(jù)、結(jié)構(gòu)化型數(shù)據(jù)(數(shù)據(jù)庫)。創(chuàng)建一個名為DataAbilityOnFile的應(yīng)用來

溫馨提示

  • 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

提交評論