flutter_exit_app 庫的鴻蒙適配解讀,你離使用 Flutter 退出鴻蒙 app 只有一步之遙 適配倉庫地址 [1]
#鴻蒙堅果派 #鴻蒙版Flutter #鴻蒙開發(fā)者 #Flutter三方庫
在數(shù)字化浪潮的推動下,跨平臺開發(fā)框架如 Flutter 憑借其高效、便捷的特性,成為了開發(fā)者們的寵兒。而鴻蒙系統(tǒng)的崛起,更是為跨平臺開發(fā)注入了新的活力。為了助力開發(fā)者在鴻蒙生態(tài)中快速實現(xiàn) flutter_exit_app 退出應(yīng)用程序功能,本文將深入淺出地為大家解析如何適配 flutter_exit_app 三方庫至鴻蒙平臺。
一、適配鴻蒙版 flutter_exit_app 三方庫 (一)版本選擇與倉庫簡介 我們先去 pub 上查看最新版本,發(fā)現(xiàn)目前 pub 上最新是 1.1.4,我們選擇以 1.1.4 版本為基礎(chǔ)進行適配。flutter_exit_app 是一個用于在 Flutter 應(yīng)用中退出應(yīng)用程序功能的插件,其 GitHub 倉庫為 https://github.com/xang555/flutter_exit_app ,我們的目標是將這個插件適配到鴻蒙平臺。
(二)引入背景與使用場景 在 OpenHarmony 北向生態(tài)的發(fā)展過程中,許多已經(jīng)適配了 Flutter 的廠商在接入 OpenHarmony 時,都希望能夠繼續(xù)使用 FlutterToast 來實現(xiàn)通知功能。因此,我們提供了這個適配方案,采用插件化的適配器模式,幫助生態(tài)伙伴快速實現(xiàn)產(chǎn)品化。
本方案適用于已經(jīng)支持 Flutter 框架的設(shè)備在移植到 OpenHarmony 系統(tǒng)過程中,作為一個備選方案。
(三)使用文檔與插件庫使用 適配 OpenHarmony 平臺的詳細使用指導(dǎo)可以參考: Flutter 使用指導(dǎo)文檔 [2]
在項目中使用該插件庫時,只需在 pubspec.yaml
文件的 dependencies
中新增如下配置:
dependencies: flutter_exit_app: git: url: "https:///nutpi/flutter_exit_app.git" path: ""
然后在項目根目錄運行 flutter pub get
,即可完成依賴添加
接下來是具體的適配過程。
二、適配過程詳解 (一)準備工作 確保已經(jīng)配置好了 Flutter 開發(fā)環(huán)境,具體可參考 Flutter 配置指南 [3] 。同時,從 官方插件庫 [4] 下載待適配的三方插件。本指導(dǎo)書, 以適配 fflutter_exit_app [5] 為例
image-20250417200546042 (二)插件目錄結(jié)構(gòu) 下載并解壓插件后,我們會看到以下目錄結(jié)構(gòu):
lib :對接 Dart 端代碼的入口,由此文件接收到參數(shù)后,通過 channel 將數(shù)據(jù)發(fā)送到原生端。 android :安卓端代碼實現(xiàn)目錄。 example :一個依賴于該插件的 Flutter 應(yīng)用程序,用于說明如何使用它。 CHANGELOG.md :記錄每個版本中的更改。 (三)創(chuàng)建插件的鴻蒙模塊 在插件目錄下,打開 Terminal,執(zhí)行以下命令來創(chuàng)建一個鴻蒙平臺的 Flutter 模塊:
flutter create . --template=plugin --platforms=ohos
步驟:
用 vscode/trae 打開剛剛下載好的插件。
執(zhí)行命令 flutter create . --template=plugin --platforms=ohos
創(chuàng)建一個 ohos 平臺的 flutter 模塊。
(四)在根目錄下添加鴻蒙平臺配置 在項目根目錄的 pubspec.yaml
文件中,添加鴻蒙平臺的相關(guān)配置:
name: flutter_exit_app description: A flutter plugin provides the best way to exit the app doesn't call exit(0) in dart code. version: 1.1 .4 homepage: https://github.com/xang555/flutter_exit_app environment: sdk: ">=2.14.0 <4.0.0" flutter: ">=2.5.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter lints: ^3.0.0 test: mockito: build_runner: # For information on the generic Dart part of this file, see the # following page: https://v/tools/pub/pubspec # The following section is specific to Flutter. flutter: # This section identifies this Flutter project as a plugin project. # The 'pluginClass' and Android 'package' identifiers should not ordinarily # be modified. They are used by the tooling to maintain consistency when # adding or updating assets for this project. plugin: platforms: android: package: com.laoitdev.lib.exit.app.flutter_exit_app pluginClass: FlutterExitAppPlugin ios: pluginClass: FlutterExitAppPlugin ohos: package: com.laoitdev.lib.exit.app.flutter_exit_app pluginClass: FlutterExitAppPlugin # To add assets to your plugin package, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg # # For details regarding assets in packages, see # https://v/assets-and-images/#from-packages # # An image asset can refer to one or more resolution-specific "variants", see # https://v/assets-and-images/#resolution-aware. # To add custom fonts to your plugin package, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts in packages, see # https://v/custom-fonts/#from-packages
(五)編寫鴻蒙插件的原生 ArkTS 模塊 1. 創(chuàng)建鴻蒙插件模塊 使用 DevEco Studio 打開鴻蒙項目。
2. 修改相關(guān)配置文件 在 ohos
目錄內(nèi)的 oh-package.json5
文件中添加 libs/flutter.har
依賴,并創(chuàng)建 .gitignore
文件,添加以下內(nèi)容以忽略 libs
目錄:
/node_modules /oh_modules /local.properties /.preview /.idea /build /libs *.har /.cxx /. test /BuildProfile.ets /oh-package-lock.json5
oh-package.json5
文件內(nèi)容如下:
{ "name" : "flutter_exit_app" , "version" : "1.0.0" , "description" : "flutter plugin provides the best way to exit the app doesn't call exit(0) in dart code." , "main" : "index.ets" , "author" : "nutpi" , "license" : "Apache-2.0" , "dependencies" : { "@ohos/flutter_ohos" : "file:./har/flutter.har" }, "modelVersion" : "5.0.4" }
在 ohos
目錄下創(chuàng)建 index.ets
文件,導(dǎo)出配置:
import FlutterExitAppPlugin from './src/main/ets/components/plugin/FlutterExitAppPlugin' ; export default FlutterExitAppPlugin;
3. 編寫 ETS 代碼 文件結(jié)構(gòu)和代碼邏輯可以參考安卓或 iOS 的實現(xiàn),鴻蒙的 API 文檔可以參考 :https:///openharmony-sig/flutter_packages/tree/master/packages/path_provider/path_provider_android
ohos 的 api 可以參考:https:///openharmony/docs
以下是 FlutterExitAppPlugin.ets
文件的代碼示例:
import { FlutterPlugin, FlutterPluginBinding, MethodCall, MethodCallHandler, MethodChannel, MethodResult, } from '@ohos/flutter_ohos' ; import { AbilityAware, AbilityPluginBinding } from '@ohos/flutter_ohos' ; import {common, UIAbility } from '@kit.AbilityKit' ; import { BusinessError } from '@kit.BasicServicesKit' ; /** FlutterExitAppPlugin **/ export default class FlutterExitAppPlugin implements FlutterPlugin , MethodCallHandler , AbilityAware { private channel: MethodChannel | null = null ; private static _context: Context | null = null ; private static _uiContext: common.UIAbilityContext | null = null ; constructor () { } static get uiContext(): common.UIAbilityContext | null { return FlutterExitAppPlugin._uiContext; } static get context(): common.Context | null { return FlutterExitAppPlugin._context; } get uiContext(): common.UIAbilityContext | null { return FlutterExitAppPlugin._uiContext; } getUniqueClassName(): string { return "FlutterExitAppPlugin" } onAttachedToAbility(binding: AbilityPluginBinding): void { FlutterExitAppPlugin._uiContext = binding.getAbility().context; // Called when the plugin is attached to an Ability. } onDetachedFromAbility(): void { // this._uiContext = null; } onAttachedToEngine(binding: FlutterPluginBinding): void { this .channel = new MethodChannel(binding.getBinaryMessenger(), "flutter_exit_app" ); this .channel.setMethodCallHandler( this ) } onDetachedFromEngine(binding: FlutterPluginBinding): void { if ( this .channel != null ) { this .channel.setMethodCallHandler( null ) } } onMethodCall(call: MethodCall, result : MethodResult): void { if (call.method == "getPlatformVersion" ) { result.success( "OpenHarmony ^ ^ " ) } else if (call.method == "com.laoitdev.exit.app" ) { console .info( "hhhhhhhhhh" ) if (FlutterExitAppPlugin._uiContext) { // Add null check here try { FlutterExitAppPlugin._uiContext.terminateSelf() .then( () => { // 執(zhí)行正常業(yè)務(wù) console .info( 'terminateSelf succeed' ); result.success( "Done" ); // Inform Flutter about success }) .catch( ( err: BusinessError ) => { // 處理業(yè)務(wù)邏輯錯誤 console .error( `terminateSelf failed, code is ${err.code} , message is ${err.message} ` ); result.error( "TERMINATE_FAILED" , `terminateSelf failed: ${err.message} ` , null ); }); } catch (err) { // 捕獲同步的參數(shù)錯誤 let code = (err as BusinessError).code; let message = (err as BusinessError).message; console .error( `terminateSelf failed, code is ${code} , message is ${message} ` ); result.error( "TERMINATE_ERROR" , `terminateSelf error: ${message} ` , null ); } } else { console .error( "UIContext is null, cannot terminate self." ); result.error( "CONTEXT_NULL" , "UIContext is null" , null ); // Inform Flutter about the error } } else { result.notImplemented() } } }
現(xiàn)在就可以正常使用啦。
這里我主要參考的是
4.UIAbilityContext.terminateSelf import { UIAbility } from '@kit.AbilityKit' ; import { BusinessError } from '@kit.BasicServicesKit' ; export default class EntryAbility extends UIAbility { onForeground () { try { this.context.terminateSelf() . then (() => { // 執(zhí)行正常業(yè)務(wù) console.info( 'terminateSelf succeed' ); }) .catch((err: BusinessError) => { // 處理業(yè)務(wù)邏輯錯誤 console.error(`terminateSelf failed, code is ${err.code} , message is ${err.message} `); }); } catch (err) { // 捕獲同步的參數(shù)錯誤 let code = (err as BusinessError).code; let message = (err as BusinessError).message; console.error(`terminateSelf failed, code is ${code} , message is ${message} `); } } }
參考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-inner-application-uiabilitycontext#uiabilitycontextterminateself-1
三、關(guān)于鴻蒙版 Flutter 的 context 這里我使用的是 UIAbilityContext
UIAbilityContext 插件繼承 AbilityAware
并且在 onAttachedToAbility
方法中獲取。
export default class XXXPlugin implements FlutterPlugin , MethodCallHandler , AbilityAware { private _uiContext: common.UIAbilityContext | null = null ; onAttachedToAbility(binding: AbilityPluginBinding): void { this .XXXPlugin = binding.getAbility().context; } onDetachedFromAbility(): void { this .XXXPlugin = null ; } }
該 uiContext
可以用于獲取 applicationInfo
等屬性。以及退出等操作。還有另外一種是
ApplicationContex 你可以直接從 onAttachedToEngine
方法中獲取。
private context: Context | null = null ; onAttachedToEngine(binding: FlutterPluginBinding): void { this .context = binding.getApplicationContext(); } onDetachedFromEngine(binding: FlutterPluginBinding): void { this .context = null ; }
該 context
可以用于獲取 applicationInfo
等屬性。
let applicationInfo = this.context.applicationInfo;
四、編寫 Example 1. 創(chuàng)建 Example 應(yīng)用 在插件根目錄下創(chuàng)建一個名為 example
的文件夾,用于存放示例應(yīng)用。在 example
文件夾中,創(chuàng)建一個鴻蒙平臺的 Flutter 應(yīng)用,用于驗證插件功能。
2. 簽名與運行 使用 Deveco Studio
打開 example > ohos
目錄,單擊 File > Project Structure > Project > Signing Configs
,勾選 Automatically generate signature
,等待自動簽名完成。然后運行以下命令:
flutter pub get flutter build hap --debug
如果應(yīng)用正常啟動,說明插件適配成功。如果沒有,歡迎大家聯(lián)系堅果派一起支持。
五、總結(jié) 通過以上步驟,我們成功地將 flutter_exit_app 三方庫適配到了鴻蒙平臺。這個過程涉及到了解插件的基本信息、配置開發(fā)環(huán)境、創(chuàng)建鴻蒙模塊、編寫原生代碼以及測試驗證等多個環(huán)節(jié)。希望這篇博客能夠幫助到需要進行 flutter_exit_app 鴻蒙適配的開發(fā)者們,讓大家在鴻蒙生態(tài)的開發(fā)中更加得心應(yīng)手。
六、參考 [如何使用 Flutter 與 OpenHarmony 通信 FlutterChannel](https:///openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/如何使用Flutter與OpenHarmony通信 FlutterChannel.md "如何使用 Flutter 與 OpenHarmony 通信 FlutterChannel") [開發(fā) module](https:///openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/如何使用混合開發(fā) module.md "開發(fā) module") [開發(fā) FFI plugin](https:///openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/開發(fā)FFI plugin.md "開發(fā) FFI plugin") 【感謝大家的認可!】若內(nèi)容對您有幫助,歡迎點贊??關(guān)注??支持!對鴻蒙原生開發(fā)以及跨平臺開發(fā)鴻蒙感興趣的小伙伴,歡迎添加我的微信(微信號:17752170152),我們一起探討技術(shù)、分享經(jīng)驗,攜手成長!
七、堅果派 堅果派由堅果等人創(chuàng)建,團隊擁有若干華為 HDE,以及若干其他領(lǐng)域的三十余位萬粉博主運營。專注于分享的技術(shù)包括 HarmonyOS/OpenHarmony,ArkUI-X,元服務(wù),服務(wù)卡片,華為自研語言,BlueOS 操作系統(tǒng)、團隊成員聚集在北京、上海、廣州、深圳、南京、杭州、蘇州、寧夏等地。 聚焦“鴻蒙原生應(yīng)用”、“智能物聯(lián)”和“AI 賦能”、“人工智能”四大業(yè)務(wù)領(lǐng)域,依托華為開發(fā)者專家等強大的技術(shù)團隊,以及涵蓋需求、開發(fā)、測試、運維于一體的綜合服務(wù)體系,賦能文旅、媒體、社交、家居、消費電子等行業(yè)客戶,滿足社區(qū)客戶數(shù)字化升級轉(zhuǎn)型的需求,幫助客戶實現(xiàn)價值提升。 目前上架鴻蒙原生應(yīng)用 18 款,三方庫 72 個。期待與大家溝通。
地址:https:///nutpi
https:///nutpi
官網(wǎng):https://www./
[1] 適配倉庫地址: https:///nutpi/flutter_exit_app
[2] Flutter 使用指導(dǎo)文檔: https:///openharmony-sig/flutter_samples/blob/master/ohos/docs/07_plugin/ohos%E5%B9%B3%E5%8F%B0%E9%80%82%E9%85%8Dflutter%E4%B8%89%E6%96%B9%E5%BA%93%E6%8C%87%E5%AF%BC.md
[3] Flutter 配置指南: https:///openharmony-sig/flutter_flutter/blob/master/README.md
[4] 官方插件庫: https://v/
[5] fflutter_exit_app: https://pub-web./packages/flutter_exit_app/versions/1.1.4
[6] 開發(fā) package: https:///openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/開發(fā)package.md
[7] 開發(fā) plugin: https:///openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/開發(fā)plugin.md
[8] developing-packages: https://docs./packages-and-plugins/developing-packages
[9] 適配倉庫地址: https:///nutpi/flutter_exit_app