HarmonyOS开发实例:【分布式新闻客户端】

news2025/1/17 5:59:29

 

介绍

本篇Codelab基于栅格布局、设备管理和多端协同,实现一次开发,多端部署的分布式新闻客户端页面。主要包含以下功能:

  1. 展示新闻列表以及左右滑动切换新闻Tab。
  2. 点击新闻展示新闻详情页。
  3. 点击新闻详情页底部的分享按钮,发现周边处在同一无线网络下的设备并进行可信认证连接。
  4. 可信认证后,再次点击分享按钮,选择已连接的设备进行跨设备启动UIAbility。

最终效果图如下:

相关概念

  • [栅格布局]:一种通用的辅助定位工具,解决多尺寸多设备的动态布局问题。
  • [设备管理]:模块提供分布式设备管理能力。
  • [跨设备启动UIAbility]:多端上的不同UIAbility/ServiceExtensionAbility同时运行、或者交替运行实现完整的业务。
  • [Tabs组件]:通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。

相关权限

本篇Codelab使用了设备管理及跨设备实现多端协同能力,需要手动替换full-SDK,并在配置文件module.json5文件requestPermissions属性中添加如下权限:

  • [分布式设备认证组网权限]:ohos.permission.ACCESS_SERVICE_DM。
  • [设备间的数据交换权限]:ohos.permission.DISTRIBUTED_DATASYNC。

约束与限制

  1. 本篇Codelab部分能力依赖于系统API,需下载full-SDK并替换DevEco Studio自动下载的public-SDK。具体操作可参考指南[《如何替换full-SDK》]。
  2. 本篇Codelab使用的部分API仅系统应用可用,需要提升应用等级。

环境搭建

软件要求

  • [DevEco Studio]版本:DevEco Studio 4.0 Beta2。
  • OpenHarmony SDK版本:API version 10。
  • 鸿蒙开发文档指导:qr23.cn/AKFP8k点击或复制转到。

硬件要求

  • 开发板类型:[润和RK3568开发板]。
  • OpenHarmony系统:4.0 Beta1。 -鸿蒙HarmonyOS与OpenHarmony开发籽料mau123789是v直接拿

搜狗高速浏览器截图20240326151450.png

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. [获取OpenHarmony系统版本]:标准系统解决方案(二进制)。以4.0 Beta1版本为例:

  1. 搭建烧录环境。

    1. [完成DevEco Device Tool的安装]
    2. [完成RK3568开发板的烧录]
  2. 搭建开发环境。

    1. 开始前请参考[工具准备],完成DevEco Studio的安装和开发环境配置。
    2. 开发环境配置完成后,请参考[使用工程向导]创建工程(模板选择“Empty Ability”)。
    3. 工程创建完成后,选择使用[真机进行调测]。

代码结构解读

本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在gitee中提供。

├──entry/src/main/ets                   // 代码区
│  ├──common
│  │  ├──constants
│  │  │  └──CommonConstants.ets         // 常量类
│  │  └──utils
│  │     └──Logger.ets                  // 日志工具类
│  ├──entryability
│  │  └──EntryAbility.ets               // 程序入口类
│  ├──model
│  │  └──RemoteDeviceModel.ets          // 设备管理类
│  ├──pages
│  │  ├──Index.ets                      // 新闻列表页
│  │  └──NewsDetail.ets                 // 新闻详情页
│  ├──view
│  │  ├──DetailFooter.ets               // 详情页页脚
│  │  ├──DetailHeadContent.ets          // 新闻详情
│  │  ├──DeviceListDialog.ets           // 设备列表弹窗
│  │  ├──NewsList.ets                   // 新闻列表
│  │  └──NewsTab.ets                    // 新闻页签
│  └──viewmodel
│     └──NewsDataModel.ets              // 新闻数据处理
└──entry/src/main/resources             // 资源文件目录

构建新闻列表页

