开源 Arkts 鸿蒙应用 开发(十七)通讯--http多文件下载

 文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发,公司安排开发app,临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

 相关链接:

开源 Arkts 鸿蒙应用 开发(一)工程文件分析-CSDN博客

开源 Arkts 鸿蒙应用 开发(二)封装库.har制作和应用-CSDN博客

开源 Arkts 鸿蒙应用 开发(三)Arkts的介绍-CSDN博客

开源 Arkts 鸿蒙应用 开发(四)布局和常用控件-CSDN博客

开源 Arkts 鸿蒙应用 开发(五)控件组成和复杂控件-CSDN博客

开源 Arkts 鸿蒙应用 开发(六)数据持久--文件和首选项存储-CSDN博客

开源 Arkts 鸿蒙应用 开发(七)数据持久--sqlite关系数据库-CSDN博客

开源 Arkts 鸿蒙应用 开发(八)多媒体--相册和相机-CSDN博客

开源 Arkts 鸿蒙应用 开发(九)通讯--tcp客户端-CSDN博客

开源 Arkts 鸿蒙应用 开发(十)通讯--Http-CSDN博客

开源 Arkts 鸿蒙应用 开发(十一)证书和包名修改-CSDN博客

开源 Arkts 鸿蒙应用 开发(十二)传感器的使用-CSDN博客

开源 Arkts 鸿蒙应用 开发(十三)音频--MP3播放_arkts avplayer播放音频 mp3-CSDN博客

开源 Arkts 鸿蒙应用 开发(十四)线程--任务池(taskpool)-CSDN博客

开源 Arkts 鸿蒙应用 开发(十五)自定义绘图控件--仪表盘-CSDN博客

开源 Arkts 鸿蒙应用 开发(十六)自定义绘图控件--波形图-CSDN博客

开源 Arkts 鸿蒙应用 开发(十七)通讯--http多文件下载-CSDN博客

开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器-CSDN博客

 推荐链接:

开源 java android app 开发(一)开发环境的搭建-CSDN博客

开源 java android app 开发(二)工程文件结构-CSDN博客

开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客

开源 java android app 开发(四)GUI界面重要组件-CSDN博客

开源 java android app 开发(五)文件和数据库存储-CSDN博客

开源 java android app 开发(六)多媒体使用-CSDN博客

开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客

开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客

开源 java android app 开发(九)后台之线程和服务-CSDN博客

开源 java android app 开发(十)广播机制-CSDN博客

开源 java android app 开发(十一)调试、发布-CSDN博客

开源 java android app 开发(十二)封库.aar-CSDN博客

推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客

本章内容主要演示了一个多文件下载的HarmonyOS应用界面,主要包含三个部分:MultipleFilesDownload主组件、FileDownloadItem下载项组件和ProgressButton进度按钮组件。

1.工程结构

2.源码解析

3.演示效果

4.工程下载网址

一、工程结构,主要包括3个文件,Index.ets,FileDownloadItem.ets,ProgressButton.ets。

二、源码解析

2.1  Index.ets文件:管理多个文件的下载任务,提供"全部开始/暂停"功能,显示下载列表。

简单说明:

使用@Entry和@Component装饰器声明为入口组件,

维护一个下载URL数组downloadUrlArray

使用ForEach渲染多个FileDownloadItem组件

提供全局的开始/暂停所有下载的功能

跟踪下载计数和失败计数

以下为代码:

