Flutter到HarmonyOS Next 的跨越:memory

06-02 997阅读

Flutter到鸿蒙的跨越:memory_info库的鸿蒙适配之旅

本项目作者:kirk/坚果

您可以使用这个Flutter插件来更改应用程序图标上的角标

作者仓库:https://github.com/MrOlolo/memory_info/tree/master/memory_info

在数字化浪潮的推动下,跨平台开发框架如 Flutter 凭借其高效、便捷的特性,成为了开发者们的宠儿。而鸿蒙系统的崛起,更是为跨平台开发注入了新的活力。为了助力开发者在鸿蒙生态中快速实现 memory_info可帮助您获取设备内存信息(ram&rom),本文将深入浅出地为大家解析如何适配 memory_info 三方库至鸿蒙平台。

一、适配鸿蒙版 memory_info 三方库

(一)版本选择与仓库简介

我们先去 pub 上查看最新版本,我们选择以 0.0.10版本为基础进行适配。memory_info可帮助您获取设备内存信息(ram&rom),其 GitHub 仓库为https://github.com/MrOlolo/memory_info/tree/master/memory_info ,我们的目标是将这个插件适配到鸿蒙平台。

(二)引入背景与使用场景

在 OpenHarmony 北向生态的发展过程中,许多已经适配了 Flutter 的厂商在接入 OpenHarmony 时,都希望能够继续使用 memory_info 来实现内存查看功能。因此,我们提供了这个适配方案,采用插件化的适配器模式,帮助生态伙伴快速实现产品化。

本方案适用于已经支持 Flutter 框架的设备在移植到 OpenHarmony 系统过程中,作为一个备选方案。

(三)使用文档与插件库使用

适配 OpenHarmony 平台的详细使用指导可以参考:Flutter使用指导文档

在项目中使用该插件库时,只需在 pubspec.yaml 文件的 dependencies 中新增如下配置:

dependencies:
  memory_info:
    git:
      url: "https://gitcode.com/nutpi/memory_info.git"
      path: ""

然后在项目根目录运行 flutter pub get,即可完成依赖添加

接下来是具体的适配过程。

二、适配过程详解

(一)准备工作

确保已经配置好了 Flutter 开发环境,具体可参考 Flutter 配置指南。同时,从 官方插件库 下载待适配的三方插件。本指导书, 以适配 memory_info 为例

Flutter到HarmonyOS Next 的跨越:memory

(二)插件目录结构