新闻列表页由页签区域和新闻列表区域组成,页签区域为自定义布局TabBuilder,新闻列表区域为Tabs组件嵌套List组件,并适配不同尺寸设备对应的栅格。新闻列表页能够左右滑动或点击页签切换新闻Tab,并设置点击新闻跳转至新闻详情页。

 
// NewsTab.ets
@Component
export default struct NewsTab {
  @State currentIndex: number = 0;
  @State currentBreakpoint: string = CommonConstants.BREAKPOINT_SM;
  private newsItems: NewsData[] = [];

  // 自定义页签栏
  @Builder TabBuilder(title: Resource, index: number) {
    Row() {
      Text(title)
        .fontSize(this.currentIndex === index ? $r('app.float.lager_font_size') : $r('app.float.middle_font_size'))
        .fontWeight(this.currentIndex === index ? CommonConstants.FONT_WEIGHT_500 : FontWeight.Normal)
        .fontColor(this.currentIndex === index ? $r('app.color.tab_font_select') : $r('app.color.font_color_gray'))
    }
    .layoutWeight(1)
    .margin({
      right: $r('app.float.news_tab_margin_right'),
      left: (this.currentBreakpoint === CommonConstants.BREAKPOINT_SM && index === 0) ?
        $r('app.float.news_tab_margin_left') : 0
    })
    .height(this.currentIndex === index ? $r('app.float.news_tab_current_height') : $r('app.float.news_tab_height'))
  }

  build() {
    ...
    Tabs() {
      ForEach(CommonConstants.ALL_TITLE, (title: string, index: number) => {
        TabContent() {
          // 新闻内容列表
          NewsList({ newsItems: NewsDataModel.getNewsByType(this.newsItems, title) })
        }
        .tabBar(this.TabBuilder(NewsDataModel.getTypeByStr(title), index))
      }, (title: string, index: number) => index + JSON.stringify(title))
    }
    .barHeight($r('app.float.news_tab_bar_height'))
    .barWidth(CommonConstants.FULL_COMPONENT)
    .barMode(this.currentBreakpoint === CommonConstants.BREAKPOINT_SM ? BarMode.Scrollable : BarMode.Fixed)
    .onChange((index: number) => {
      this.currentIndex = index;
    })
    ...
  }
}

// NewsList.ets
@Component
export default struct NewsList {
  private newsItems: NewsData[] = [];

  build() {
    List() {
      ForEach(this.newsItems, (item: NewsData, index: number) => {
        ListItem() {
          // 栅格布局
          GridRow({
            columns: {
              sm: CommonConstants.FOUR_COLUMN,
              md: CommonConstants.EIGHT_COLUMN,
              lg: CommonConstants.TWELVE_COLUMN
            },
            breakpoints: {
              value: [
                CommonConstants.SMALL_DEVICE_TYPE,
                CommonConstants.MIDDLE_DEVICE_TYPE,
                CommonConstants.LARGE_DEVICE_TYPE
              ]
            },
            gutter: { x: $r('app.float.grid_row_gutter') }
          }) {
            GridCol({
              span: {
                sm: CommonConstants.FOUR_COLUMN,
                md: CommonConstants.EIGHT_COLUMN,
                lg: CommonConstants.EIGHT_COLUMN
              },
              offset: {
                sm: CommonConstants.ZERO_COLUMN,
                md: CommonConstants.ZERO_COLUMN,
                lg: CommonConstants.TWO_COLUMN
              }
            }) {
              NewsItem({ newsItem: item, isLast: index === this.newsItems.length - 1 })
            }
          }
        }
      }, (item: NewsData, index: number) => index + JSON.stringify(item))
    }
    .height(CommonConstants.FULL_COMPONENT)
  }
}

构建新闻详情页

新闻详情页