import { request } from '@kit.BasicServicesKit';
import { FileDownloadItem } from '../view/FileDownloadItem';const NO_TASK: number = 0;function downloadConfig(downloadUrl: string): request.agent.Config {const config: request.agent.Config = {action: request.agent.Action.DOWNLOAD,url: downloadUrl,overwrite: true,method: 'GET',saveas: './',mode: request.agent.Mode.BACKGROUND,gauge: true,retry: false};return config;
}@Entry
@Component
struct MultipleFilesDownload {/*** enter the download urls*/private downloadUrlArray: string[] = ["https://m.down.sandai.net/mobile/OfficialSite_MobileThunder1.apk"];@State downloadConfigArray: request.agent.Config[] = [];@State isStartAllDownload: boolean = false;@State downloadCount: number = 0;@State downloadFailCount: number = 0;aboutToAppear(): void {for (let i = 0; i < this.downloadUrlArray.length; i++) {const config: request.agent.Config = downloadConfig(this.downloadUrlArray[i]);this.downloadConfigArray.push(config);}this.downloadCount = this.downloadUrlArray.length;}build() {Column() {Row() {Text($r('app.string.multiple_files_download_transfer_list')).fontWeight(FontWeight.Bold).fontSize($r('app.integer.title_font_size')).width('100%').fontColor($r('app.color.text_color'))}.alignItems(VerticalAlign.Bottom).width('91.1%').height(112)Row() {Row() {Text($r('app.string.multiple_files_download_queue')).fontSize($r('app.integer.multiple_files_download_text_font_size_fourteen')).fontColor($r('sys.color.ohos_id_color_text_secondary'))}.width($r('app.string.multiple_files_download_row_width'))Row() {Text(this.isStartAllDownload && this.downloadCount > NO_TASK ? $r('app.string.pause_all') :$r('app.string.start_all')).fontSize($r('app.integer.multiple_files_download_text_font_size_fourteen')).fontWeight(500).fontColor($r('sys.color.ohos_id_color_text_primary_activated')).textAlign(TextAlign.End).width($r('app.string.multiple_files_download_row_text_width')).onClick(() => {if (this.downloadCount === NO_TASK) {this.getUIContext().showAlertDialog({message: $r('app.string.multiple_files_download_completed'),alignment: DialogAlignment.Center});return;}this.isStartAllDownload = !this.isStartAllDownload;})}.width($r('app.string.multiple_files_download_row_width'))}.margin({left: 16,right: 16,top: $r('app.integer.multiple_files_download_margin_top_twenty_eight'),bottom: $r('app.integer.margin_eight')})List() {ForEach(this.downloadConfigArray, (item: request.agent.Config) => {ListItem() {FileDownloadItem({downloadConfig: item,isStartAllDownload: this.isStartAllDownload,downloadCount: this.downloadCount,downloadFailCount: this.downloadFailCount})}}, (item: request.agent.Config) => JSON.stringify(item))}.width('100%').height('100%')}.focusable(false)}
}@Builder
export function getMultipleFilesDownload(): void {MultipleFilesDownload();
}

2.2  FileDownloadItem.ets组件:显示文件名、下载进度和状态,提供暂停/继续下载功能,处理下载过程中的各种回调。

简单说明:

completedCallback: 下载完成

failedCallback: 下载失败

pauseCallback: 暂停下载

resumeCallback: 继续下载

progressCallback: 下载进度更新

responseCallback: HTTP响应

使用ProgressButton组件显示下载进度和控制按钮

处理文件大小和下载进度的显示转换