下载并解压插件后,我们会看到以下目录结构:

  • lib :对接 Dart 端代码的入口,由此文件接收到参数后,通过 channel 将数据发送到原生端。
  • android :安卓端代码实现目录。
  • ios :iOS 原生端实现目录。
  • example :一个依赖于该插件的 Flutter 应用程序,用于说明如何使用它。
  • README.md :介绍包的文件。
  • CHANGELOG.md :记录每个版本中的更改。
  • LICENSE :包含软件包许可条款的文件。

    (三)创建插件的鸿蒙模块

    在插件目录下,打开 Terminal,执行以下命令来创建一个鸿蒙平台的 Flutter 模块:

    flutter create . --org com.mrololo.memory_info --template=plugin --platforms=ohos
    

    步骤:

    1. 用vscode/trae打开刚刚下载好的插件。

    2. 打开Terminal,cd到插件目录下。

    3. 执行命令flutter create . --org com.mrololo.memory_info --template=plugin --platforms=ohos 创建一个ohos平台的flutter模块。

    第一个问题,修改sdk的版本,适配旧版本。

    我们做好修改就好。

    (四)在根目录下添加鸿蒙平台配置

    在项目根目录的 pubspec.yaml 文件中,添加鸿蒙平台的相关配置:

    name: memory_info
    description: Flutter package to get device memory info(ram&rom) at android/ios devices
    repository: https://com.nutpi.memory_info/
    version: 0.0.4
    environment:
      sdk: ">=2.12.0 =1.20.0"
    dependencies:
      flutter:
        sdk: flutter
    dev_dependencies:
      flutter_test:
        sdk: flutter
    # For information on the generic Dart part of this file, see the
    # following page: https://dart.dev/tools/pub/pubspec
    # The following section is specific to Flutter.
    flutter:
      plugin:
        platforms:
          android:
            package: com.mrololo.memory_info
            pluginClass: MemoryInfoPlugin
          ios:
            pluginClass: MemoryInfoPlugin
          ohos:
            package: com.mrololo.memory_info
            pluginClass: MemoryInfoPlugin
    

    (五)编写鸿蒙插件的原生 ArkTS模块

    1. 创建鸿蒙插件模块

    使用 DevEco Studio 打开鸿蒙项目。

    2. 修改相关配置文件

    在 ohos 目录内的 oh-package.json5 文件中添加 libs/flutter.har 依赖,并创建 .gitignore 文件,添加以下内容以忽略 libs 目录:

    /node_modules
    /oh_modules
    /local.properties
    /.preview
    /.idea
    /build
    /libs
    *.har
    /.cxx
    /.test
    /BuildProfile.ets
    /oh-package-lock.json5
    

    oh-package.json5 文件内容如下:

    {
      "name": "memory_info",
      "version": "1.0.0",
      "description": "Flutter package to get device memory info(ram&rom) at Android/ios/OpenHarmony devices",
      "main": "index.ets",
      "author": "nutpi",
      "license": "Apache-2.0",
      "dependencies": {
        "@ohos/flutter_ohos": "file:./har/flutter.har"
      }
    }
    

    在 ohos 目录下创建 index.ets 文件,导出配置:

    import MemoryInfoPlugin from './src/main/ets/components/plugin/MemoryInfoPlugin';
    export default MemoryInfoPlugin;
    
    3. 编写 ETS 代码

    ohos的api可以参考:https://gitcode.com/openharmony/docs

    以下是 MemoryInfoPlugin 文件的代码示例:

    import {
      FlutterPlugin,
      FlutterPluginBinding,
      MethodCall,
      MethodCallHandler,
      MethodChannel,
      MethodResult,
    } from '@ohos/flutter_ohos';
    import { storageStatistics,statfs } from '@kit.CoreFileKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import { hidebug } from '@kit.PerformanceAnalysisKit';
    import appManager from '@ohos.application.appManager';
    /** MemoryInfoPlugin **/
    export default class MemoryInfoPlugin implements FlutterPlugin, MethodCallHandler {
      private channel: MethodChannel | null = null;
      constructor() {
      }
      getUniqueClassName(): string {
        return "MemoryInfoPlugin"
      }
      onAttachedToEngine(binding: FlutterPluginBinding): void {
        this.channel = new MethodChannel(binding.getBinaryMessenger(), "com.nutpi.memory_info");
        this.channel.setMethodCallHandler(this)
      }
      onDetachedFromEngine(binding: FlutterPluginBinding): void {
        if (this.channel != null) {
          this.channel.setMethodCallHandler(null)
        }
      }
       onMethodCall(call: MethodCall, result: MethodResult)  {
        if (call.method == "getPlatformVersion") {
          result.success("OpenHarmony ^ ^ ")
        } else if (call.method == "getDiskSpace") {
          try {
            const Info = new Map();
            storageStatistics.getTotalSize()
            // 获取内置存储的总空间大小(单位为Byte),同步返回
            let diskTotalSpaceBytes =  storageStatistics.getFreeSizeSync();
            // 获取内置存储的可用空间大小(单位为Byte),同步返回
            let diskFreeSpaceBytes =  storageStatistics.getTotalSizeSync();
             // 转换为 MB
             const mbFactor = 1024 * 1024;
             let diskTotalSpaceMB = diskTotalSpaceBytes / mbFactor;
             let diskFreeSpaceMB = diskFreeSpaceBytes / mbFactor;
             Info.set("diskTotalSpace", diskTotalSpaceMB);
             Info.set("diskFreeSpace", diskFreeSpaceMB);
             console.info(`getDiskSpace success: total=${diskTotalSpaceMB}MB, free=${diskFreeSpaceMB}MB`);
             result.success(Info);
          } catch (err) {
            console.error("getDiskSpace failed with error:" + JSON.stringify(err));
            // 在 Flutter 端,通常期望一个 Map 或者 null/error
            // 这里返回一个空的 Map 或者可以考虑 result.error
            result.error("DISK_SPACE_ERROR", "Failed to get disk space", JSON.stringify(err));
          }
        } else if (call.method == "getMemoryInfo") {
          const Info = new Map();
          // 转换为 MB
          const mbFactor = 1024 * 1024;
          let systemMemInfo: hidebug.SystemMemInfo = hidebug.getSystemMemInfo();
          // Convert bigint to number before division
          Info.set("total", Number(systemMemInfo.totalMem)/mbFactor);
          Info.set("free", Number(systemMemInfo.freeMem)/mbFactor);
          Info.set("usedByApp", Number(systemMemInfo.availableMem)/mbFactor);
          console.info(`totalMem: ${systemMemInfo.totalMem}, freeMem: ${systemMemInfo.freeMem}, ` +
            `availableMem: ${systemMemInfo.availableMem}`);
          //获取当前应用的存储空间大小。
          storageStatistics.getCurrentBundleStats((err: BusinessError, bundleStats: storageStatistics.BundleStats) => {
            if (err) {
              console.error(`Invoke getCurrentBundleStats failed, code is ${err.code}, message is ${err.message}`);
            } else {
              console.info(`Invoke getCurrentBundleStats succeeded, appsize is ${bundleStats.appSize}`);
              Info.set("appSize", Number(bundleStats.appSize)/mbFactor);
            }
            result.success(Info);
          });
        } else {
          result.notImplemented()
        }
       }
    }
    

    这里我主要参考的是

    三、应用及文件系统空间统计

    1.storageStatistics.getCurrentBundleStats

    getCurrentBundleStats(): Promise

    应用异步获取当前应用存储空间大小(单位为Byte),以Promise方式返回。

    系统能力:SystemCapability.FileManagement.StorageService.SpatialStatistics

    返回值:

    类型说明
    PromisePromise对象,返回指定卷上的应用存储空间大小(单位为Byte)。

    错误码:

    以下错误码的详细介绍请参见文件管理错误码。

    错误码ID错误信息
    401The input parameter is invalid. Possible causes: Mandatory parameters are left unspecified.
    13600001IPC error.
    13900042Unknown error.

    示例:

    import { BusinessError } from '@kit.BasicServicesKit';storageStatistics.getCurrentBundleStats().then((BundleStats: storageStatistics.BundleStats) => {  console.info("getCurrentBundleStats successfully:" + JSON.stringify(BundleStats));}).catch((err: BusinessError) => {  console.error("getCurrentBundleStats failed with error:"+ JSON.stringify(err));});
    

    https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-storage-statistics#storagestatisticsgetfreesize15

    2.应用及文件系统空间统计

    在系统中,可能出现系统空间不够或者cacheDir等目录受系统配额限制等情况,需要应用开发者关注系统剩余空间,同时控制应用自身占用的空间大小。

    https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-fs-space-statistics

    表1 文件系统空间和应用空间统计

    模块接口名功能
    @ohos.file.storageStatisticsgetCurrentBundleStats获取当前应用的存储空间大小(单位为Byte)。
    @ohos.file.storageStatisticsgetFreeSize异步获取内置存储的总空间大小(单位为Byte)。
    @ohos.file.storageStatisticsgetTotalSize异步获取内置存储的可用空间大小(单位为Byte)。

    表2 应用空间统计

    BundleStats属性含义统计路径
    appSize应用安装文件大小(单位为Byte)应用安装文件保存在以下目录:/data/storage/el1/bundle
    cacheSize应用缓存文件大小(单位为Byte)应用的缓存文件保存在以下目录:/data/storage/el1/base/cache/data/storage/el1/base/haps/entry/cache/data/storage/el2/base/cache/data/storage/el2/base/haps/entry/cache
    dataSize应用文件存储大小(除应用安装文件和缓存文件)(单位为Byte)应用文件由本地文件、分布式文件以及数据库文件组成。本地文件保存在以下目录(注意缓存文件目录为以下目录的子目录):/data/storage/el1/base/data/storage/el2/base分布式文件保存在以下目录:/data/storage/el2/distributedfiles数据库文件保存在以下目录:/data/storage/el1/database/data/storage/el2/database

    https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-hidebug#hidebuggetsystemmeminfo12

    3.使用 HiDebug 模块

    HiDebug 提供了一系列接口,可以获取系统的内存信息,进而间接获取 RAM size 。具体步骤如下:

    • 导入 HiDebug 模块 :在代码中导入 HiDebug 模块,import { hidebug } from '@ohos.hidebug';。

      4.SystemMemInfo

      描述系统内存信息。

      系统能力:SystemCapability.HiviewDFX.HiProfiler.HiDebug

      名称类型必填说明
      totalMembigint系统总的内存,以KB为单位,计算方式:/proc/meminfo: MemTotal。
      freeMembigint系统空闲的内存,以KB为单位,计算方式:/proc/meminfo: MemFree。
      availableMembigint系统可用的内存,以KB为单位,计算方式:/proc/meminfo: MemAvailable
      • usedByApp: 表示当前应用程序占用的内存大小(单位:MB)。这是通过 Runtime 类计算得到的应用已分配内存减去其中的空闲内存。
      • total: 表示设备的总内存(RAM)大小(单位:MB)。这是通过 ActivityManager.MemoryInfo 获取的系统总内存。
      • free: 表示设备当前可用的内存大小(单位:MB)。这是通过 ActivityManager.MemoryInfo 获取的系统可用内存,指系统在开始强制关闭后台进程之前可用的内存。
      • lowMemory: 一个布尔值,表示系统当前是否处于低内存状态。如果为 true,则表示系统内存不足。

        5.appManager.isRamConstrainedDevice7+

        isRamConstrainedDevice(): Promise

        查询是否为ram受限设备。使用Promise异步回调。

        系统能力:SystemCapability.Ability.AbilityRuntime.Core

        返回值:

        类型说明
        PromisePromise对象。返回true表示是ram受限设备;返回false表示不是ram受限设备。

        示例:

        import appManager from '@ohos.application.appManager';import { BusinessError } from '@ohos.base';
        appManager.isRamConstrainedDevice().then((data) => {    console.log(`The result of isRamConstrainedDevice is: ${JSON.stringify(data)}`);}).catch((error: BusinessError) => {    console.error(`error: ${JSON.stringify(error)}`);});
        

        https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-application-appmanager

        6.appManager.isRamConstrainedDevice7+

        isRamConstrainedDevice(callback: AsyncCallback): void

        查询是否为ram受限设备。使用callback异步回调。

        系统能力:SystemCapability.Ability.AbilityRuntime.Core

        参数:

        参数名类型必填说明
        callbackAsyncCallback回调函数。返回true表示当前是ram受限设备;返回false表示当前不是ram受限设备。

        示例:

        import appManager from '@ohos.application.appManager';
        appManager.isRamConstrainedDevice((error, data) => {    if (error && error.code !== 0) {        console.error(`isRamConstrainedDevice fail, error: ${JSON.stringify(error)}`);    } else {        console.log(`The result of isRamConstrainedDevice is: ${JSON.stringify(data)}`);    }});
        

        7.使用 HiDebug 模块

        HiDebug 提供了一系列接口,可以获取系统的内存信息,进而间接获取 RAM size 。具体步骤如下:

        • 导入 HiDebug 模块 :在代码中导入 HiDebug 模块,import { hidebug } from '@ohos.hidebug';。
        • 调用接口获取内存信息 :调用 hidebug.getSystemMemInfo() 接口获取系统内存信息,该方法返回一个对象,其中包含了系统的总内存、可用内存等信息。

          https://github.com/SebghatYusuf/system_info_plus

          四、编写 Example

          1. 创建 Example 应用

          在插件根目录下创建一个名为 example 的文件夹,用于存放示例应用。在 example 文件夹中,创建一个鸿蒙平台的 Flutter 应用,用于验证插件功能。

          2. 签名与运行

          使用 Deveco Studio 打开 example > ohos 目录,单击 File > Project Structure > Project > Signing Configs,勾选 Automatically generate signature,等待自动签名完成。然后运行以下命令:

          flutter pub get
           flutter build hap --debug
          

          如果应用正常启动,说明插件适配成功。如果没有,欢迎大家联系坚果派一起支持。

          五、总结

          通过以上步骤,我们成功地将 memory_info 三方库适配到了鸿蒙平台。这个过程涉及到了解插件的基本信息、配置开发环境、创建鸿蒙模块、编写原生代码以及测试验证等多个环节。希望这篇博客能够帮助到需要进行 memory_info可帮助您获取设备内存信息(ram&rom) 鸿蒙适配的开发者们,让大家在鸿蒙生态的开发中更加得心应手。

          六、参考

          • [如何使用Flutter与OpenHarmony通信 FlutterChannel](https://gitcode.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/如何使用Flutter与OpenHarmony通信 FlutterChannel.md)
          • [开发module](https://gitcode.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/如何使用混合开发 module.md)
          • 开发package
          • 开发plugin
          • [开发FFI plugin](https://gitcode.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/开发FFI plugin.md)
          • developing-packages
          • 适配仓库地址
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码