新闻详情页由新闻内容区域和页脚区域组成,其中新闻内容区域为Scroll组件嵌套栅格组件展示新闻详情,页脚区域为栅格布局,包含TextInput组件和三个按钮图标。

 
// DetailHeadContent.ets
build() {
  Column() {
    ...
    // 可滚动的容器组件
    Scroll() {
      // 栅格布局
      GridRow({
        columns: {
          sm: CommonConstants.FOUR_COLUMN,
          md: CommonConstants.EIGHT_COLUMN,
          lg: CommonConstants.TWELVE_COLUMN
        },
        breakpoints: {
          value: [
          CommonConstants.SMALL_DEVICE_TYPE,
          CommonConstants.MIDDLE_DEVICE_TYPE,
          CommonConstants.LARGE_DEVICE_TYPE
          ]
        },
        gutter: { x: $r('app.float.grid_row_gutter') }
      }) {
        GridCol({
          span: {
            sm: CommonConstants.FOUR_COLUMN,
            md: CommonConstants.EIGHT_COLUMN,
            lg: CommonConstants.EIGHT_COLUMN
          },
          offset: {
            sm: CommonConstants.ZERO_COLUMN,
            md: CommonConstants.ZERO_COLUMN,
            lg: CommonConstants.TWO_COLUMN
          }
        }) {
          ...
        }
        ...
      }
    }
    .padding({
      bottom: $r('app.float.news_detail_padding_bottom')
    })
    .scrollBar(BarState.Off)
  }
  .margin({
    left: $r('app.float.news_detail_margin'),
    right: $r('app.float.news_detail_margin')
  })
  .height(CommonConstants.FULL_COMPONENT)
  .alignItems(HorizontalAlign.Start)
}

// DetailFooter.ets
build() {
  Column() {
    // 分割线
    Divider()
      .color($r('app.color.detail_divider_color'))
      .width(CommonConstants.FULL_COMPONENT)

    // 栅格布局
    GridRow({
      columns: {
        sm: CommonConstants.FOUR_COLUMN,
        md: CommonConstants.EIGHT_COLUMN,
        lg: CommonConstants.TWELVE_COLUMN
      },
      breakpoints: {
        value: [
        CommonConstants.SMALL_DEVICE_TYPE,
        CommonConstants.MIDDLE_DEVICE_TYPE,
        CommonConstants.LARGE_DEVICE_TYPE
        ]
      },
      gutter: { x: $r('app.float.grid_row_gutter') }
    }) {
      GridCol({
        span: {
          sm: CommonConstants.FOUR_COLUMN,
          md: CommonConstants.EIGHT_COLUMN,
          lg: CommonConstants.EIGHT_COLUMN
        },
        offset: {
          sm: CommonConstants.ZERO_COLUMN,
          md: CommonConstants.ZERO_COLUMN,
          lg: CommonConstants.TWO_COLUMN
        }
      }) {
        ...
      }
      .margin({
        left: this.currentBreakpoint === CommonConstants.BREAKPOINT_SM ? $r('app.float.footer_margin_sm') :
          $r('app.float.footer_margin_other'),
        right: this.currentBreakpoint === CommonConstants.BREAKPOINT_SM ? $r('app.float.footer_margin_sm') :
          $r('app.float.footer_margin_other')
      })
    }
    .backgroundColor($r('app.color.bg_color_gray'))
    .height($r('app.float.footer_height'))
    .width(CommonConstants.FULL_COMPONENT)
    .onBreakpointChange((breakpoints) => {
      ...
    })
  }
}

分享按钮弹窗