import { common } from '@kit.AbilityKit';
import { request } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';import { ProgressButton } from './ProgressButton';const uiContext: UIContext | undefined = AppStorage.get('uiContext');const TAG = 'FileDownloadItem';
const BYTE_CONVERSION: number = 1024;
const context = uiContext!.getHostContext()! as common.UIAbilityContext;function getFileNameFromUrl(url: string): string {const segments = url.split('/');let tmp = segments.pop() || '';if (tmp.indexOf('?') != -1) {return tmp.split('?')[0];}return tmp;
}@Component
export struct FileDownloadItem {@State downloadConfig: request.agent.Config = { action: request.agent.Action.DOWNLOAD, url: '' };@State fileName: string = '';@State textState: string | Resource = "";@Link @Watch('onDownLoadUpdated') isStartAllDownload: boolean;private downloadTask: request.agent.Task | undefined = undefined;@Link downloadCount: number;@Link downloadFailCount: number;@State isShow: boolean = false;@State downloading: boolean = false;@State sFileSize: string | number = "-";@State nFileSize: number = 0;@State sCurrentDownloadSize: string = "-";@State @Watch('updateProgress') nCurrentDownloadSize: number = 0;@State progress: number = 0;@State isPaused: boolean = false;private completedCallback = (progress: request.agent.Progress) => {this.textState = $r("app.string.download_completed");if (this.sFileSize === -1) {this.sFileSize = this.sCurrentDownloadSizethis.nCurrentDownloadSize = 1;}this.downloadCount--;}private failedCallback = (progress: request.agent.Progress) => {this.textState = $r("app.string.download_fail");this.downloadFailCount++;if (this.downloadFailCount === this.downloadCount) {this.isStartAllDownload = false;}if (this.downloadTask) {request.agent.show(this.downloadTask.tid, (err: Error, taskInfo: request.agent.TaskInfo) => {if (err) {hilog.error(0x0000, TAG, 'agent show error:', err);return;}});}}private pauseCallback = (progress: request.agent.Progress) => {this.isPaused = true;this.downloading = false;this.textState = $r("app.string.paused");}private resumeCallback = (progress: request.agent.Progress) => {this.isPaused = false;this.textState = $r("app.string.downloading");this.downloading = true;}private progressCallback = (progress: request.agent.Progress) => {this.textState = $r("app.string.downloading");this.downloading = true;this.isShow = true;if (this.downloadTask) {if (this.sFileSize === '-') {if (progress.sizes[0] === -1) {this.sFileSize = -1;this.nCurrentDownloadSize = 0;this.nFileSize = 1;} else {this.nFileSize = progress.sizes[0];this.sFileSize = (progress.sizes[0] / BYTE_CONVERSION).toFixed() + 'kb';this.nCurrentDownloadSize = progress.processed;}} else if (this.sFileSize === -1) {hilog.info(0x0000, TAG, 'file size unknown');} else {this.nCurrentDownloadSize = progress.processed;}this.sCurrentDownloadSize = (progress.processed / BYTE_CONVERSION).toFixed() + 'kb';}}private responseCallback = (response: request.agent.HttpResponse) => {hilog.info(0x0000, TAG, 'response:' + response.statusCode);};updateProgress() {setTimeout(() => {if (this.textState == $r("app.string.paused")) {this.isPaused = true;return;}let tmp = this.nCurrentDownloadSize / this.nFileSize * 100;if (tmp <= this.progress) {return;}this.progress = tmp;}, 10)}aboutToAppear(): void {this.fileName = getFileNameFromUrl(this.downloadConfig.url);}onDownLoadUpdated(): void {if (this.isStartAllDownload) {if (this.textState === $r("app.string.download_fail")) {this.downloadTask = undefined;this.isShow = false;this.textState = "";}this.startDownload();} else {if (this.downloadFailCount > 0 && this.downloadFailCount === this.downloadCount) {this.downloadFailCount = 0;} else {this.pauseDownload();}}}startDownload(): void {if (this.downloadTask === undefined) {request.agent.create(context, this.downloadConfig).then((task: request.agent.Task) => {task.on('completed', this.completedCallback);task.on('failed', this.failedCallback);task.on('pause', this.pauseCallback);task.on('resume', this.resumeCallback);task.on('progress', this.progressCallback);task.on('response', this.responseCallback);task.start().then(() => {this.downloadTask = task;}).catch((err: Error) => {hilog.error(0x0000, TAG, 'task start error:', err);})}).catch((err: Error) => {hilog.error(0x0000, TAG, 'create error:', err);});} else {this.resumeDownload();}}pauseOrResumeDownload(): void {if (this.downloadTask) {request.agent.show(this.downloadTask.tid, (err: Error, taskInfo: request.agent.TaskInfo) => {if (err) {hilog.error(0x0000, TAG, 'agent show error:', err);return;}if (taskInfo.progress.state === request.agent.State.PAUSED) {this.resumeDownload();} else {this.pauseDownload();}});}}pauseDownload(): void {if (this.downloadTask) {request.agent.show(this.downloadTask.tid, (err: Error, taskInfo: request.agent.TaskInfo) => {if (err) {hilog.error(0x0000, TAG, 'agent show error:', err);return;}if (this.downloadTask && (taskInfo.progress.state === request.agent.State.WAITING || taskInfo.progress.state=== request.agent.State.RUNNING || taskInfo.progress.state === request.agent.State.RETRYING)) {this.downloadTask.pause().then(() => {}).catch((err: Error) => {hilog.error(0x0000, TAG, 'task pause error:', err);});}});}}resumeDownload(): void {if (this.downloadTask) {request.agent.show(this.downloadTask.tid, (err: Error, taskInfo: request.agent.TaskInfo) => {if (err) {hilog.error(0x0000, TAG, 'agent show error:', err);return;}if (this.downloadTask && taskInfo.progress.state === request.agent.State.PAUSED) {this.downloadTask.resume().then(() => {}).catch((err: Error) => {hilog.error(0x0000, TAG, 'task resume error:', err);});}});}}build() {RelativeContainer() {Image($r('app.media.multiple_files_download_file')).height($r("app.integer.multiple_files_download_image_size")).width($r("app.integer.multiple_files_download_image_size")).id('fileImage').alignRules({center: { anchor: '__container__', align: VerticalAlign.Center }})Text(this.fileName).fontSize($r("app.integer.multiple_files_download_text_font_size")).padding({ left: $r("app.integer.multiple_files_download_padding") }).alignRules({left: { anchor: 'fileImage', align: HorizontalAlign.End },top: { anchor: 'fileImage', align: VerticalAlign.Top },}).fontWeight(FontWeight.Medium).margin({ top: $r('app.integer.item_name_top_margin') }).id('fileName')ProgressButton({paused: this.isPaused,progress: this.progress,progressButtonWidth: $r('app.integer.progress_btn_width'),content: this.textState,enable: true,clickCallback: () => {this.pauseOrResumeDownload();}}).visibility(this.isShow ? Visibility.Visible : Visibility.Hidden).alignRules({right: { anchor: '__container__', align: HorizontalAlign.End },center: { anchor: '__container__', align: VerticalAlign.Center }})Text(this.sCurrentDownloadSize + "/" + this.sFileSize).fontSize($r('app.integer.multiple_files_download_text_font_size_fourteen')).width($r('app.string.multiple_files_download_text_width')).fontColor($r('app.color.multiple_files_download_text_font_color')).margin({ top: $r("app.integer.multiple_files_download_margin_top") }).padding({ left: $r("app.integer.multiple_files_download_padding") }).alignRules({top: { anchor: 'fileName', align: VerticalAlign.Bottom },left: { anchor: 'fileImage', align: HorizontalAlign.End }}).id('downloadVal')}.height($r('app.integer.item_height')).margin({ left: 16, right: 16 }).padding({ left: 12, right: 12 })}
}

