<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          HarmonyOS學(xué)習(xí)路之開(kāi)發(fā)篇—Service Ability

          共 9312字,需瀏覽 19分鐘

           ·

          2021-07-01 22:04

          點(diǎn)擊上方藍(lán)色字體,關(guān)注我們




          1


          Service Ability基本概念


          基于Service模板的Ability(以下簡(jiǎn)稱(chēng)“Service”)主要用于后臺(tái)運(yùn)行任務(wù)(如執(zhí)行音樂(lè)播放、文件下載等),但不提供用戶(hù)交互界面。Service可由其他應(yīng)用或Ability啟動(dòng),即使用戶(hù)切換到其他應(yīng)用,Service仍將在后臺(tái)繼續(xù)運(yùn)行。


          Service是單實(shí)例的。在一個(gè)設(shè)備上,相同的Service只會(huì)存在一個(gè)實(shí)例。如果多個(gè)Ability共用這個(gè)實(shí)例,只有當(dāng)與Service綁定的所有Ability都退出后,Service才能夠退出。


          由于Service是在主線(xiàn)程里執(zhí)行的,因此,如果在Service里面的操作時(shí)間過(guò)長(zhǎng),開(kāi)發(fā)者必須在Service里創(chuàng)建新的線(xiàn)程來(lái)處理,防止造成主線(xiàn)程阻塞,應(yīng)用程序無(wú)響應(yīng)。


          創(chuàng)建Service


          介紹如何創(chuàng)建一個(gè)Service。


          1、創(chuàng)建Ability的子類(lèi),實(shí)現(xiàn)Service相關(guān)的生命周期方法。Service也是一種Ability,Ability為Service提供了以下生命周期方法,通過(guò)重寫(xiě)這些方法,來(lái)添加其他Ability請(qǐng)求與Service Ability交互時(shí)的處理方法。


          • onStart() 該方法在創(chuàng)建Service的時(shí)候調(diào)用,用于Service的初始化。在Service的整個(gè)生命周期只會(huì)調(diào)用一次,調(diào)用時(shí)傳入的Intent應(yīng)為空。
          • onCommand() 在Service創(chuàng)建完成之后調(diào)用,該方法在客戶(hù)端每次啟動(dòng)該Service時(shí)都會(huì)調(diào)用,用戶(hù)可以在該方法中做一些調(diào)用統(tǒng)計(jì)、初始化類(lèi)的操作。
          • onConnect() 在Ability和Service連接時(shí)調(diào)用,該方法返回IRemoteObject對(duì)象,用戶(hù)可以在該回調(diào)函數(shù)中生成對(duì)應(yīng)Service的IPC通信通道,以便Ability與Service交互。Ability可以多次連接同一個(gè)Service,系統(tǒng)會(huì)緩存該Service的IPC通信對(duì)象,只有第一個(gè)客戶(hù)端連接Service時(shí),系統(tǒng)才會(huì)調(diào)用Service的onConnect方法來(lái)生成IRemoteObject對(duì)象,而后系統(tǒng)會(huì)將同一個(gè)RemoteObject對(duì)象傳遞至其他連接同一個(gè)Service的所有客戶(hù)端,而無(wú)需再次調(diào)用onConnect方法。
          • onDisconnect() 在Ability與綁定的Service斷開(kāi)連接時(shí)調(diào)用。
          • onStop() 在Service銷(xiāo)毀時(shí)調(diào)用。Service應(yīng)通過(guò)實(shí)現(xiàn)此方法來(lái)清理任何資源,如關(guān)閉線(xiàn)程、注冊(cè)的偵聽(tīng)器等。創(chuàng)建Service的代碼示例如下:

          public class ServiceAbility extends Ability {
              @Override
              public void onStart(Intent intent) {
                  super.onStart(intent);
              }

              @Override
              public void onCommand(Intent intent, boolean restart, int startId) {
                  super.onCommand(intent, restart, startId);
              }

              @Override
              public IRemoteObject onConnect(Intent intent) {
                  return super.onConnect(intent);
              }

              @Override
              public void onDisconnect(Intent intent) {
                  super.onDisconnect(intent);
              }

              @Override
              public void onStop() {
                  super.onStop();
              }
          }


          2、注冊(cè)Service。Service也需要在應(yīng)用配置文件中進(jìn)行注冊(cè),注冊(cè)類(lèi)型type需要設(shè)置為service。


          {
              "module": {
                  "abilities": [         
                      {    
                          "name"".ServiceAbility",
                          "type""service",
                          "visible"true
                          ...
                      }
                  ]
                  ...
              }
              ...
          }


          啟動(dòng)Service


          介紹通過(guò)startAbility()啟動(dòng)Service以及對(duì)應(yīng)的停止方法。


          • 啟動(dòng)Service Ability為開(kāi)發(fā)者提供了startAbility()方法來(lái)啟動(dòng)另外一個(gè)Ability。因?yàn)镾ervice也是Ability的一種,開(kāi)發(fā)者同樣可以通過(guò)將Intent傳遞給該方法來(lái)啟動(dòng)Service。不僅支持啟動(dòng)本地Service,還支持啟動(dòng)遠(yuǎn)程Service。開(kāi)發(fā)者可以通過(guò)構(gòu)造包含DeviceId、BundleName與AbilityName的Operation對(duì)象來(lái)設(shè)置目標(biāo)Service信息。這三個(gè)參數(shù)的含義如下:
            • DeviceId:表示設(shè)備ID。如果是本地設(shè)備,則可以直接留空;如果是遠(yuǎn)程設(shè)備,可以通過(guò)ohos.distributedschedule.interwork.DeviceManager提供的getDeviceList獲取設(shè)備列表,詳見(jiàn)《API參考》。
            • BundleName:表示包名稱(chēng)。
            • AbilityName:表示待啟動(dòng)的Ability名稱(chēng)。

          啟動(dòng)本地設(shè)備Service的代碼示例如下:


          Intent intent = new Intent();
          Operation operation = new Intent.OperationBuilder()
                  .withDeviceId("")
                  .withBundleName("com.domainname.hiworld.himusic")
                  .withAbilityName("com.domainname.hiworld.himusic.ServiceAbility")
                  .build();
          intent.setOperation(operation);
          startAbility(intent);


          啟動(dòng)遠(yuǎn)程設(shè)備Service的代碼示例如下:


          Intent intent = new Intent();
          Operation operation = new Intent.OperationBuilder()
                  .withDeviceId("deviceId")
                  .withBundleName("com.domainname.hiworld.himusic")
                  .withAbilityName("com.domainname.hiworld.himusic.ServiceAbility")
                  .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE) // 設(shè)置支持分布式調(diào)度系統(tǒng)多設(shè)備啟動(dòng)的標(biāo)識(shí)
                  .build();
          intent.setOperation(operation);
          startAbility(intent);


          執(zhí)行上述代碼后,Ability將通過(guò)startAbility() 方法來(lái)啟動(dòng)Service。


          • 如果Service尚未運(yùn)行,則系統(tǒng)會(huì)先調(diào)用onStart()來(lái)初始化Service,再回調(diào)Service的onCommand()方法來(lái)啟動(dòng)Service。

          • 如果Service正在運(yùn)行,則系統(tǒng)會(huì)直接回調(diào)Service的onCommand()方法來(lái)啟動(dòng)Service。

          • 停止Service Service一旦創(chuàng)建就會(huì)一直保持在后臺(tái)運(yùn)行,除非必須回收內(nèi)存資源,否則系統(tǒng)不會(huì)停止或銷(xiāo)毀Service。開(kāi)發(fā)者可以在Service中通過(guò)terminateAbility()停止本Service或在其他Ability調(diào)用stopAbility()來(lái)停止Service。停止Service同樣支持停止本地設(shè)備Service和停止遠(yuǎn)程設(shè)備Service,使用方法與啟動(dòng)Service一樣。一旦調(diào)用停止Service的方法,系統(tǒng)便會(huì)盡快銷(xiāo)毀Service。


          連接Service


          如果Service需要與Page Ability或其他應(yīng)用的Service Ability進(jìn)行交互,則須創(chuàng)建用于連接的Connection。Service支持其他Ability通過(guò)connectAbility()方法與其進(jìn)行連接。


          在使用connectAbility()處理回調(diào)時(shí),需要傳入目標(biāo)Service的Intent與IAbilityConnection的實(shí)例。IAbilityConnection提供了兩個(gè)方法供開(kāi)發(fā)者實(shí)現(xiàn):onAbilityConnectDone()是用來(lái)處理連接Service成功的回調(diào),onAbilityDisconnectDone()是用來(lái)處理Service異常死亡的回調(diào)。


          創(chuàng)建連接Service回調(diào)實(shí)例的代碼示例如下:


          // 創(chuàng)建連接Service回調(diào)實(shí)例
          private IAbilityConnection connection = new IAbilityConnection() {
              // 連接到Service的回調(diào)
              @Override
              public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int resultCode) {
                  // Client側(cè)需要定義與Service側(cè)相同的IRemoteObject實(shí)現(xiàn)類(lèi)。開(kāi)發(fā)者獲取服務(wù)端傳過(guò)來(lái)IRemoteObject對(duì)象,并從中解析出服務(wù)端傳過(guò)來(lái)的信息。
              }

              // Service異常死亡的回調(diào)
              @Override
              public void onAbilityDisconnectDone(ElementName elementName, int resultCode) {
              }
          };


          連接Service的代碼示例如下:


          // 連接Service
          Intent intent = new Intent();
          Operation operation = new Intent.OperationBuilder()
                  .withDeviceId("deviceId")
                  .withBundleName("com.domainname.hiworld.himusic")
                  .withAbilityName("com.domainname.hiworld.himusic.ServiceAbility")
                  .build();
          intent.setOperation(operation);
          connectAbility(intent, connection);


          同時(shí),Service側(cè)也需要在onConnect()時(shí)返回IRemoteObject,從而定義與Service進(jìn)行通信的接口。onConnect()需要返回一個(gè)IRemoteObject對(duì)象,HarmonyOS提供了IRemoteObject的默認(rèn)實(shí)現(xiàn),用戶(hù)可以通過(guò)繼承LocalRemoteObject來(lái)創(chuàng)建自定義的實(shí)現(xiàn)類(lèi)。Service則把自身的實(shí)例返回給調(diào)用側(cè)的代碼示例如下:


          // 創(chuàng)建自定義IRemoteObject實(shí)現(xiàn)類(lèi)
          private class MyRemoteObject extends LocalRemoteObject {
              MyRemoteObject(){
              }
          }

          // 把IRemoteObject返回給客戶(hù)端
          @Override
          protected IRemoteObject onConnect(Intent intent) {
              return new MyRemoteObject();
          }



          2


          Service Ability生命周期



          與Page類(lèi)似,Service也擁有生命周期,如圖1所示。根據(jù)調(diào)用方法的不同,其生命周期有以下兩種路徑:


          • 啟動(dòng)Service 該Service在其他Ability調(diào)用startAbility()時(shí)創(chuàng)建,然后保持運(yùn)行。其他Ability通過(guò)調(diào)用stopAbility()來(lái)停止Service,Service停止后,系統(tǒng)會(huì)將其銷(xiāo)毀。
          • 連接Service 該Service在其他Ability調(diào)用connectAbility()時(shí)創(chuàng)建,客戶(hù)端可通過(guò)調(diào)用disconnectAbility()斷開(kāi)連接。多個(gè)客戶(hù)端可以綁定到相同Service,而且當(dāng)所有綁定全部取消后,系統(tǒng)即會(huì)銷(xiāo)毀該Service。


          圖1 Service生命周期


          3


          前臺(tái)Service


          一般情況下,Service都是在后臺(tái)運(yùn)行的,后臺(tái)Service的優(yōu)先級(jí)都是比較低的,當(dāng)資源不足時(shí),系統(tǒng)有可能回收正在運(yùn)行的后臺(tái)Service。


          在一些場(chǎng)景下(如播放音樂(lè)),用戶(hù)希望應(yīng)用能夠一直保持運(yùn)行,此時(shí)就需要使用前臺(tái)Service。前臺(tái)Service會(huì)始終保持正在運(yùn)行的圖標(biāo)在系統(tǒng)狀態(tài)欄顯示。


          使用前臺(tái)Service并不復(fù)雜,開(kāi)發(fā)者只需在Service創(chuàng)建的方法里,調(diào)用keepBackgroundRunning()將Service與通知綁定。調(diào)用keepBackgroundRunning()方法前需要在配置文件中聲明ohos.permission.KEEP_BACKGROUND_RUNNING權(quán)限,同時(shí)還需要在配置文件中添加對(duì)應(yīng)的backgroundModes參數(shù)。在onStop()方法中調(diào)用cancelBackgroundRunning()方法可停止前臺(tái)Service。


          使用前臺(tái)Service的onStart()代碼示例如下:


          // 創(chuàng)建通知,其中1005為notificationId
          NotificationRequest request = new NotificationRequest(1005);
          NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent();
          content.setTitle("title").setText("text");
          NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content);
          request.setContent(notificationContent);

          // 綁定通知,1005為創(chuàng)建通知時(shí)傳入的notificationId
          keepBackgroundRunning(1005, request);


          在配置文件中,“module > abilities”字段下對(duì)當(dāng)前Service做如下配置:


          {    
              "name"".ServiceAbility",
              "type""service",
              "visible"true,
              "backgroundModes": ["dataTransfer""location"]
          }


          往期推薦



          點(diǎn)擊閱讀原文,更精彩~
          瀏覽 81
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产91看片婬黄大片 | 日本色情视频在线观看 | 超碰碰人人家 | 成人开心网 | 国产亚洲欧美精品久久久久久 |