页脚点击分享按钮,弹出自定义弹窗DeviceListDialog,用于多端协同拉起应用。DeviceListDialog由两个标题栏和两个List组件构成,其中List组件使用ForEach循环渲染设备数据。

 
// DeviceListDialog.ets
build() {
  Column() {
    Row() {
      ...
    }
    .height($r('app.float.choose_device_row_height'))
    .width(CommonConstants.FULL_COMPONENT)
    .padding({
      left: $r('app.float.dialog_padding'),
      right: $r('app.float.dialog_padding')
    })

    // 信任设备列表
    List() {
      ForEach(this.trustedDeviceList, (item: deviceManager.DeviceInfo, index: number) => {
        ListItem() {
          ...
        }
      }, (item: deviceManager.DeviceInfo) => JSON.stringify(item.deviceId))
    }

    Row() {
      ...
    }
    .height($r('app.float.choose_device_row_height'))
    .width(CommonConstants.FULL_COMPONENT)
    .padding({
      left: $r('app.float.dialog_padding'),
      right: $r('app.float.dialog_padding')
    })

    // 发现设备列表
    List() {
      ForEach(this.discoverDeviceList, (item: deviceManager.DeviceInfo, index: number) => {
        ListItem() {
          ...
        }
      }, (item: deviceManager.DeviceInfo) => JSON.stringify(item.deviceId))
    }

    Row() {
      ...
    }
    .height($r('app.float.dialog_button_row_height'))
    .padding({
      top: $r('app.float.dialog_button_padding_top'),
      bottom: $r('app.float.dialog_button_padding_bottom'),
      left: $r('app.float.dialog_padding'),
      right: $r('app.float.dialog_padding')
    })
    .width(CommonConstants.FULL_COMPONENT)
  }
  .borderRadius($r('app.float.dialog_border_radius'))
  .backgroundColor($r('app.color.device_dialog_background'))
  .width(CommonConstants.FULL_COMPONENT)
}

多端协同拉起应用

创建设备管理器

应用创建时创建一个设备管理器实例,注册设备状态监听和获取信任的设备列表。其中deviceManager类需使用full-SDK。

// EntryAbility.ets
onCreate(want: Want) {
  ...
  // 创建设备管理器
  RemoteDeviceModel.createDeviceManager(this.context);
}

// RemoteDeviceModel.ets
async createDeviceManager(context: common.UIAbilityContext): Promise<void> {
  if (this.deviceManager !== undefined) {
    return;
  }
  await new Promise((resolve: (value: Object | PromiseLike<Object>) => void, reject:
    ((reason?: RejectError) => void)) => {
    deviceManager.createDeviceManager(context.abilityInfo.bundleName, (err, value) => {
      if (err) {
        reject(err);
        logger.error('createDeviceManager failed.');
        return;
      }
      this.deviceManager = value;
      // 注册设备状态监听
      this.registerDeviceStateListener();
      // 获取信任设备列表
      this.getTrustedDeviceList();
      resolve(value);
    })
  })
}

发现设备

用户点击新闻详情页底部的分享按钮,调用startDeviceDiscovery()方法,发现周边处在同一无线网络下的设备并添加设备至已发现的设备列表。

// RemoteDeviceModel.ets
startDeviceDiscovery(): void {
  if (this.deviceManager === undefined) {
    logger.error('deviceManager has not initialized');
    this.showToast($r('app.string.no_device_manager'));
    return;
  }
  this.deviceManager.on('deviceFound', (data) => {
    if (data === null) {
      return;
    }
    // 监听设备发现
    this.deviceFound(data);
  })
  this.deviceManager.on('discoverFail', (data) => {
    logger.error(`discoverFail data = ${JSON.stringify(data)}`);
  })
  this.deviceManager.on('serviceDie', () => {
    logger.error('serviceDie');
  })

  let info: deviceManager.SubscribeInfo = {
    subscribeId: SUBSCRIBE_ID,
    mode: CommonConstants.INFO_MODE,
    medium: 0,
    freq: CommonConstants.INFO_FREQ,
    isSameAccount: false,
    isWakeRemote: true,
    capability: 0
  };
  // 添加设备至发现列表
  this.discoverList = [];
  AppStorage.setOrCreate(CommonConstants.DISCOVER_DEVICE_LIST, this.discoverList);

  try {
    this.deviceManager.startDeviceDiscovery(info);
  } catch (err) {
    logger.error(`startDeviceDiscovery failed error = ${JSON.stringify(err)}`);
  }
}