2.3  ProgressButton.ets,这个自定义的组建实现了:显示下载进度百分比,根据状态显示不同文本(下载中/暂停/完成),提供点击回调功能。

简单说明:

使用HarmonyOS的Progress组件显示进度条

根据进度值自动更新显示文本

支持启用/禁用状态

提供圆角胶囊样式

const EMPTY_STRING: string = '';
const MAX_PROGRESS: number = 100;
const MAX_PERCENTAGE: string = '100%';
const MIN_PERCENTAGE: string = '0%';
const TEXT_OPACITY: number = 0.4;
const BUTTON_NORMAL_WIDTH: number = 44;
const BUTTON_NORMAL_HEIGHT: number = 28;
const BUTTON_BORDER_RADIUS: number = 14;
const TEXT_ENABLE: number = 1.0;
const MIN_WIDTH: Length = 44;
const PADDING_TEXT: Length = 8;const PROGRESS_BUTTON_PROGRESS_KEY = 'progress_button_progress_key';
const PROGRESS_BUTTON_PRIMARY_FONT_KEY = 'progress_button_primary_font_key';
const PROGRESS_BUTTON_CONTAINER_BACKGROUND_COLOR_KEY = 'progress_button_container_background_color_key';
const PROGRESS_BUTTON_EMPHASIZE_SECONDARY_BUTTON_KEY = 'progress_button_emphasize_secondary_button_key';@Component
export struct ProgressButton {@Prop @Watch('updateText') paused: boolean = false;@Prop @Watch('getProgressContext') progress: number;@State textProgress: string = EMPTY_STRING;@Prop content: string | Resource = EMPTY_STRING;@State isLoading: boolean = false;progressButtonWidth?: Length = BUTTON_NORMAL_WIDTH;clickCallback: () => void = () => {};@Prop enable: boolean = true;@State progressColor: ResourceColor = '#330A59F7';@State containerBorderColor: ResourceColor = '#330A59F7';@State containerBackgroundColor: ResourceColor = $r('sys.color.ohos_id_color_foreground_contrary');private getButtonProgress(): number {if (this.progress < 0) {return 0;} else if (this.progress > MAX_PROGRESS) {return MAX_PROGRESS;}return this.progress;}updateText() {if (this.paused) {setTimeout(() => {this.isLoading = !this.paused;}, 10);} else {this.isLoading = !this.paused;}}private getProgressContext() {if (this.progress < 0) {this.isLoading = false;this.textProgress = MIN_PERCENTAGE;} else if (this.progress >= MAX_PROGRESS) {this.isLoading = false;this.textProgress = MAX_PERCENTAGE;} else {this.isLoading = true;this.textProgress = Math.floor(this.progress / MAX_PROGRESS * MAX_PROGRESS).toString() + "%";}}build() {Button() {Stack() {Progress({value: this.getButtonProgress(), total: MAX_PROGRESS,style: ProgressStyle.Capsule}).height(BUTTON_NORMAL_HEIGHT).borderRadius(BUTTON_BORDER_RADIUS).width('100%').hoverEffect(HoverEffect.None).clip(false).enabled(this.enable).key(PROGRESS_BUTTON_PROGRESS_KEY).color(this.progressColor)Text(this.isLoading ? this.textProgress : this.content).fontSize($r('sys.float.ohos_id_text_size_button3')).fontWeight(FontWeight.Medium).key(PROGRESS_BUTTON_PRIMARY_FONT_KEY).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis }).padding({ left: PADDING_TEXT, right: PADDING_TEXT }).opacity(this.enable ? TEXT_ENABLE : TEXT_OPACITY)Row().key(PROGRESS_BUTTON_CONTAINER_BACKGROUND_COLOR_KEY).backgroundColor(Color.Transparent).border({ width: 1, color: this.containerBorderColor }).height(BUTTON_NORMAL_HEIGHT).borderRadius(BUTTON_BORDER_RADIUS).width('100%')}}.borderRadius(BUTTON_BORDER_RADIUS).clip(false).hoverEffect(HoverEffect.None).key(PROGRESS_BUTTON_EMPHASIZE_SECONDARY_BUTTON_KEY).backgroundColor(this.containerBackgroundColor).constraintSize({ minWidth: MIN_WIDTH }).width((!this.progressButtonWidth || this.progressButtonWidth < BUTTON_NORMAL_WIDTH) ?BUTTON_NORMAL_WIDTH : this.progressButtonWidth).stateEffect(this.enable).onClick(() => {if (!this.enable) {return;}if (this.progress < MAX_PROGRESS) {this.isLoading = !this.isLoading;}this.clickCallback && this.clickCallback();})}
}

