HarmonyOS之深入解析Ability的功能和使用
生活随笔
收集整理的這篇文章主要介紹了
HarmonyOS之深入解析Ability的功能和使用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、Ability 概述
- Ability 是應用所具備能力的抽象,也是應用程序的重要組成部分。一個應用可以具備多種能力(即可以包含多個 Ability),HarmonyOS 支持應用以 Ability 為單位進行部署。
- Ability 可以分為 FA(Feature Ability)和 PA(Particle Ability)兩種類型,每種類型為開發者提供了不同的模板,以便實現不同的業務功能。
- FA 支持 Page Ability:Page 模板是 FA 唯一支持的模板,用于提供與用戶交互的能力。一個 Page 實例可以包含一組相關頁面,每個頁面用一個 AbilitySlice 實例表示。
- PA 支持 Service Ability 和 Data Ability:
-
- Service 模板:用于提供后臺運行任務的能力;
-
- Data 模板:用于對外部提供統一的數據訪問抽象。
- 在配置文件(config.json)中注冊 Ability 時,可以通過配置 Ability 元素中的“type”屬性來指定 Ability 模板類型,其中,“type”的取值可以為“page”、“service”或“data”,分別代表 Page 模板、Service 模板、Data 模板,如下所示:
二、Page Ability
① Page Ability 基本概念
- Page 模板(以下簡稱“Page”)是 FA 唯一支持的模板,用于提供與用戶交互的能力。
- 一個 Page 可以由一個或多個 AbilitySlice 構成,AbilitySlice 是指應用的單個頁面及其控制邏輯的總和。
- 當一個 Page 由多個 AbilitySlice 共同構成時,這些 AbilitySlice 頁面提供的業務能力應具有高度相關性。例如,新聞瀏覽功能可以通過一個 Page 來實現,其中包含了兩個 AbilitySlice:一個 AbilitySlice 用于展示新聞列表,另一個 AbilitySlice 用于展示新聞詳情。
- Page 和 AbilitySlice 的關系下圖所示:
- 相比于桌面場景,移動場景下應用之間的交互更為頻繁。通常,單個應用專注于某個方面的能力開發,當它需要其他能力輔助時,會調用其他應用提供的能力。例如,外賣應用提供了聯系商家的業務功能入口,當用戶在使用該功能時,會跳轉到通話應用的撥號頁面。
- 與此類似,HarmonyOS 支持不同 Page 之間的跳轉,并可以指定跳轉到目標 Page 中某個具體的 AbilitySlice。
- 雖然一個 Page 可以包含多個 AbilitySlice,但是 Page 進入前臺時界面默認只展示一個 AbilitySlice,默認展示的 AbilitySlice 是通過 setMainRoute() 方法來指定的。
- 如果需要更改默認展示的 AbilitySlice,可以通過 addActionRoute() 方法為此 AbilitySlice 配置一條路由規則,此時,當其它 Page 實例期望導航到此 AbilitySlice 時,可以在 Intent 中指定 Action。
- setMainRoute() 方法與 addActionRoute() 方法的使用示例如下:
- addActionRoute() 方法中使用的動作命名,需要在應用配置文件(config.json)中注冊:
② Page Ability 生命周期
- Page 生命周期的不同狀態轉換及其對應的回調,如下圖所示:
- onStart()
-
- 當系統首次創建Page實例時,觸發該回調。
-
- 對于一個 Page 實例,該回調在其生命周期過程中僅觸發一次,Page 在該邏輯后將進入 INACTIVE 狀態。
-
- 開發者必須重寫該方法,并在此配置默認展示的 AbilitySlice。
- onActive()
-
- Page 會在進入INACTIVE狀態后來到前臺,然后系統調用此回調。
-
- Page 在此之后進入 ACTIVE 狀態,該狀態是應用與用戶交互的狀態。Page 將保持在此狀態,除非某類事件發生導致 Page 失去焦點,比如用戶點擊返回鍵或導航到其他 Page。當此類事件發生時,會觸發 Page 回到 INACTIVE 狀態,系統將調用 onInactive() 回調。此后,Page 可能重新回到 ACTIVE 狀態,系統將再次調用 onActive() 回調。
-
- 因此,開發者通常需要成對實現 onActive() 和 onInactive(),并在 onActive() 中獲取在 onInactive() 中被釋放的資源。
- onInactive()
-
- 當 Page 失去焦點時,系統將調用此回調,此后 Page 進入 INACTIVE狀態。
-
- 開發者可以在此回調中實現 Page 失去焦點時應表現的恰當行為。
- onBackground()
-
- 如果 Page 不再對用戶可見,系統將調用此回調通知開發者用戶進行相應的資源釋放,此后 Page 進入 BACKGROUND 狀態。
-
- 開發者應該在此回調中釋放 Page 不可見時無用的資源,或在此回調中執行較為耗時的狀態保存操作。
- onForeground()
-
- 處于 BACKGROUND 狀態的 Page 仍然駐留在內存中,當重新回到前臺時(比如用戶重新導航到此 Page),系統將先調用 onForeground() 回調通知開發者,而后 Page 的生命周期狀態回到 INACTIVE 狀態。
-
- 開發者應當在此回調中重新申請在 onBackground() 中釋放的資源,最后 Page 的生命周期狀態進一步回到 ACTIVE 狀態,系統將通過 onActive() 回調通知開發者用戶。
- onStop()
-
- 系統將要銷毀 Page 時,將會觸發此回調函數,通知用戶進行系統資源的釋放。
-
- 銷毀 Page 的可能原因包括以下幾個方面:
-
-
- 用戶通過系統管理能力關閉指定 Page,例如使用任務管理器關閉 Page。
-
-
-
- 用戶行為觸發 Page 的 terminateAbility() 方法調用,例如使用應用的退出功能。
-
-
-
- 配置變更導致系統暫時銷毀 Page 并重建。
-
-
-
- 系統出于資源管理目的,自動觸發對處于 BACKGROUND 狀態 Page 的銷毀。
-
- AbilitySlice 作為 Page 的組成單元,其生命周期是依托于其所屬 Page 生命周期的。AbilitySlice 和 Page 具有相同的生命周期狀態和同名的回調,當 Page 生命周期發生變化時,它的 AbilitySlice 也會發生相同的生命周期變化。
- 此外,AbilitySlice 還具有獨立于 Page 的生命周期變化,這發生在同一 Page 中的 AbilitySlice 之間導航時,此時 Page 的生命周期狀態不會改變。
- AbilitySlice 生命周期回調與 Page 的相應回調類似,因此不再贅述。由于 AbilitySlice 承載具體的頁面,開發者必須重寫 AbilitySlice的onStart() 回調,并在此方法中通過 setUIContent() 方法設置頁面,如下所示:
- AbilitySlice 實例創建和管理通常由應用負責,系統僅在特定情況下會創建 AbilitySlice 實例。例如,通過導航啟動某個 AbilitySlice 時,是由系統負責實例化;但是在同一個 Page 中不同的 AbilitySlice 間導航時則由應用負責實例化。
- 當 AbilitySlice 處于前臺且具有焦點時,其生命周期狀態隨著所屬 Page 的生命周期狀態的變化而變化。當一個 Page 擁有多個 AbilitySlice 時,例如:MyAbility 下有 FooAbilitySlice 和 BarAbilitySlice,當前 FooAbilitySlice 處于前臺并獲得焦點,并即將導航到 BarAbilitySlice,在此期間的生命周期狀態變化順序為:
-
- FooAbilitySlice 從 ACTIVE 狀態變為 INACTIVE 狀態;
-
- BarAbilitySlice 則從 INITIAL 狀態首先變為 INACTIVE 狀態,然后變為 ACTIVE 狀態(假定此前 BarAbilitySlice 未曾啟動);
-
- FooAbilitySlice 從 INACTIVE 狀態變為 BACKGROUND 狀態。
- 對應兩個slice的生命周期方法回調順序為:
FooAbilitySlice.onInactive() --> BarAbilitySlice.onStart() --> BarAbilitySlice.onActive() --> FooAbilitySlice.onBackground() - 在整個流程中,MyAbility 始終處于 ACTIVE 狀態。但是,當 Page 被系統銷毀時,其所有已實例化的 AbilitySlice 將聯動銷毀,而不僅是處于前臺的 AbilitySlice。
③ AbilitySlice 間導航
- 同一 Page 內導航:當發起導航的 AbilitySlice 和導航目標的 AbilitySlice 處于同一個 Page 時,您可以通過 present() 方法實現導航。如下代碼片段展示通過點擊按鈕導航到其他 AbilitySlice 的方法:
- 如果開發者希望在用戶從導航目標 AbilitySlice 返回時,能夠獲得其返回結果,則應當使用 presentForResult() 實現導航。用戶從導航目標 AbilitySlice 返回時,系統將回調 onResult() 來接收和處理返回結果,開發者需要重寫該方法。返回結果由導航目標 AbilitySlice 在其生命周期內通過 setResult() 進行設置。
- 系統為每個 Page 維護了一個 AbilitySlice 實例的棧,每個進入前臺的 AbilitySlice 實例均會入棧。當開發者在調用 present() 或 presentForResult() 時指定的 AbilitySlice 實例已經在棧中存在時,則棧中位于此實例之上的 AbilitySlice 均會出棧并終止其生命周期。
- 前面的示例代碼中,導航時指定的 AbilitySlice 實例均是新建的,即便重復執行此代碼(此時作為導航目標的這些實例是同一個類),也不會導致任何 AbilitySlice 出棧。
- 不同 Page 間導航:AbilitySlice 作為 Page 的內部單元,以 Action 的形式對外暴露,因此可以通過配置 Intent 的 Action 導航到目標 AbilitySlice。Page 間的導航可以使用 startAbility() 或 startAbilityForResult() 方法,獲得返回結果的回調為 onAbilityResult()。在 Ability 中調用 setResult() 可以設置返回結果。
④ 跨設備遷移
- 跨設備遷移(下文簡稱“遷移”)支持將 Page 在同一用戶的不同設備間遷移,以便支持用戶無縫切換的訴求。
- 以 Page 從設備 A 遷移到設備 B 為例,遷移動作主要步驟如下:
-
- 設備 A 上的 Page 請求遷移;
-
- HarmonyOS 處理遷移任務,并回調設備 A 上 Page 的保存數據方法,用于保存遷移必須的數據;
-
- HarmonyOS 在設備 B 上啟動同一個 Page,并回調其恢復數據方法。
- 實現 IAbilityContinuation 接口:
-
- onStartContinuation():Page 請求遷移后,系統首先回調此方法,開發者可以在此回調中決策當前是否可以執行遷移,比如,彈框讓用戶確認是否開始遷移;
-
- onSaveData():如果 onStartContinuation() 返回 true,則系統回調此方法,開發者在此回調中保存必須傳遞到另外設備上以便恢復 Page 狀態的數據。
-
- onRestoreData():源側設備上 Page 完成保存數據后,系統在目標側設備上回調此方法,開發者在此回調中接受用于恢復 Page 狀態的數據。注意,在目標側設備上的Page會重新啟動其生命周期,無論其啟動模式如何配置。且系統回調此方法的時機在 onStart() 之前。
-
- onCompleteContinuation():目標側設備上恢復數據一旦完成,系統就會在源側設備上回調 Page 的此方法,以便通知應用遷移流程已結束。開發者可以在此檢查遷移結果是否成功,并在此處理遷移結束的動作,例如,應用可以在遷移完成后終止自身生命周期。
-
- onRemoteTerminated():如果開發者使用 continueAbilityReversibly() 而不是 continueAbility(),則此后可以在源側設備上使用 reverseContinueAbility() 進行回遷。這種場景下,相當于同一個 Page(的兩個實例)同時在兩個設備上運行,遷移完成后,如果目標側設備上 Page 因任何原因終止,則源側 Page 通過此回調接收終止通知。
- 請求遷移:
-
- 實現 IAbilityContinuation 的 Page 可以在其生命周期內,調用 continueAbility() 或 continueAbilityReversibly() 請求遷移。兩者的區別是,通過后者發起的遷移此后可以進行回遷。
-
- 以 Page 從設備 A 遷移到設備 B 為例,詳細的流程如下:
-
-
- 設備 A 上的 Page 請求遷移;
-
-
-
- 系統回調設備 A 上 Page 及其 AbilitySlice 棧中所有 AbilitySlice 實例的 IAbilityContinuation.onStartContinuation() 方法,以確認當前是否可以立即遷移。
-
-
-
- 如果可以立即遷移,則系統回調設備 A 上 Page 及其 AbilitySlice 棧中所有 AbilitySlice 實例的 IAbilityContinuation.onSaveData() 方法,以便保存遷移后恢復狀態必須的數據。
-
-
-
- 如果保存數據成功,則系統在設備 B 上啟動同一個 Page,并恢復 AbilitySlice 棧,然后回調 IAbilityContinuation.onRestoreData() 方法,傳遞此前保存的數據;此后設備 B 上此 Page從onStart() 開始其生命周期回調。
-
-
-
- 系統回調設備 A 上 Page 及其 AbilitySlice 棧中所有 AbilitySlice 實例的 IAbilityContinuation.onCompleteContinuation() 方法,通知數據恢復成功與否。
-
- 請求回遷
-
- 使用 continueAbilityReversibly() 請求遷移并完成后,源側設備上已遷移的 Page 可以發起回遷,以便使用戶活動重新回到此設備。
-
- 以 Page 從設備 A 遷移到設備 B 后并請求回遷為例,詳細的流程如下:
-
-
- 設備 A 上的 Page 請求回遷;
-
-
-
- 系統回調設備 B 上 Page 及其 AbilitySlice 棧中所有 AbilitySlice 實例的 IAbilityContinuation.onStartContinuation() 方法,以確認當前是否可以立即遷移;
-
-
-
- 如果可以立即遷移,則系統回調設備 B 上 Page 及其 AbilitySlice 棧中所有 AbilitySlice 實例的 IAbilityContinuation.onSaveData() 方法,以便保存回遷后恢復狀態必須的數據;
-
-
-
- 如果保存數據成功,則系統在設備 A 上 Page 恢復 AbilitySlice 棧,然后回調 IAbilityContinuation.onRestoreData() 方法,傳遞此前保存的數據;
-
-
-
- 如果數據恢復成功,則系統終止設備 B 上 Page 的生命周期。
-
- 參考示例:Page模板的Ability與用戶交互的能力。
三、Service Ability
① Service Ability 基本概念
- 基于 Service 模板的 Ability(以下簡稱“Service”)主要用于后臺運行任務(如執行音樂播放、文件下載等),但不提供用戶交互界面。
- Service 可由其他應用或Ability啟動,即使用戶切換到其他應用,Service 仍將在后臺繼續運行。
- Service 是單實例的,在一個設備上,相同的 Service 只會存在一個實例。如果多個 Ability 共用這個實例,只有當與 Service 綁定的所有 Ability 都退出后,Service 才能夠退出。
- 由于 Service 是在主線程里執行的,因此,如果在 Service 里面的操作時間過長,開發者必須在 Service 里創建新的線程來處理,防止造成主線程阻塞,應用程序無響應。
② 創建 Service
- 創建 Ability 的子類,實現 Service 相關的生命周期方法。Service 也是一種 Ability,Ability 為 Service 提供了以下生命周期方法,用戶可以重寫這些方法,來添加其他 Ability 請求與 Service Ability 交互時的處理方法。
-
- onStart():該方法在創建 Service 的時候調用,用于 Service 的初始化。在 Service 的整個生命周期只會調用一次,調用時傳入的 Intent 應為空。
-
- onCommand():在 Service 創建完成之后調用,該方法在客戶端每次啟動該 Service 時都會調用,用戶可以在該方法中做一些調用統計、初始化類的操作。
-
- onConnect?():在 Ability 和 Service 連接時調用,該方法返回 IRemoteObject 對象,用戶可以在該回調函數中生成對應 Service 的 IPC 通信通道,以便 Ability 與 Service 交互。Ability 可以多次連接同一個 Service,系統會緩存該 Service 的 IPC 通信對象,只有第一個客戶端連接 Service 時,系統才會調用 Service 的 onConnect 方法來生成 IRemoteObject 對象,而后系統會將同一個 RemoteObject 對象傳遞至其他連接同一個 Service 的所有客戶端,而無需再次調用 onConnect 方法。
-
- onDisconnect?():在 Ability 與綁定的 Service 斷開連接時調用。
-
- onStop():在 Service 銷毀時調用,Service 應通過實現此方法來清理任何資源,如關閉線程、注冊的偵聽器等。
- 創建 Service 的代碼示例如下:
- 注冊 Service:Service 也需要在應用配置文件中進行注冊,注冊類型 type 需要設置為 service:
③ 啟動 Service
- Ability 為開發者提供了 startAbility() 方法來啟動另外一個 Ability,因為 Service 也是 Ability 的一種,開發者同樣可以通過將 Intent 傳遞給該方法來啟動 Service。不僅支持啟動本地 Service,還支持啟動遠程 Service。
- 開發者可以通過構造包含 DeviceId、BundleName 與 AbilityName 的 Operation 對象來設置目標 Service 信息,這三個參數的含義如下:
-
- DeviceId:表示設備 ID,如果是本地設備,則可以直接留空;如果是遠程設備,可以通過 ohos.distributedschedule.interwork.DeviceManager 提供的 getDeviceList 獲取設備列表;
-
- BundleName:表示包名稱;
-
- AbilityName:表示待啟動的 Ability 名稱。
- 啟動本地設備 Service 的代碼示例如下:
- 啟動遠程設備 Service 的代碼示例如下:
- 執行上述代碼后,Ability 將通過 startAbility() 方法來啟動 Service。如果 Service 尚未運行,則系統會先調用 onStart() 來初始化 Service,再回調 Service 的 onCommand() 方法來啟動 Service。如果 Service 正在運行,則系統會直接回調 Service 的 onCommand() 方法來啟動 Service。
- Service 一旦創建就會一直保持在后臺運行,除非必須回收內存資源,否則系統不會停止或銷毀 Service。開發者可以在 Service 中通過 terminateAbility() 停止本 Service 或在其他 Ability 調用 stopAbility() 來停止 Service。
- 停止 Service 同樣支持停止本地設備 Service 和停止遠程設備 Service,使用方法與啟動 Service 一樣。一旦調用停止 Service 的方法,系統便會盡快銷毀 Service。
④ 鏈接 Service
- 如果 Service 需要與 Page Ability 或其他應用的 Service Ability 進行交互,則須創建用于連接的 Connection。Service 支持其他 Ability 通過 connectAbility() 方法與其進行連接。
- 在使用 connectAbility() 處理回調時,需要傳入目標 Service 的 Intent 與 IAbilityConnection 的實例。IAbilityConnection 提供了兩個方法供開發者實現:onAbilityConnectDone() 是用來處理連接 Service 成功的回調, onAbilityDisconnectDone() 是用來處理 Service 異常死亡的回調。
- 創建連接 Service 回調實例的代碼示例如下:
- 連接 Service 的代碼示例如下:
- 同時,Service 側也需要在 onConnect() 時返回 IRemoteObject,從而定義與 Service 進行通信的接口。onConnect() 需要返回一個 IRemoteObject 對象,HarmonyOS 提供了 IRemoteObject 的默認實現,用戶可以通過繼承 LocalRemoteObject 來創建自定義的實現類。
- Service 側把自身的實例返回給調用側的代碼示例如下:
⑤ Service Ability 生命周期
- 與 Page 類似,Service 也擁有生命周期,如下圖所示:
- 根據調用方法的不同,其生命周期有以下兩種路徑:
-
- 啟動 Service:該 Service 在其他 Ability 調用 startAbility() 時創建,然后保持運行。其他 Ability 通過調用 stopAbility() 來停止 Service,Service 停止后,系統會將其銷毀。
-
- 連接 Service:該 Service 在其他 Ability 調用 connectAbility() 時創建,客戶端可通過調用 disconnectAbility?() 斷開連接。多個客戶端可以綁定到相同 Service,而且當所有綁定全部取消后,系統即會銷毀該 Service。
⑥ 前臺 Service
- 一般情況下,Service都是在后臺運行的,后臺 Service 的優先級都是比較低的,當資源不足時,系統有可能回收正在運行的后臺 Service。
- 在一些場景下(如播放音樂),用戶希望應用能夠一直保持運行,此時就需要使用前臺 Service,前臺 Service 會始終保持正在運行的圖標在系統狀態欄顯示。
- 使用前臺 Service 并不復雜,開發者只需在 Service 創建的方法里,調用 keepBackgroundRunning() 將 Service 與通知綁定。調用 keepBackgroundRunning() 方法前需要在配置文件中聲明 ohos.permission.KEEP_BACKGROUND_RUNNING 權限,同時還需要在配置文件中添加對應的 backgroundModes 參數。在 onStop() 方法中調用 cancelBackgroundRunning?() 方法可停止前臺 Service。
- 使用前臺 Service的onStart() 代碼示例如下:
- 在配置文件中,“module > abilities”字段下對當前 Service 做如下配置:
- 參考示例:HarmonyOS之音樂播放器展示前臺Service的使用方法。
四、Data Ability
① Data Ability 基本概念
- 使用 Data 模板的 Ability(以下簡稱“Data”)有助于應用管理其自身和其他應用存儲數據的訪問,并提供與其他應用共享數據的方法。Data 既可用于同設備不同應用的數據共享,也支持跨設備不同應用的數據共享。
- 數據的存放形式多樣,可以是數據庫,也可以是磁盤上的文件。Data 對外提供對數據的增、刪、改、查,以及打開文件等接口,這些接口的具體實現由開發者提供。
- Data 的提供方和使用方都通過 URI(Uniform Resource Identifier)來標識一個具體的數據,例如數據庫中的某個表或磁盤上的某個文件。 HarmonyOS 的 URI 仍基于 URI 通用標準,格式如下:
- 參數說明:
-
- scheme:協議方案名,固定為“dataability”,代表 Data Ability 所使用的協議類型。
-
- authority:設備 ID,如果為跨設備場景,則為目標設備的 ID;如果為本地設備場景,則不需要填寫。
-
- path:資源的路徑信息,代表特定資源的位置信息。
-
- query:查詢參數。
-
- fragment:可以用于指示要訪問的子資源。
② 創建 Data
- 確定數據的存儲方式,Data 支持以下兩種數據形式:
-
- 文件數據:如文本、圖片、音樂等;
-
- 結構化數據:如數據庫等。
- 實現 UserDataAbility
-
- UserDataAbility 用于接收其他應用發送的請求,提供外部程序訪問的入口,從而實現應用間的數據訪問。
-
- 實現 UserDataAbility,需要在“Project”窗口當前工程的主目錄(“entry > src > main > java > com.xxx.xxx”)選擇“File > New > Ability > Empty Data Ability”,設置“Data Name”后完成 UserDataAbility 的創建。
- Data 提供了文件存儲和數據庫存儲兩組接口供用戶使用。
-
- 文件存儲
-
-
- 開發者需要在 Data 中重寫 FileDescriptor openFile?(Uri uri, String mode)方法來操作文件:uri 為客戶端傳入的請求目標路徑;mode為開發者對文件的操作選項,可選方式包含“r”(讀), “w”(寫), “rw”(讀寫)等。
-
-
-
- ohos.rpc.MessageParcel 類提供了一個靜態方法,用于獲取 MessageParcel 實例。開發者可通過獲取到的 MessageParcel 實例,使用 dupFileDescriptor() 函數復制待操作文件流的文件描述符,并將其返回,供遠端應用訪問文件。
-
-
-
- 根據傳入的 uri 打開對應的文件:
-
-
- 數據庫存儲
-
-
- 初始化數據庫連接,系統會在應用啟動時調用 onStart() 方法創建 Data 實例。在此方法中,開發者應該創建數據庫連接,并獲取連接對象,以便后續和數據庫進行操作。為了避免影響應用啟動速度,開發者應當盡可能將非必要的耗時任務推遲到使用時執行,而不是在此方法中執行所有初始化。
-
-
-
- 編寫數據庫操作方法,Ability 定義了6個方法供用戶處理對數據庫表數據的增刪改查,這6個方法在 Ability 中已默認實現,開發者可按需重寫:
-
| ResultSet query?(Uri uri, String[] columns, DataAbilityPredicates predicates) | 查詢數據庫 |
| int insert?(Uri uri, ValuesBucket value) | 向數據庫中插入單條數據 |
| int batchInsert?(Uri uri, ValuesBucket[] values) | 向數據庫中插入多條數據 |
| int delete?(Uri uri, DataAbilityPredicates predicates) | 刪除一條或多條數據 |
| int update?(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) | 更新數據庫 |
| DataAbilityResult[] executeBatch?(ArrayList operations) | 批量操作數據庫 |
- query():該方法接收三個參數,分別是查詢的目標路徑,查詢的列名,以及查詢條件,查詢條件由類 DataAbilityPredicates 構建。根據傳入的列名和查詢條件查詢用戶表的代碼示例如下:
- insert():該方法接收兩個參數,分別是插入的目標路徑和插入的數據值。其中,插入的數據由 ValuesBucket 封裝,服務端可以從該參數中解析出對應的屬性,然后插入到數據庫中。此方法返回一個 int 類型的值用于標識結果。接收到傳過來的用戶信息并把它保存到數據庫中的代碼示例如下:
- batchInsert():該方法為批量插入方法,接收一個 ValuesBucket 數組用于單次插入一組對象。它的作用是提高插入多條重復數據的效率。該方法系統已實現,開發者可以直接調用。
- delete():該方法用來執行刪除操作,刪除條件由類 DataAbilityPredicates 構建,服務端在接收到該參數之后可以從中解析出要刪除的數據,然后到數據庫中執行。根據傳入的條件刪除用戶表數據的代碼示例如下:
- update():此方法用來執行更新操作,用戶可以在 ValuesBucket 參數中指定要更新的數據,在 DataAbilityPredicates 中構建更新的條件等。更新用戶表的數據的代碼示例如下:
- executeBatch():此方法用來批量執行操作,DataAbilityOperation 中提供了設置操作類型、數據和操作條件的方法,用戶可自行設置自己要執行的數據庫操作。該方法系統已實現,開發者可以直接調用。
- 注冊 UserDataAbility,和 Service 類似,開發者必須在配置文件中注冊 Data。配置文件中該字段在創建 Data Ability 時會自動創建,name 與創建的 Data Ability 一致。需要關注以下屬性:
-
- type: 類型設置為 data;
-
- uri: 對外提供的訪問路徑,全局唯一;
-
- permissions: 訪問該 data ability 時需要申請的訪問權限。
③ 訪問 Data
- 開發者可以通過 DataAbilityHelper 類來訪問當前應用或其他應用提供的共享數據。DataAbilityHelper 作為客戶端,與提供方的 Data 進行通信。 Data 接收到請求后,執行相應的處理,并返回結果。DataAbilityHelper 提供了一系列與 Data Ability 對應的方法。
- 如果待訪問的 Data 聲明了訪問需要權限,則訪問此 Data 需要在配置文件中聲明需要此權限:
- DataAbilityHelper 為開發者提供了 creator() 方法來創建 DataAbilityHelper 實例。該方法為靜態方法,有多個重載。最常見的方法是通過傳入一個 context 對象來創建 DataAbilityHelper 對象。獲取 helper 對象示例:
- 訪問 Data Ability:DataAbilityHelper 為開發者提供了一系列的接口來訪問不同類型的數據(文件、數據庫等)。
-
- 訪問文件:DataAbilityHelper 為開發者提供了 FileDescriptor openFile?(Uri uri, String mode)方法來操作文件。此方法需要傳入兩個參數,其中uri用來確定目標資源路徑,mode用來指定打開文件的方式,可選方式包含“r”(讀), “w”(寫), “rw”(讀寫),“wt”(覆蓋寫),“wa”(追加寫),“rwt”(覆蓋寫且可讀)。該方法返回一個目標文件的 FD(文件描述符),把文件描述符封裝成流,開發者就可以對文件流進行自定義處理。訪問文件示例:
- 訪問數據庫:DataAbilityHelper 為開發者提供了增、刪、改、查以及批量處理等方法來操作數據庫,見上文中的對數據庫表數據的增刪改查表。
五、Intent
① 基本概念
- Intent 是對象之間傳遞信息的載體。
- 當一個 Ability 需要啟動另一個 Ability 時,或者一個 AbilitySlice 需要導航到另一個 AbilitySlice 時,可以通過 Intent 指定啟動的目標同時攜帶相關數據。
- Intent 的構成元素包括 Operation 與 Parameters。
- Operation 的子屬性如下:
| Action | 表示動作,通常使用系統預置Action,應用也可以自定義Action。例如IntentConstants.ACTION_HOME表示返回桌面動作 |
| Entity | 表示類別,通常使用系統預置Entity,應用也可以自定義Entity。例如Intent.ENTITY_HOME表示在桌面顯示圖標 |
| Uri | 表示Uri描述。如果在Intent中指定了Uri,則Intent將匹配指定的Uri信息,包括scheme, schemeSpecificPart, authority和path信息 |
| Flags | 表示處理Intent的方式。例如Intent.FLAG_ABILITY_CONTINUATION標記在本地的一個Ability是否可以遷移到遠端設備繼續運行 |
| BundleName | 表示包描述。如果在Intent中同時指定了BundleName和AbilityName,則Intent可以直接匹配到指定的Ability |
| AbilityName | 表示待啟動的Ability名稱。如果在Intent中同時指定了BundleName和AbilityName,則Intent可以直接匹配到指定的Ability |
| DeviceId | 表示運行指定Ability的設備ID |
- Parameters 是一種支持自定義的數據結構,開發者可以通過 Parameters 傳遞某些請求所需的額外信息。
- 當 Intent 用于發起請求時,根據指定元素的不同,分為兩種類型:
-
- 如果同時指定了 BundleName 與 AbilityName,則根據 Ability 的全稱(例如“com.demoapp.FooAbility”)來直接啟動應用;
-
- 如果未同時指定 BundleName 和 AbilityName,則根據 Operation 中的其他屬性來啟動應用。
- Intent 設置屬性時,必須先使用 Operation 來設置屬性。如果需要新增或修改屬性,必須在設置 Operation 后再執行操作。
② 根據 Ability 的全稱啟動應用
- 通過構造包含 BundleName 與 AbilityName 的 Operation 對象,可以啟動一個 Ability、并導航到該 Ability。示例代碼如下:
- 作為處理請求的對象,會在相應的回調方法中接收請求方傳遞的 Intent 對象。以導航到另一個 Ability 為例,導航的目標 Ability 可以在其 onStart() 回調的參數中獲得 Intent 對象。
③ 根據 Operation 的其他屬性啟動應用
- 有些場景下,開發者需要在應用中使用其他應用提供的某種能力,而不感知提供該能力的具體是哪一個應用。例如開發者需要通過瀏覽器打開一個鏈接,而不關心用戶最終選擇哪一個瀏覽器應用,則可以通過 Operation 的其他屬性(除 BundleName 與 AbilityName 之外的屬性)描述需要的能力。如果設備上存在多個應用提供同種能力,系統則彈出候選列表,由用戶選擇由哪個應用處理請求。
- 以下示例展示使用 Intent 跨 Ability 查詢天氣信息:
-
- 在 Ability 中構造 Intent 以及包含 Action 的 Operation 對象,并調用 startAbilityForResult() 方法發起請求,然后重寫 onAbilityResult() 回調方法,對請求結果進行處理。
-
- 作為處理請求的對象,首先需要在配置文件中聲明對外提供的能力,以便系統據此找到自身并作為候選的請求處理者:
-
- 在 Ability 中配置路由以便支持以此 action 導航到對應的 AbilitySlice:
-
- 在 Ability 中處理請求,并調用 setResult() 方法暫存返回結果:
總結
以上是生活随笔為你收集整理的HarmonyOS之深入解析Ability的功能和使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HarmonyOS之在工程中导入Samp
- 下一篇: HarmonyOS之分布式任务调度开发流