进行可信认证连接

在已发现的设备列表中选择设备,调用authenticateDevice()方法进行可信认证,输入PIN码,连接设备,将设备改为信任状态,添加至已信任设备列表。

// RemoteDeviceModel.ets
authenticateDevice(device: deviceManager.DeviceInfo, context: common.UIAbilityContext): void {
  if (this.deviceManager === undefined) {
    logger.error('deviceManager has not initialized');
    this.showToast($r('app.string.no_device_manager'));
    return;
  }

  for (let i: number = 0; i < this.discoverList.length; i++) {
    if (this.discoverList[i].deviceId !== device.deviceId) {
      continue;
    }
    let extraInfo: AuthExtraInfoInterface = {
      targetPkgName: context.abilityInfo.bundleName,
      appName: context.applicationInfo.name,
      appDescription: context.applicationInfo.description,
      business: CommonConstants.ZERO
    };
    let authParam: deviceManager.AuthParam = {
      'authType': CommonConstants.ONE,
      'extraInfo': extraInfo
    };
    try {
      // 可信认证
      this.deviceManager.authenticateDevice(device, authParam, (err) => {
        if (err) {
          logger.error(`authenticateDevice error. Code is ${err.code}, message is ${err.message}`);
          return;
        }
      })
    } catch (err) {
      logger.error(`authenticateDevice failed error = ${JSON.stringify(err)}`);
    }
  }
}

跨设备启动UIAbility

可信认证后,用户再次点击分享按钮,选择已信任设备列表中的设备,调用startAbilityContinuation()方法进行拉起应用,在另一设备中触发aboutToAppear()方法渲染当前的新闻详情页,实现跨设备启动UIAbility。

// DeviceListDialog.ets
function startAbilityContinuation(deviceId: string, newsId: string, context: common.UIAbilityContext): void {
  let want: Want = {
    deviceId: deviceId,
    bundleName: context.abilityInfo.bundleName,
    abilityName: CommonConstants.ABILITY_NAME,
    parameters: {
      newsId: newsId
    }
  };
  // 拉起应用
  context.startAbility(want).catch((err: Error) => {
    Logger.error(`startAbilityContinuation failed error = ${JSON.stringify(err)}`);
    prompt.showToast({
      message: $r('app.string.start_ability_continuation_error')
    });
  })
}

// NewsDetail.ets
aboutToAppear() {
  let newsId: string | undefined = AppStorage.get<string>('wantNewsId');
  if (newsId === undefined) {
    this.newsData = (router.getParams() as Record<string, NewsData>)['newsItem'];
    return;
  }
  // 读取跨设备传递的参数信息
  this.newsData = this.newsItems.filter((item: NewsData) => (item.newsId === newsId))[0];
}

最后呢,很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

高清完整版请点击→《鸿蒙NEXT星河版开发学习文档》

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细资料鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家在技术的道路上更进一步。

《鸿蒙 (OpenHarmony)开发学习视频》

图片

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

获取这份鸿蒙星河版学习资料,请点击→《鸿蒙NEXT星河版开发学习文档》

OpenHarmony北向、南向开发环境搭建

图片

《鸿蒙开发基础》

  1. ArkTS语言

  2. 安装DevEco Studio

  3. 运用你的第一个ArkTS应用

  4. ArkUI声明式UI开发

  5. .……

图片

《鸿蒙开发进阶》

  1. Stage模型入门

  2. 网络管理

  3. 数据管理

  4. 电话服务

  5. 分布式应用开发

  6. 通知与窗口管理

  7. 多媒体技术

  8. 安全技能

  9. 任务管理

  10. WebGL

  11. 国际化开发

  12. 应用测试

  13. DFX面向未来设计

  14. 鸿蒙系统移植和裁剪定制

  15. ……