2.4  module.json5权限需要添加ohos.permission.INTERNET

{"module": {"name": "entry","type": "entry","description": "$string:module_desc","mainElement": "EntryAbility","deviceTypes": ["phone"],"requestPermissions": [{"name": "ohos.permission.INTERNET","reason": "$string:reason_internet","usedScene": {"abilities": ["EntryAbility"],"when": "always"}},],"deliveryWithInstall": true,"installationFree": false,"pages": "$profile:main_pages","abilities": [{"name": "EntryAbility","srcEntry": "./ets/entryability/EntryAbility.ets","description": "$string:EntryAbility_desc","icon": "$media:layered_image","label": "$string:EntryAbility_label","startWindowIcon": "$media:startIcon","startWindowBackground": "$color:start_window_background","exported": true,"skills": [{"entities": ["entity.system.home"],"actions": ["action.system.home"]}]}]}
}

三、演示效果,下载地址数组里只用写了1个,所以只有1个文件,需要的可以自行添加。

四、工程下载网址:https://download.csdn.net/download/ajassi2000/91685765?spm=1011.2124.3001.6210

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

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

相关文章

Cloudflare Tunnel 使用SAAS回源加速配置教程

在使用 Cloudflare Tunnel 时,通过“主域名+加速域名”的联动配置,既能隐藏内网 IP,又能优化访问速度。本文以实际部署场景为例(主域名 zhuyuming.dpdns.org、加速域名 jiasu.dpdns.org),带你一步步完成内网服务穿透(以 192.168.1.6:5555 网页服务为例),实操性强,可直…

