28、鴻蒙Harmony Next開發:不依賴UI組件的全局氣泡提示 (openPopup)和不依賴UI組件的全局菜單 (openMenu)、Toast

目錄

不依賴UI組件的全局氣泡提示 (openPopup)

彈出氣泡

創建ComponentContent

綁定組件信息

設置彈出氣泡樣式

更新氣泡樣式

關閉氣泡

在HAR包中使用全局氣泡提示

不依賴UI組件的全局菜單 (openMenu)

彈出菜單

創建ComponentContent

綁定組件信息

設置彈出菜單樣式

更新菜單樣式

關閉菜單

在HAR包中使用全局菜單

Toast

使用建議

即時反饋模式對比

創建即時反饋

顯示關閉即時反饋


不依賴UI組件的全局氣泡提示 (openPopup)

氣泡提示(Popup)在使用時依賴綁定UI組件,否則無法使用。從API version 18開始,可以通過使用全局接口openPopup的方式,在無UI組件的場景下直接或封裝使用,例如在事件回調中使用或封裝后對外提供能力。

彈出氣泡

通過openPopup可以彈出氣泡。

promptAction.openPopup(contentNode, { id: targetId }, {enableArrow: true
}).then(() => {console.info('openPopup success');}).catch((err: BusinessError) => {console.error('openPopup error: ' + err.code + ' ' + err.message);})

創建ComponentContent

通過調用openPopup接口彈出其氣泡,需要提供用于定義自定義彈出框的內容ComponentContent。其中,wrapBuilder(buildText)封裝自定義組件,new Params(this.message)是自定義組件的入參,可以缺省,也可以傳入基礎數據類型。

private contentNode: ComponentContent<Object> = new ComponentContent(uiContext, wrapBuilder(buildText), this.message);

如果在wrapBuilder中包含其他組件(例如:Popup、Chip組件),則ComponentContent應采用帶有四個參數的構造函數constructor,其中options參數應傳遞{ nestingBuilderSupported: true }。