图片

《鸿蒙开发实战》

  1. ArkTS实践

  2. UIAbility应用

  3. 网络案例

  4. ……

图片

 获取这份鸿蒙星河版学习资料,请点击→《鸿蒙NEXT星河版开发学习文档》

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1603281.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Go 之 sync.Mutex 加锁失效现象

我先声明一下&#xff0c;并不是真的加锁失效&#xff0c;而是我之前的理解有误&#xff0c;导致看起来像是加锁失效一样。于是乎记录一下&#xff0c;加深一下印象。 我之前有个理解误区&#xff08;不知道大家有没有&#xff0c;有的话赶紧纠正一下——其实也是因为我这块的…

项目7-音乐播放器5+注册账号

1.前端代码 MAPPER Insert("insert into user(username,password) values (#{username},#{password}) ")Integer insertUserInfo(String username,String password); Service public Result insertUserInfo(String username, String oldpassword,String newpasswo…

算法学习——LeetCode力扣补充篇11(64. 最小路径和、48. 旋转图像 、169. 多数元素、394. 字符串解码、240. 搜索二维矩阵 II )

算法学习——LeetCode力扣补充篇11 64. 最小路径和 64. 最小路径和 - 力扣&#xff08;LeetCode&#xff09; 描述 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只…

测绘管理与法律法规 | 测绘资质管理办法 | 学习笔记

目录 一、测绘资质概述 二、测绘资质分类与等级 三、审批与管理 四、申请条件 五、审批程序 六、测绘资质证书 七、监督管理 八、违规处理 九、特殊规定 十、审批受理时间要点补充 1. 审批机关决定是否受理的时间 2. 审批机关作出批准与否的决定时间 3. 颁发测绘资…

在报表控件 FastReport .NET 中使用 PageCreate 事件

FastReport Business Graphics .NET&#xff0c;是一款基于fastreport报表开发控件的商业图形库&#xff0c;借助 FastReport 商业图形库&#xff0c;您可以可视化不同的分层数据&#xff0c;构建业务图表以进行进一步分析和决策。利用数据呈现领域专家针对 .NET 7、.NET Core、…

论文阅读-Federated-Unlearning-With-Momentum-Degradation

论文阅读-Federated Unlearning With Momentum Degradation 联邦忘却与动量退化 Yian Zhao IEEE Internet of Things Journal 2023 年 10 月 2 日 CCF-C momentum degradation-MoDe 动量退化 memory guidance-记忆引导 knowledge erasure-知识擦除 Deep-learning neural n…

【记录】Python|Selenium 下载 PDF 不预览不弹窗(2024年)

版本&#xff1a; Chrome 124Python 12Selenium 4.19.0 版本与我有差异不要紧&#xff0c;只要别差异太大比如 Chrome 用 57 之前的版本了&#xff0c;就可以看本文。 如果你从前完全没使用过、没安装过Selenium&#xff0c;可以参考这篇博客《【记录】Python3&#xff5c;Sele…

搭建Zookeeper完全分布式集群(CentOS 9 )

ZooKeeper是一个开源的分布式协调服务&#xff0c;它为分布式应用提供了高效且可靠的分布式协调服务&#xff0c;并且是分布式应用保证数据一致性的解决方案。该项目由雅虎公司创建&#xff0c;是Google Chubby的开源实现。 分布式应用可以基于ZooKeeper实现诸如数据发布/订阅…

UE5 C++ 射线检测

一.声明四个变量 FVector StartLocation;FVector ForwardVector;FVector EndLocation;FHitResult HitResult;二.起点从摄像机&#xff0c;重点为摄像机前9999m。射线检测 使用LineTraceSingleByChannel 射线直线通道检测&#xff0c;所以 void AMyCharacter::Tick(float Delt…

c++ qt6.5 打包sqlite组件无法使用,尽然 也需要dll支持!这和开发php 有什么区别!

运行 程序会默认使用当前所在文件夹中的 dll 文件&#xff0c;若文件不存在&#xff0c;会使用系统环境变量路径中的文件&#xff1b;又或者是需要在程序源代码中明确指定使用的 dll 的路径。由于我安装 Qt 时将相关 dll 文件路径都添加到了系统环境变量中&#xff0c;所以即使…

Hbase的shell命令(详细)

一、help 1.help 显示命名的分组情况 2.help 命令名称 查看命令的具体使用&#xff0c;包括命令的作用和用法。 举例&#xff1a;help list 二、general 组&#xff08;普通命令组&#xff09; 命令 描述 …

设计循环队列(队列oj)

1.设计循环队列 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。…

高版本Android studio 使用Markdown无法预览(已解决)

目录 概述 解决方法 概述 本人升级Android studio 当前版本为Android Studio Jellyfish | 2023.3.1 RC 2导致Markdown无法预览。 我尝试了很多网上的方法都无法Markdown解决预览问题&#xff0c;包括升级插件、安装各种和Markdown相关的插件及使用“Choose Boot Java Runtim…

CentOS系统上部署Docker,mysql,nginx

CentOS7系统上部署Docker&#xff0c;mysql&#xff0c;nginx 未完&#xff0c;持续更新中 更新软件包索引&#xff1a; 首先&#xff0c;确保你的CentOS系统是最新的。你可以通过运行以下命令来更新你的系统&#xff1a; yum update安装Docker&#xff1a; CentOS的软件仓…

十大开源机器人 智能体

1- Poppy 网址 https://www.poppy-project.org/en/ 2- Nao 网址:https://www.aldebaran.com/en/nao 3- iCub 网址: https://icub.iit.it/

蓝桥杯2024年第十五届省赛真题-R 格式

找到规律后如下&#xff0c;只需要用高精度加法和四舍五入&#xff08;本质也是高精度加法就能做&#xff09;&#xff0c;如果没有找到规律&#xff0c;就得自己写高精度乘法和加法&#xff0c;不熟练很容易错。 //#include<bits/stdc.h> #include<iostream> #i…

【UE5.1】使用MySQL and MariaDB Integration插件——(3)表格形式显示数据

在上一篇&#xff08;【UE5.1】使用MySQL and MariaDB Integration插件——&#xff08;2&#xff09;查询&#xff09;基础上继续实现以表格形式显示查询到的数据的功能 效果 步骤 1. 在“WBP_Query”中将多行文本框替换未网格面板控件&#xff0c;该控件可以用表格形式布局…

论文笔记:Are Human-generated Demonstrations Necessary for In-context Learning?

iclr 2024 reviewer 评分 6668 1 intro 大型语言模型&#xff08;LLMs&#xff09;已显示出在上下文中学习的能力 给定几个带注释的示例作为演示&#xff0c;LLMs 能够为新的测试输入生成输出然而&#xff0c;现行的上下文学习&#xff08;ICL&#xff09;范式仍存在以下明显…

1 回归:锂电池温度预测top2 代码部分(一) Tabnet

2024 iFLYTEK A.I.开发者大赛-讯飞开放平台 TabNet&#xff1a; 模型也是我在这个比赛一个意外收获&#xff0c;这个模型在比赛之中可用。但是需要GPU资源&#xff0c;否则运行真的是太慢了。后面针对这个模型我会写出如何使用的方法策略。 比赛结束后有与其他两位选手聊天&am…

YOLOv9改进策略 | 损失函数篇 | EIoU、SIoU、WIoU、DIoU、FocusIoU等二十余种损失函数

一、本文介绍 这篇文章介绍了YOLOv9的重大改进&#xff0c;特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体&#xff0c;如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU&#xff0c;还融合了“Focus”思想&#xff0c;创造了一系列新的损失函数。这些组合形式的…