C++实战

Ref deepwiki vuecruddllamma.cpp 目标 计划实现一个C项目&#xff0c;前端用vue&#xff0c;后端用C和llama.cpp。实现可以进行逻辑功能和AI推理。

dify 调用本地的 stable diffusion api生成图片的工作流搭建

Dify调用本地Stable Diffusion API的工作流搭建指南 核心架构 #mermaid-svg-ce029i4XFKrDzRgU {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ce029i4XFKrDzRgU .error-icon{fill:#552222;}#mermaid-svg-ce029i4XFK…

【Web后端】Django、flask及其场景——以构建系统原型为例

一、Django 和 Flask 简介 Django 是一个高级 Python Web 框架&#xff0c;提供了完整的“开箱即用”功能&#xff0c;包括 ORM、认证、管理后台等&#xff0c;便于快速开发安全且可维护的网站。Flask 是一个轻量级 Python Web 框架&#xff0c;核心功能比较简单&#xff0c;但…

飞算JavaAI:从智能调度到出行服务的全链路技术升级

免责声明&#xff1a;此文章所有内容都是实验测试数据 目录一、智慧交通核心场景的技术突破1.1 交通态势感知与智能预警系统1.2 公共交通智能调度系统1.3 一体化出行服务系统二、智慧交通系统效能升级实践2.1 交通数据中台构建结语&#xff1a;重新定义智慧交通技术边界一、智慧…

vscode的wsl环境,ESP32驱动0.96寸oled屏幕

注意大小写&#xff0c;wsl&#xff08;也就是linux环境&#xff09;严格区分大小写。有帮助记得订阅专栏点赞&#xff0c;当前不定期持续更新。 一、文件夹格式&#xff1a; project/ # 项目根目录 ├─ main/ # 主程序文件夹 │ ├─ mai…

CodeBuddy AI Coding 企业场景落地实践与思考

&#x1f449;目录1 引言2 诊断团队研发流程3 选择合适的 AI CODING 工具4 团队 AI 研发流程落地实践5 全面 CodeBuddy &#xff0c;深入 CodeBuddy6 诚邀共建在 AI 浪潮席卷全球的今天&#xff0c;AI CODING 已经不是企业研发团队的可选项&#xff0c;而是必选项。如果你是企业…

windows下hashcat使用gpu破解execl打开密码

需要的软件 1.hashcat &#xff1a;https://hashcat.net 2.john the ripper &#xff1a;https://www.openwall.com 获取execl加密文件的Hash PS G:\dl\john-1.9.0-jumbo-1-win64\john-1.9.0-jumbo-1-win64\run> python .\office2john.py .\test6.xlsx test6.xlsx:$office$*…

SpringCloud -- Nacos详细介绍

5. Nacos 5.1 Nacos介绍 Nacos 可以理解为微服务的“电话簿 遥控器”。它是阿里巴巴开源的一个核心工具&#xff0c;主要解决微服务架构中的两大问题&#xff1a; 5.1.1 服务注册与发现&#xff08;电话簿&#xff09; 服务注册&#xff1a;当某个微服务&#xff08;比如“订单…

【狂热算法篇】探寻图论幽径之SPFA算法:图论迷宫里的闪电寻径者(通俗易懂版)