@Builder
export function buildText(params: Params) {Popup({// 類型設置圖標內容icon: {image: $r('app.media.app_icon'),width: 32,height: 32,fillColor: Color.White,borderRadius: 10} as PopupIconOptions,// 設置文字內容title: {text: `This is a Popup title 1`,fontSize: 20,fontColor: Color.Black,fontWeight: FontWeight.Normal} as PopupTextOptions,// 設置文字內容message: {text: `This is a Popup message 1`,fontSize: 15,fontColor: Color.Black} as PopupTextOptions,// 設置按鈕內容buttons: [{text: 'confirm',action: () => {console.info('confirm button click');},fontSize: 15,fontColor: Color.Black,},{text: 'cancel',action: () => {console.info('cancel button click');},fontSize: 15,fontColor: Color.Black},] as [PopupButtonOptions?, PopupButtonOptions?]})
}let contentNode: ComponentContent<Object> = new ComponentContent(uiContext, wrapBuilder(buildText), this.message, { nestingBuilderSupported: true });

綁定組件信息

通過調用openPopup接口彈出氣泡,需要提供綁定組件的信息TargetInfo。若未傳入有效的target,則無法彈出氣泡。

let frameNode: FrameNode | null = this.ctx.getFrameNodeByUniqueId(this.getUniqueId());
let targetId = frameNode?.getChild(0)?.getUniqueId();

設置彈出氣泡樣式

通過調用openPopup接口彈出氣泡,可以設置PopupCommonOptions屬性調整氣泡樣式。

private options: PopupCommonOptions = { enableArrow: true };

更新氣泡樣式

通過updatePopup可以更新氣泡的樣式。支持全量更新和增量更新其氣泡樣式,不支持更新showInSubWindow、focusable、onStateChange、onWillDismiss和transition。

promptAction.updatePopup(contentNode, {enableArrow: false
}, true).then(() => {console.info('updatePopup success');}).catch((err: BusinessError) => {console.error('updatePopup error: ' + err.code + ' ' + err.message);})

關閉氣泡

通過調用closePopup可以關閉氣泡。

promptAction.closePopup(contentNode).then(() => {console.info('closePopup success');}).catch((err: BusinessError) => {console.error('closePopup error: ' + err.code + ' ' + err.message);})

由于updatePopup和closePopup依賴content來更新或者關閉指定的氣泡,開發者需自行維護傳入的content。

在HAR包中使用全局氣泡提示

以下示例通過HAR包封裝一個Popup,從而對外提供氣泡的彈出、更新和關閉能力。

// library/src/main/ets/components/MainPage.etsimport { BusinessError } from '@kit.BasicServicesKit';
import { ComponentContent, TargetInfo, PromptAction } from '@kit.ArkUI';export class PromptActionClass {private promptAction: PromptAction | null = null;private contentNode: ComponentContent<Object> | null = null;private options: PopupCommonOptions | null = null;private target: TargetInfo | null = null;private isPartialUpdate: boolean = false;public setPromptAction(promptAction: PromptAction) {this.promptAction = promptAction;}public setContentNode(node: ComponentContent<Object>) {this.contentNode = node;}public setTarget(target: TargetInfo) {this.target = target;}public setOptions(options: PopupCommonOptions) {this.options = options;}public setIsPartialUpdate(isPartialUpdate: boolean) {this.isPartialUpdate = isPartialUpdate;}public openPopup() {if (this.promptAction != null) {this.promptAction.openPopup(this.contentNode, this.target, this.options).then(() => {console.info('openPopup success');}).catch((err: BusinessError) => {console.error('openPopup error: ' + err.code + ' ' + err.message);})}}public closePopup() {if (this.promptAction != null) {this.promptAction.closePopup(this.contentNode).then(() => {console.info('closePopup success');}).catch((err: BusinessError) => {console.error('closePopup error: ' + err.code + ' ' + err.message);})}}public updatePopup(options: PopupCommonOptions) {if (this.promptAction != null) {this.promptAction.updatePopup(this.contentNode, options, this.isPartialUpdate).then(() => {console.info('updatePopup success');}).catch((err: BusinessError) => {console.error('updatePopup error: ' + err.code + ' ' + err.message);})}}
}
// entry/src/main/ets/pages/Index.etsimport { PromptActionClass } from "library";
import { ComponentContent, PromptAction } from '@kit.ArkUI';class Params {text: string = "";promptActionClass: PromptActionClass = new PromptActionClass();constructor(text: string, promptActionClass: PromptActionClass) {this.text = text;this.promptActionClass = promptActionClass;}
}@Builder
function buildText(params: Params) {Column() {Text(params.text).fontSize(20).margin({ top: 10 })Button('Update').margin({ top: 10 }).width(100).onClick(() => {params.promptActionClass.updatePopup({enableArrow: false,});})Button('Close').margin({ top: 10 }).width(100).onClick(() => {params.promptActionClass.closePopup();})}.width(130).height(150)
}@Entry
@Component
struct Index {@State message: string = "hello";private uiContext: UIContext = this.getUIContext();private promptAction: PromptAction = this.uiContext.getPromptAction();private promptActionClass: PromptActionClass = new PromptActionClass();private targetId: number = 0;private contentNode: ComponentContent<Object> =new ComponentContent(this.uiContext, wrapBuilder(buildText), new Params(this.message, this.promptActionClass));private options: PopupCommonOptions = { enableArrow: true };build() {Column() {Button("openPopup").margin({ top: 50, left: 100 }).onClick(() => {let frameNode: FrameNode | null = this.uiContext.getFrameNodeByUniqueId(this.getUniqueId());let targetId = frameNode?.getChild(0)?.getUniqueId();if (targetId == undefined) {this.targetId = 0;} else {this.targetId = targetId;}this.promptActionClass.setPromptAction(this.promptAction);this.promptActionClass.setContentNode(this.contentNode);this.promptActionClass.setOptions(this.options);this.promptActionClass.setIsPartialUpdate(false);this.promptActionClass.setTarget({ id: this.targetId });this.promptActionClass.openPopup();})}}
}

?

不依賴UI組件的全局菜單 (openMenu)

菜單控制 (Menu)在使用時依賴綁定UI組件,否則無法使用。從API version 18開始,可以通過使用全局接口openMenu的方式,在無UI組件的場景下直接或封裝使用,例如在事件回調中使用或封裝后對外提供能力。

彈出菜單

通過openMenu可以彈出菜單。

promptAction.openMenu(contentNode, { id: targetId }, {enableArrow: true
}).then(() => {console.info('openMenu success');}).catch((err: BusinessError) => {console.error('openMenu error: ' + err.code + ' ' + err.message);})

創建ComponentContent

通過調用openMenu接口彈出菜單,需要提供用于定義自定義彈出框的內容ComponentContent。其中,wrapBuilder(buildText)封裝自定義組件,new Params(this.message)是自定義組件的入參,可以缺省,也可以傳入基礎數據類型。

private contentNode: ComponentContent<Object> = new ComponentContent(uiContext, wrapBuilder(buildText), this.message);

如果在wrapBuilder中包含其他組件(例如:Popup、Chip組件),則ComponentContent應采用帶有四個參數的構造函數constructor,其中options參數應傳遞{ nestingBuilderSupported: true }。

@Builder
export function buildText(params: Params) {Menu({// 類型設置圖標內容icon: {image: $r('app.media.app_icon'),width: 32,height: 32,fillColor: Color.White,borderRadius: 10} as MenuIconOptions,// 設置文字內容title: {text: `This is a Menu title 1`,fontSize: 20,fontColor: Color.Black,fontWeight: FontWeight.Normal} as MenuTextOptions,// 設置文字內容message: {text: `This is a Menu message 1`,fontSize: 15,fontColor: Color.Black} as MenuTextOptions,// 設置按鈕內容buttons: [{text: 'confirm',action: () => {console.info('confirm button click');},fontSize: 15,fontColor: Color.Black,},{text: 'cancel',action: () => {console.info('cancel button click');},fontSize: 15,fontColor: Color.Black},] as [MenuButtonOptions?, MenuButtonOptions?]})
}let contentNode: ComponentContent<Object> = new ComponentContent(uiContext, wrapBuilder(buildText), this.message, { nestingBuilderSupported: true });

綁定組件信息

通過調用openMenu接口彈出菜單,需要提供綁定組件的信息TargetInfo。若未傳入有效的target,則無法彈出菜單。

let frameNode: FrameNode | null = this.ctx.getFrameNodeByUniqueId(this.getUniqueId());
let targetId = frameNode?.getChild(0)?.getUniqueId();

設置彈出菜單樣式

通過調用openMenu接口彈出菜單,可以設置MenuOptions屬性調整菜單樣式。title屬性不生效。preview參數僅支持設置MenuPreviewMode類型。

private options: MenuOptions = { enableArrow: true, placement: Placement.Bottom };

更新菜單樣式

通過updateMenu可以更新菜單的樣式。支持全量更新和增量更新其菜單樣式,不支持更新showInSubWindow、preview、previewAnimationOptions、transition、onAppear、aboutToAppear、onDisappear和aboutToDisappear。

promptAction.updateMenu(contentNode, {enableArrow: false
}, true).then(() => {console.info('updateMenu success');}).catch((err: BusinessError) => {console.error('updateMenu error: ' + err.code + ' ' + err.message);})

關閉菜單

通過調用closeMenu可以關閉菜單。

promptAction.closeMenu(contentNode).then(() => {console.info('openMenu success');}).catch((err: BusinessError) => {console.error('openMenu error: ' + err.code + ' ' + err.message);})

由于updateMenu和closeMenu依賴content來更新或者關閉指定的菜單,開發者需自行維護傳入的content。

在HAR包中使用全局菜單

可以通過HAR包封裝一個Menu,從而對外提供菜單的彈出、更新和關閉能力。

Toast

即時反饋(Toast)是一種臨時性的消息提示框,用于向用戶顯示簡短的操作反饋或狀態信息。?它通常在屏幕的底部或頂部短暫彈出,隨后在一段時間后自動消失。即時反饋的主要目的是提供簡潔、不打擾的信息反饋,避免干擾用戶當前的操作流程。

可以通過使用UIContext中的getPromptAction方法獲取當前UI上下文關聯的PromptAction對象,再通過該對象調用showToast創建并顯示文本提示框。

為了安全考慮,例如Toast惡意遮擋其他頁面,Toast只能顯示在當前的UI實例中,應用退出后,不會單獨顯示在桌面上。

使用建議

  • 合理使用彈出場景,避免過度提醒用戶。
  • 可以針對以下常用場景使用即時反饋操作,例如,當用戶執行某個操作時及時結果反饋,用來提示用戶操作是否成功或失敗;或是當應用程序的狀態發生變化時提供狀態更新等。
  • 注意文本的信息密度,即時反饋展示時間有限,應當避免長文本的出現。
  • Toast控件的文本應該清晰可讀,字體大小和顏色應該與應用程序的主題相符。除此之外,即時反饋控件本身不應該包含任何可交互的元素,如按鈕或鏈接。
  • 杜絕強制占位和密集彈出的提示。
  • 即時反饋作為應用內的輕量通知,應當避免內容布局占用界面內的其他元素信息,如遮蓋彈出框的展示內容,從而迷惑用戶彈出的內容是否屬于彈出框。再或者頻繁性的彈出信息內容,且每次彈出之間無時間間隔,影響用戶的正常使用。也不要在短時間內頻繁彈出新的即時反饋替代上一個。即時反饋的單次顯示時長不要超過 3 秒鐘,避免影響用戶正常的行為操作。
  • 遵從系統默認彈出位置。
  • 即時反饋在系統中默認從界面底部彈出,距離底部有一定的安全間距,作為系統性的應用內提示反饋,請遵守系統默認效果,避免與其他彈出類組件內容重疊。特殊場景下可對內容布局進行規避。

即時反饋模式對比

即時反饋提供了兩種顯示模式,分別為DEFAULT(顯示在應用內)、TOP_MOST(顯示在應用之上)。

在TOP_MOST類型的Toast顯示前,會創建一個全屏大小的子窗(手機上子窗大小和主窗大小一致),然后在該子窗上計算Toast的布局位置,最后顯示在該子窗上。具體和DEFAULT模式Toast的差異如下:

差異點DEFAULTTOP_MOST
是否創建子窗
層級顯示在主窗內,層級和主窗一致,一般比較低顯示在子窗中,一般比主窗層級高,比其他彈窗類組件層級高,比軟鍵盤和權限彈窗層級低
是否避讓軟鍵盤軟鍵盤抬起時,必定上移軟鍵盤的高度軟鍵盤抬起時,只有toast被遮擋時,才會避讓,且避讓后toast底部距離軟鍵盤高度為80vp
UIExtension內布局以UIExtension為主窗中布局,對齊方式與UIExtension對齊以宿主窗口為主窗中布局,對齊方式與宿主窗口對齊
import { promptAction } from '@kit.ArkUI';@Entry
@Component
struct Index {build() {Column({ space: 10 }) {TextInput()Button() {Text("DEFAULT類型Toast").fontSize(20).fontWeight(FontWeight.Bold)}.width('100%').onClick(() => {this.getUIContext().getPromptAction().showToast({message: "ok,我是DEFAULT toast",duration: 2000,showMode: promptAction.ToastShowMode.DEFAULT,bottom: 80});})Button() {Text("TOPMOST類型Toast").fontSize(20).fontWeight(FontWeight.Bold)}.width('100%').onClick(() => {this.getUIContext().getPromptAction().showToast({message: "ok,我是TOP_MOST toast",duration: 2000,showMode: promptAction.ToastShowMode.TOP_MOST,bottom: 85});})}}
}

創建即時反饋

適用于短時間內提示框自動消失的場景

import { PromptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';@Entry
@Component
struct toastExample {private uiContext: UIContext = this.getUIContext();private promptAction: PromptAction = this.uiContext.getPromptAction();build() {Column() {Button('Show toast').fontSize(20).onClick(() => {try {this.promptAction.showToast({message: 'Hello World',duration: 2000})} catch (error) {let message = (error as BusinessError).message;let code = (error as BusinessError).code;console.error(`showToast args error code is ${code}, message is ${message}`);};})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}

顯示關閉即時反饋

適用于提示框提留時間較長,用戶操作可以提前關閉提示框的場景。

import { LengthMetrics, PromptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';@Entry
@Component
struct toastExample {@State toastId: number = 0;private uiContext: UIContext = this.getUIContext();private promptAction: PromptAction = this.uiContext.getPromptAction();build() {Column() {Button('Open Toast').type(ButtonType.Capsule).height(100).onClick(() => {try {this.promptAction.openToast({message: 'Toast Massage',duration: 10000,}).then((toastId: number) => {this.toastId = toastId;});} catch (error) {let message = (error as BusinessError).message;let code = (error as BusinessError).code;console.error(`OpenToast error code is ${code}, message is ${message}`);};})Blank().height(50);Button('Close Toast').height(100).type(ButtonType.Capsule).onClick(() => {try {this.promptAction.closeToast(this.toastId);} catch (error) {let message = (error as BusinessError).message;let code = (error as BusinessError).code;console.error(`CloseToast error code is ${code}, message is ${message}`);};})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/89579.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/89579.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/89579.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

讓老舊醫療設備“聽懂”新語言:CAN轉EtherCAT的醫療行業應用

在醫療影像設備的智能化升級中&#xff0c;通信協議的兼容性常成為工程師的“痛點”。例如&#xff0c;某醫院的移動式X射線機采用CAN協議控制機械臂&#xff0c;而主控系統基于EtherCAT架構。兩者協議差異導致數據延遲高達5ms&#xff0c;影像定位精度下降&#xff0c;甚至影響…

ubuntu基礎搭建

ubuntu上docker的搭建 https://vulhub.org/zh 網站最下面找到開始使用&#xff0c;有搭建的命令//安裝docker&#xff0c;連接失敗多試幾次 curl -fsSL https://get.docker.com | sh //驗證Docker是否正確安裝&#xff1a; docker version //還要驗證Docker Compose是否可用&am…

動態規劃 + DFS + 記憶化!Swift 解 LeetCode 329 的實戰筆記

文章目錄摘要描述題解答案題解代碼分析代碼解析示例測試及結果時間復雜度空間復雜度總結摘要 這篇文章帶你用 Swift 實戰一道非常經典的 DFS 記憶化搜索題目 —— LeetCode 329《矩陣中的最長遞增路徑》。看似一個簡單的“走格子”游戲&#xff0c;實則考察了搜索順序、剪枝策…

046_局部內部類與匿名內部類

一、局部內部類&#xff08;Local Inner Class&#xff09; 1.1 定義與基本概念 局部內部類是定義在方法、構造器或代碼塊內部的類&#xff0c;其作用域僅限于所在的局部范圍&#xff08;定義它的方法、構造器或代碼塊&#xff09;&#xff0c;超出該范圍則無法訪問。 它的核心…

Jenkins Pipeline 中使用 JsonSlurper 報錯:cannot find current thread

Jenkins Pipeline 中使用 JsonSlurper 報錯&#xff1a;cannot find current thread&#x1f31f; 背景? 問題重現&#x1f9e0; 原因解析&#xff1a;CPS 與非 CPS 安全方法沖突? 解決方案一&#xff1a;使用 NonCPS 注解&#xff08;經典方案&#xff09;? 解決方案二&…

Go 語言循環語句詳解

Go 語言循環語句詳解 在編程語言中&#xff0c;循環語句是實現重復執行某些代碼塊的關鍵元素。Go 語言作為現代編程語言之一&#xff0c;提供了多種循環結構來滿足不同的編程需求。本文將詳細講解 Go 語言中的循環語句&#xff0c;包括 for、while 和 goto 語句&#xff0c;幫助…

day30——零基礎學嵌入式之進程間通信1.0

一、進程間通信7種方式1.傳統的進程間通信方式&#xff08;1&#xff09;管道①無名管道&#xff1a;②有名管道&#xff1a;&#xff08;2&#xff09;③信號&#xff08;3&#xff09;system Ⅴ 》系統Ⅴ 進程間通信方式 inner Process Comunication④共享內存 &#xff…

408考研逐題詳解:2010年第33題——網絡體系結構

2010年第33題 下列選項中&#xff0c;不屬于網絡體系結構所描述的內容是&#xff08; &#xff09; A. 網絡的層次 \qquad B. 每層使用的協議 \qquad C. 協議的內部實現細節 \qquad D. 每層必須完成的功能 解析 本題屬于計算機網絡基礎知識的范疇&#xff0c;考查網絡體系結構…

VR 遠程系統的沉浸式協作體驗?

在傳統的遠程協作中&#xff0c;團隊成員往往通過二維的視頻畫面進行交流&#xff0c;這種方式雖然能實現基本的溝通&#xff0c;但缺乏真實感和互動性。而 VR 遠程系統的出現&#xff0c;徹底改變了這一局面。戴上 VR 設備&#xff0c;員工們仿佛置身于同一個真實的辦公室空間…

記錄DataGrip 2025.1.3破解失敗后,無法重啟問題修復

記錄DataGrip 2025.1.3破解失敗后&#xff0c;無法重啟問題修復安裝過程復盤異常場景解決方式總結安裝過程 在官網下載了最新版本2025.1.3。安裝成功后&#xff0c;使用30天試用方式&#xff0c;打開datagrip。 復盤異常場景 網上搜索破解教程進行破解。找了一個需要現在ja…

私有服務器AI智能體搭建配置選擇記錄

在搭建私有服務器上的AI智能體時&#xff0c;需要從多個方面進行選擇和規劃&#xff0c;以確保系統性能、安全性、可擴展性等方面滿足需求。1. 硬件選擇 服務器配置&#xff1a; CPU&#xff1a;選擇高性能多核CPU&#xff08;如Intel Xeon或AMD EPYC系列&#xff09;&#xff…

SDC Specical check setting的描述 - false path

在上一篇文中描述了SDC的基本語法&#xff0c;其中關于時序異常約束并沒有進行詳細的描述&#xff0c;但是在正常的設計中&#xff0c;一般這種異常的設置反而是需要特別關注的&#xff0c;主要包括&#xff1a;1. 虛假路徑- false path不需要滿足任何時序要求的路徑&#xff1…

【Python練習】048. 編寫一個函數,實現簡單的命令行接口,接受用戶輸入并響應

048. 編寫一個函數,實現簡單的命令行接口,接受用戶輸入并響應 在 Python 中,可以通過 input() 函數創建一個簡單的命令行接口,接受用戶輸入并根據輸入內容進行響應。 示例代碼 def simple_command_line_interface():"""實現一個簡單的命令行接口,接受用…

軟件工廠語境下的知識系統選型:兼顧合規性與集成深度

在過去幾十年間&#xff0c;制造業從“工匠手作”邁向“工業流水線”&#xff0c;完成了生產效率的巨大飛躍。當軟件開發也面臨交付復雜性、合規要求與協作成本不斷上升的現實&#xff0c;“軟件工廠”的理念逐步興起。 在這場“開發現代化”的轉型中&#xff0c;知識管理被重新…

C語言-一維數組,二維數組

數組 數組的引入如果要在程序中保存一個人的年齡&#xff1f;如何保存&#xff1f; 答&#xff1a;創建一個基于int類型的變量&#xff0c;舉例&#xff1a;int age 22如果要在程序中保存一個人的三門課的成績&#xff1f;如何保存&#xff1f; 答&#xff1a;創建三個基于flo…

如何區別HTML和HTML5?

要區分 HTML&#xff08;通常指 HTML4 及更早版本&#xff09;和 HTML5&#xff0c;主要可以從以下關鍵方面進行比較&#xff1a;一、文檔聲明區別 <!-- HTML4 文檔聲明 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http:/…

Java實戰:實時聊天應用開發(附GitHub鏈接)

一、前置技術項目介紹&#xff1a; 項目為局域網溝通軟件&#xff0c;類似內網通&#xff0c;核心功能包括昵稱輸入、聊天界面展示在線人數&#xff08;實時更新&#xff09;、群聊&#xff0c;也可擴展私聊、登錄注冊、聊天記錄存儲等功能&#xff0c;結尾附GitHub鏈接。項目涉…

linux 的list_for_each_entry

linux的宏定義提高了代碼的簡潔性&#xff0c;但有時候的命名不夠完美。比如list_for_each_entry&#xff0c;看名字只知道是遍歷list&#xff0c;但一看里面的三個變量參數&#xff0c;有點懵逼。/*** list_for_each_entry - iterate over list of given type* pos: …

分布式面試點

目錄 1.分布式理論 為什么CAP不可兼得呢? 2.CAP對應的模型和應用 3.Base理論 4,有哪些分布式鎖的案例 5.分布式事務 6.Seata 分布式一致性算法 1. 準備階段&#xff08;Prepare Phase&#xff09; 2. 接受階段&#xff08;Accept Phase&#xff09; 3. 學習階段&…

Neo4j系列---【Linux離線安裝neo4j】

Linux離線安裝neo4j 1.官方安裝文檔 地址&#xff1a;https://neo4j.com/docs/operations-manual/current/installation/linux/tarball/ 2.如果瀏覽器無法訪問 修改neo4j.conf,開放所有ip訪問 # 允許所有IP地址訪問 server.default_listen_address0.0.0.0 3.創建開機自啟動服務…