​​​​​本篇带大家探究的是SPFA算法&#xff1b;从基本理解&#xff0c;画图分析展示&#xff0c;再到最后的代码实现&#xff0c;以及为何要这样实现代码&#xff0c;等一些细节问题做解释&#xff0c;相关题型应用&#xff0c;非常值得哟&#xff0c;尤其是刚入门的小白学…

webrtc网页一对一通话

基于flutter-webrtc-server做的更改&#xff0c;只使用网页实现语音和视频一对一通话&#xff0c;不支持多对多。 项目地址: https://github.com/chging/rtc-server

Java调用bat执行python脚本

1、问题概述&#xff1f;在windows环境中可以通过Java调用bat执行文件&#xff0c;从而调用python脚本&#xff0c;使用起来方便。2、实现方式&#xff1f;2.1、核心代码bat文件可以在任意位置//获取文件在项目中的文职 String batFilePathSystem.getProperty("user.dir&q…

JavaWeb 欢迎页设置详解

JavaWeb 欢迎页设置详解 欢迎页&#xff08;Welcome Page&#xff09;是用户访问 Web 应用根目录时自动展示的默认页面。在 JavaWeb 中有多种配置方式&#xff1a;一、配置方式 1. 通过 web.xml 配置&#xff08;传统方式&#xff09; <web-app><!-- 配置欢迎页列表 -…

反射和类加载机制

一 类加载机制 1.1 加载机制简介 Java程序从编写到运行这个过程大致可以分为两个阶段&#xff1a;编译阶段和运行阶段。 编译阶段指的是&#xff0c;java源代码文件**(*.java)被java编译器&#xff08;javac&#xff09;编译成字节码文件(*.class)**的过程。这个过程不需要直接…

在CentOS 7 上安装 MySQL 数据库

文章目录前言一、使用官方 MySQL 仓库安装 MySQL1.1 下载并安装 MySQL 官方 YUM 仓库1.2 安装 MySQL YUM 仓库1.3 安装 MySQL1.3.1 补充&#xff1a;1.4 启动 MySQL 服务1.5 设置 MySQL 服务开机启动1.6 获取临时 root 密码1.7 配置 MySQL1.7.1 注意事项1.8 完成安装二、使用默…

Linux:套接字

从进程的视角来看&#xff0c;网络通信就是一个主机上的进程和另外一个主机上的进程进行信息传递&#xff0c;因此对于操作系统而言&#xff0c;网络通信就是一种进程间通信的方式。不过这种进程间通信有特殊之处&#xff1a;同一台主机下可以通过进程ID来标识一个唯一的进程&a…

Android init.rc详解3

关于Android Init的详解&#xff0c;关于Action&#xff0c;Service&#xff0c;Trigger的请参考Android init.rc详解1&#xff0c;关于Options的请参考Android init.rc详解2&#xff0c;本章将介绍常见的Commands。 1 Commands bootchart [start|stop] 启动或停止bootcharti…

Sentinel原理之规则管理

文章目录1. 基础知识2. 数据源使用2.1 RedisDatasource2.2 ZookeeperDatasource1. 基础知识 流量控制规则&#xff08;FlowRule&#xff09;&#xff1a; 阈值类型grade&#xff1a; 0&#xff08;并发线程数&#xff09;&#xff1a;限制同时处理请求的线程1&#xff08;QPS…

系统时钟配置

STM32F103C8T6的系统时钟配置成72MHZ1. 什么是 STM32 系统时钟系统时钟&#xff08;System Clock&#xff09;是整个 MCU&#xff08;微控制器&#xff09;运行的“节拍信号”&#xff0c;所有 CPU 指令执行、外设操作、定时器计时、总线数据传输等&#xff0c;都依赖这个时钟频…

Al大模型-本地私有化部署大模型-大模型微调

魔塔社区 魔塔社区平台介绍 https://www.modelscope.cn/models/Qwen/Qwen2.5-0.5B-Instruct 申请免费的试用机器 如果自己没有机器 &#xff0c;从这里申请机器 。 下载大模型 pip install modelscope 下载到当前目录 mkdir -p /root/autodl-tmp/demo/Qwen/Qwen2.5-0.5B-Ins…