HarmonyOS(三)—— 應用程序入口—UIAbility

前言

學習過android的同學都是知道Activity,Activity是Android組件中最基本也是最為常見用的四大組件之一,用戶可以用來交互為了完成某項任務。

Activity中所有操作都與用戶密切相關,是一個負責與用戶交互的組件,可以通過setContentView(View)來顯示指定控件。

在一個android應用中,一個Activity通常就是一個單獨的屏幕,它上面可以顯示一些控件也可以監聽并處理用戶的事件做出響應。Activity之間通過Intent進行通信。

同時,Activity也有這自己的生命周期,不同的生命周期Activity的交互狀態也有所不同。

而HarmonyOS的UIAbility就和Android的activity非常相似,今天就介紹一下UIAbility是什么,是如何和用戶交互,頁面間跳轉,以及各個生命周期的作用。

UIAbility概述

UIAbility是一種包含用戶界面的應用組件,主要用于和用戶進行交互。UIAbility也是系統調度的單元,為應用提供窗口在其中繪制界面。

每一個UIAbility實例,都對應于一個最近任務列表中的任務。

一個應用可以有一個UIAbility,也可以有多個UIAbility,如下圖所示。例如瀏覽器應用可以通過一個UIAbility結合多頁面的形式讓用戶進行的搜索和瀏覽內容;而聊天應用增加一個“外賣功能”的場景,則可以將聊天應用中“外賣功能”的內容獨立為一個UIAbility,當用戶打開聊天應用的“外賣功能”,查看外賣訂單詳情,此時有新的聊天消息,即可以通過最近任務列表切換回到聊天窗口繼續進行聊天對話。

一個UIAbility可以對應于多個頁面,建議將一個獨立的功能模塊放到一個UIAbility中,以多頁面的形式呈現。例如新聞應用在瀏覽內容的時候,可以進行多頁面的跳轉使用。

在這里插入圖片描述

UIAbility內頁面的跳轉和數據傳遞

我們知道,在Android中,activity之間頁面跳轉是通過startActivity方法進行跳轉的,二頁面間參數傳遞則是通過Intent進行通信。而作為HarmonyOS的應用程序入口—UIAbility同樣支持相同的功能。

UIAbility的數據傳遞包括有UIAbility內頁面的跳轉和數據傳遞、UIAbility間的數據跳轉和數據傳遞,這里主要講解UIAbility內頁面的跳轉和數據傳遞。

頁面間的導航可以通過頁面路由router模塊來實現。頁面路由模塊根據頁面url找到目標頁面,從而實現跳轉。通過頁面路由模塊,可以使用不同的url訪問不同的頁面,包括跳轉到UIAbility內的指定頁面、用UIAbility內的某個頁面替換當前頁面、返回上一頁面或指定的頁面等。具體使用方法請參見ohos.router (頁面路由)。

頁面跳轉和參數接收

在使用頁面路由之前,需要先導入router模塊,如下代碼所示。

import router from '@ohos.router';

頁面跳轉的幾種方式,根據需要選擇一種方式跳轉即可。

  1. 方式一:API9及以上,router.pushUrl()方法新增了mode參數,可以將mode參數配置為router.RouterMode.Single單實例模式和router.RouterMode.Standard多實例模式。
    在單實例模式下:如果目標頁面的url在頁面棧中已經存在同url頁面,離棧頂最近同url頁面會被移動到棧頂,移動后的頁面為新建頁,原來的頁面仍然存在棧中,頁面棧的元素數量不變;如果目標頁面的url在頁面棧中不存在同url頁面,按多實例模式跳轉,頁面棧的元素數量會加1。
router.pushUrl({url: 'pages/Second',params: {src: 'Index頁面傳來的數據',}
}, router.RouterMode.Single)

注意:
當頁面棧的元素數量較大或者超過32時,可以通過調用router.clear()方法清除頁面棧中的所有歷史頁面,僅保留當前頁面作為棧頂頁面。

  1. 方式二:API9及以上,router.replaceUrl()方法新增了mode參數,可以將mode參數配置為router.RouterMode.Single單實例模式和router.RouterMode.Standard多實例模式。
    在單實例模式下:如果目標頁面的url在頁面棧中已經存在同url頁面,離棧頂最近同url頁面會被移動到棧頂,替換當前頁面,并銷毀被替換的當前頁面,移動后的頁面為新建頁,頁面棧的元素數量會減1;如果目標頁面的url在頁面棧中不存在同url頁面,按多實例模式跳轉,頁面棧的元素數量不變。
router.replaceUrl({url: 'pages/Second',params: {src: 'Index頁面傳來的數據',}
}, router.RouterMode.Single)

已經實現了頁面的跳轉,接下來,在Second頁面中如何進行自定義參數的接收呢?

通過調用router.getParams()方法獲取Index頁面傳遞過來的自定義參數。

import router from '@ohos.router';@Entry
@Component
struct Second {@State src: string = (router.getParams() as Record<string, string>)['src'];// 頁面刷新展示...
}

頁面返回和參數接收

經常還會遇到一個場景,在Second頁面中,完成了一些功能操作之后,希望能返回到Index頁面,那我們要如何實現呢?

在Second頁面中,可以通過調用router.back()方法實現返回到上一個頁面,或者在調用router.back()方法時增加可選的options參數(增加url參數)返回到指定頁面。

  • 調用router.back()返回的目標頁面需要在頁面棧中存在才能正常跳轉。
  • 例如調用router.pushUrl()方法跳轉到Second頁面,在Second頁面可以通過調用router.back()方法返回到上一個頁面。
  • 例如調用router.clear()方法清空了頁面棧中所有歷史頁面,僅保留當前頁面,此時則無法通過調用router.back()方法返回到上一個頁面。

1:返回上一個頁面。

router.back();

2:返回到指定頁面。

router.back({ url: 'pages/Index' });

3:頁面返回詢問對話框。
有的時候,頁面返回根據業務需要增加一個詢問對話框。即在調用router.back()方法之前,可以先調用router.enableBackPageAlert()方法開啟頁面返回詢問對話框功能。

router.enableBackPageAlert({message: 'Message Info'
});router.back();

注意:
1: router.enableBackPageAlert()方法開啟頁面返回詢問對話框功能,只針對當前頁面生效。例如在調用router.pushUrl()或者router.replaceUrl()方法,跳轉后的頁面均為新建頁面,因此在頁面返回之前均需要先調用router.enableBackPageAlert()方法之后,頁面返回詢問對話框功能才會生效。
2:如需關閉頁面返回詢問對話框功能,可以通過調用router.disableAlertBeforeBackPage()方法關閉該功能即可。

4:返回指定頁面
調用router.back()方法返回上一個指定頁面時,通過指定url,返回指定的頁面。如果需要繼續增加自定義參數,例如可以在返回時增加一個自定義參數data。

router.back({url: 'pages/Index',params: {data: 'Second頁面傳來的數據',}
})

從Second頁面返回到Index頁面。在Index頁面通過調用router.getParams()方法,獲取Second頁面傳遞過來的自定義參數。

注意:
調用router.back()方法,不會新建頁面,返回的是原來的頁面,在原來頁面中@State聲明的變量不會重復聲明,以及也不會觸發頁面的aboutToAppear()生命周期回調,因此無法直接在變量聲明以及頁面的aboutToAppear()生命周期回調中接收和解析router.back()傳遞過來的自定義參數。

可以放在業務需要的位置進行參數解析。示例代碼在Index頁面中的onPageShow()生命周期回調中進行參數的解析。

import router from '@ohos.router';
@Entry
@Component
struct Index {@State src: string = '';onPageShow() {this.src = (router.getParams() as Record<string, string>)['src'];}// 頁面刷新展示...
}

UIAbility的生命周期

當用戶瀏覽、切換和返回到對應應用的時候,應用中的UIAbility實例會在其生命周期的不同狀態之間轉換。

UIAbility類提供了很多回調,通過這些回調可以知曉當前UIAbility的某個狀態已經發生改變:例如UIAbility的創建和銷毀,或者UIAbility發生了前后臺的狀態切換。

在UIAbility的使用過程中,會有多種生命周期狀態。掌握UIAbility的生命周期,對于應用的開發非常重要。

為了實現多設備形態上的裁剪和多窗口的可擴展性,系統對組件管理和窗口管理進行了解耦。UIAbility的生命周期包括Create、Foreground、Background、Destroy四個狀態,WindowStageCreate和WindowStageDestroy為窗口管理器(WindowStage)在UIAbility中管理UI界面功能的兩個生命周期回調,從而實現UIAbility與窗口之間的弱耦合。如下圖所示。

在這里插入圖片描述

  • Create狀態,在UIAbility實例創建時觸發,系統會調用onCreate回調。可以在onCreate回調中進行相關初始化操作。
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';export default class EntryAbility extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {// 應用初始化...}...
}

例如用戶打開電池管理應用,在應用加載過程中,在UI頁面可見之前,可以在onCreate回調中讀取當前系統的電量情況,用于后續的UI頁面展示。

  • UIAbility實例創建完成之后,在進入Foreground之前,系統會創建一個WindowStage。每一個UIAbility實例都對應持有一個WindowStage實例。
    WindowStage為本地窗口管理器,用于管理窗口相關的內容,例如與界面相關的獲焦/失焦、可見/不可見。

可以在onWindowStageCreate回調中,設置UI頁面加載、設置WindowStage的事件訂閱。

在onWindowStageCreate(windowStage)中通過loadContent接口設置應用要加載的頁面,Window接口的使用詳見窗口開發指導。

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';export default class EntryAbility extends UIAbility {...onWindowStageCreate(windowStage: window.WindowStage) {// 設置UI頁面加載// 設置WindowStage的事件訂閱(獲焦/失焦、可見/不可見)...windowStage.loadContent('pages/Index', (err, data) => {...});}...
}

例如用戶打開游戲應用,正在打游戲的時候,有一個消息通知,打開消息,消息會以彈窗的形式彈出在游戲應用的上方,此時,游戲應用就從獲焦切換到了失焦狀態,消息應用切換到了獲焦狀態。對于消息應用,在onWindowStageCreate回調中,會觸發獲焦的事件回調,可以進行設置消息應用的背景顏色、高亮等操作。

  • Foreground和Background狀態,分別在UIAbility切換至前臺或者切換至后臺時觸發。
    分別對應于onForeground回調和onBackground回調。

onForeground回調,在UIAbility的UI頁面可見之前,即UIAbility切換至前臺時觸發。可以在onForeground回調中申請系統需要的資源,或者重新申請在onBackground中釋放的資源。

onBackground回調,在UIAbility的UI頁面完全不可見之后,即UIAbility切換至后臺時候觸發。可以在onBackground回調中釋放UI頁面不可見時無用的資源,或者在此回調中執行較為耗時的操作,例如狀態保存等。

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';export default class EntryAbility extends UIAbility {...onForeground() {// 申請系統需要的資源,或者重新申請在onBackground中釋放的資源...}onBackground() {// 釋放UI頁面不可見時無用的資源,或者在此回調中執行較為耗時的操作// 例如狀態保存等...}
}

例如用戶打開地圖應用查看當前地理位置的時候,假設地圖應用已獲得用戶的定位權限授權。在UI頁面顯示之前,可以在onForeground回調中打開定位功能,從而獲取到當前的位置信息。

當地圖應用切換到后臺狀態,可以在onBackground回調中停止定位功能,以節省系統的資源消耗。

  • 前面我們了解了UIAbility實例創建時的onWindowStageCreate回調的相關作用。

對應于onWindowStageCreate回調。在UIAbility實例銷毀之前,則會先進入onWindowStageDestroy回調,我們可以在該回調中釋放UI頁面資源。

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';export default class EntryAbility extends UIAbility {...onWindowStageDestroy() {// 釋放UI頁面資源...}
}

例如在onWindowStageCreate中設置的獲焦/失焦等WindowStage訂閱事件。

  • Destroy狀態,在UIAbility銷毀時觸發。可以在onDestroy回調中進行系統資源的釋放、數據的保存等操作。
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';export default class EntryAbility extends UIAbility {...onDestroy() {// 系統資源的釋放、數據的保存等...}
}

例如用戶使用應用的程序退出功能,會調用UIAbilityContext的terminalSelf()方法,從而完成UIAbility銷毀。或者用戶使用最近任務列表關閉該UIAbility實例時,也會完成UIAbility的銷毀。

UIAbility的啟動模式

通常我們打開某一個應用,并瀏覽訪問相關內容后,回到桌面,當再次打開該應用,顯示的仍然是用戶當前訪問的界面。

對于應用的分屏操作,用戶希望使用兩個不同應用(例如備忘錄應用和圖庫應用)之間進行分屏,也希望能使用同一個應用(例如備忘錄應用自身)進行分屏。

對于文檔應用,用戶從文檔應用中打開一個文檔內容,回到文檔應用,繼續打開同一個文檔,希望打開的還是同一個文檔內容。

基于以上場景的考慮,UIAbility當前支持singleton(單實例模式)、multiton(多實例模式)和specified(指定實例模式)3種啟動模式。

3種啟動模式的詳細說明如下:

  • singleton(單實例模式)

打開某一個應用,并瀏覽訪問相關內容后,回到桌面,當再次打開該應用,顯示的仍然是用戶當前訪問的界面。

這種情況下可以將UIAbility配置為singleton(單實例模式)。每次調用startAbility()方法時,如果應用進程中該類型的UIAbility實例已經存在,則復用系統中的UIAbility實例,系統中只存在唯一一個該UIAbility實例。

即在最近任務列表中只存在一個該類型的UIAbility實例。

singleton啟動模式,也是默認情況下的啟動模式。singleton啟動模式,每次調用startAbility()啟動UIAbility時,如果應用進程中該類型的UIAbility實例已經存在,則復用系統中的UIAbility實例,系統中只存在唯一一個該UIAbility實例。

singleton啟動模式的開發使用,在module.json5文件中的“launchType”字段配置為“singleton”即可。

{"module": {..."abilities": [{"launchType": "singleton",...}]}
}
  • multiton(多實例模式)

用戶在使用分屏功能時,希望使用兩個不同應用(例如備忘錄應用和圖庫應用)之間進行分屏,也希望能使用同一個應用(例如備忘錄應用自身)進行分屏。

這種情況下可以將UIAbility配置為multiton(多實例模式)。每次調用startAbility()方法時,都會在應用進程中創建一個該類型的UIAbility實例。

即在最近任務列表中可以看到有多個該類型的UIAbility實例。

multiton啟動模式,每次調用startAbility()方法時,都會在應用進程中創建一個該類型的UIAbility實例。

multiton啟動模式的開發使用,在module.json5文件中的“launchType”字段配置為“multiton”即可。

{"module": {..."abilities": [{"launchType": "multiton",...}]}
}
  • specified(指定實例模式)

用戶打開文檔應用,從文檔應用中打開一個文檔內容,回到文檔應用,繼續打開同一個文檔,希望打開的還是同一個文檔內容;以及在文檔應用中新建一個新的文檔,每次新建文檔,希望打開的都是一個新的空白文檔內容。

這種情況下可以將UIAbility配置為specified(指定實例模式)。在UIAbility實例新創建之前,允許開發者為該實例創建一個字符串Key,新創建的UIAbility實例綁定Key之后,后續每次調用startAbility方法時,都會詢問應用使用哪個Key對應的UIAbility實例來響應startAbility請求。如果匹配有該UIAbility實例的Key,則直接拉起與之綁定的UIAbility實例,否則創建一個新的UIAbility實例。運行時由UIAbility內部業務決定是否創建多實例。

specified啟動模式,根據業務需要是否創建一個新的UIAbility實例。在UIAbility實例創建之前,會先進入AbilityStage的onAcceptWant回調,在onAcceptWant回調中為每一個UIAbility實例創建一個Key,后續每次調用startAbility()方法創建該類型的UIAbility實例都會詢問使用哪個Key對應的UIAbility實例來響應startAbility()請求。

specified啟動模式的開發使用的步驟如下所示。

  1. 在module.json5文件中的“launchType”字段配置為“specified”。
{"module": {..."abilities": [{"launchType": "specified",...}]}
}
  1. 在調用startAbility()方法的want參數中,增加一個自定義參數來區別UIAbility實例,例如增加一個“instanceKey”自定義參數。
// 在啟動指定實例模式的UIAbility時,給每一個UIAbility實例配置一個獨立的Key標識
function getInstance() {...
}
let context:common.UIAbilityContext = ...; // context為調用方UIAbility的UIAbilityContext
let want: Want = {deviceId: '', // deviceId為空表示本設備bundleName: 'com.example.myapplication',abilityName: 'SpecifiedAbility',moduleName: 'specified', // moduleName非必選parameters: { // 自定義信息instanceKey: getInstance(),},
}
context.startAbility(want).then(() => {...
}).catch((err: BusinessError) => {...
})
  1. 在被拉起方UIAbility對應的AbilityStage的onAcceptWant生命周期回調中,解析傳入的want參數,獲取“instanceKey”自定義參數。根據業務需要返回一個該UIAbility實例的字符串Key標識。如果之前啟動過此Key標識的UIAbility,則會將之前的UIAbility拉回前臺并獲焦,而不創建新的實例,否則創建新的實例并啟動。
onAcceptWant(want: want): string {// 在被啟動方的AbilityStage中,針對啟動模式為specified的UIAbility返回一個UIAbility實例對應的一個Key值// 當前示例指的是device Module的EntryAbilityif (want.abilityName === 'MainAbility') {return `DeviceModule_MainAbilityInstance_${want.parameters.instanceKey}`;}return '';
}

例如在文檔應用中,可以對不同的文檔實例內容綁定不同的Key值。當每次新建文檔的時候,可以傳入不同的新Key值(如可以將文件的路徑作為一個Key標識),此時AbilityStage中啟動UIAbility時都會創建一個新的UIAbility實例;當新建的文檔保存之后,回到桌面,或者新打開一個已保存的文檔,回到桌面,此時再次打開該已保存的文檔,此時AbilityStage中再次啟動該UIAbility時,打開的仍然是之前原來已保存的文檔界面。

總結

  • UIAbility是一種包含用戶界面的應用組件,用于和用戶進行交互的相關邏輯,他和Android的activity類似,都是屬于系統調度的單元。
  • UIAbility之間是可以相互跳轉和傳遞值的,這些都是通過路由來實現的
  • UIAbility和和Android的activity一樣也是有生命周期的,了解UIAbility的創建,前后臺切換,銷毀的生命周期狀態,有助于靈活掌握各個生命周期在特定場景可以干什么事。
  • 了解UIAbility的創建以及其對應頁面的如何創建。

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

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

相關文章

10個容易被忽視的FastAPI實用功能

大家好&#xff0c;FastAPI是一種現代、高性能的Python Web框架&#xff0c;用于構建Web應用程序和API。它基于Python的異步編程庫asyncio和await語法&#xff0c;以及類型注解和自動文檔生成等特性&#xff0c;提供了快速、易用和可靠的開發體驗&#xff0c;接下來本文將介紹1…

ElasticSearch之Nodes info API

查看當前集群中各節點的信息&#xff0c;執行如下命令&#xff1a; curl -X GET "https://localhost:9200/_nodes?pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"本接口允許指定節點和指標。 當前支持的指標&#…

機器視覺公司為什么寧愿高薪招新人,也不愿加薪留老員工?老員工特殊時間特殊照顧,新人必須常照顧

?職場常出現的“薪酬倒掛”現象。其實這是正常的職場規律&#xff0c;實際上是企業管理不得不面對的一種選擇。 很多企業寧愿老員工離職也不加薪&#xff0c;卻高薪請新員工&#xff1f;這就是職場上的鯰魚效應&#xff0c;一些高層領導認為一個企業&#xff0c;老員工好比沙…

基本的彈層,點擊彈出

<div class"role"><el-button type"primary" size"mini" click"showDialog true">添加角色</el-button></div><!--控制彈框的顯示隱藏visible .sync可以點擊X關閉彈框 --> <el-dialog width"…

Spring Cloud學習(十一)【深入Elasticsearch 分布式搜索引擎03】

文章目錄 數據聚合聚合的種類DSL實現聚合RestAPI實現聚合 自動補全拼音分詞器自定義分詞器自動補全查詢completion suggester查詢RestAPI實現自動補全 數據同步數據同步思路分析實現elasticsearch與數據庫數據同步 集群搭建ES集群創建es集群集群狀態監控創建索引庫1&#xff09…

【RocketMq系列-02】RocketMq的架構解析和高性能設計

RocketMq系列整體欄目 內容鏈接地址【一】RocketMq安裝和基本概念https://zhenghuisheng.blog.csdn.net/article/details/134486709【二】RocketMq的架構解析和高性能設計/font>https://zhenghuisheng.blog.csdn.net/article/details/134559514 RocketMq的架構解析和高性能設…

CentOS 防火墻查看已開發的端口

在CentOS上&#xff0c;你可以使用 firewall-cmd 命令來查詢當前防火墻規則&#xff0c;以查看已經開放的端口。以下是一些常見的查詢命令&#xff1a; 查詢已開啟的端口&#xff1a; sudo firewall-cmd --list-ports這將列出所有已經開啟的端口。 查詢已開啟的服務&#xf…

leetcode:520. 檢測大寫字母

一、題目&#xff1a; 鏈接&#xff1a;520. 檢測大寫字母 - 力扣&#xff08;LeetCode&#xff09; 函數原型&#xff1a;bool detectCapitalUse(char* word) 二、思路&#xff1a; 本題較為簡單&#xff0c;分為三種情況&#xff1a; 1.首字母大寫&#xff0c;其余小寫 2.首字…

外網IP和內網ip的區別

首先得先知道什么是ip地址&#xff0c;它就是唯一標識連接網絡的設備的&#xff0c;即IP地址充當了設備在網絡中的“住址”&#xff0c;使得設備能夠相互通信和交換數據。 我們常聽開發人員說外網內網&#xff0c;那么它們有什么區別呢&#xff1f; 外網可以理解為互聯網&…

RT-Thread Sensor框架使用 - 1

RT-Thread Sensor框架使用 - 1 簡介Sensor框架結構函數說明rt_device_findrt_device_openrt_device_read 簡介 使用氣體傳感器&#xff0c;對接到sensor框架中使用。 Sensor框架結構 device框架 --》sensor框架 --》具體的設備 函數說明 rt_device_find 查找設備時的名稱…

【Docker】從零開始:6.配置鏡像加速器

【Docker】從零開始&#xff1a;5.配置鏡像加速器 什么是鏡像加速器&#xff1f;為什么要配置docker鏡像加速器?常見的Docker鏡像加速器有哪些&#xff1f;如何申請Docker鏡像加速器如何配置Docker鏡像加速器 什么是鏡像加速器&#xff1f; 鏡像加速器是一個位于Docker Hub之…

vue2.x中使用JS與路由守衛配置、vue2.x中使用TS與路由守衛的配置和vuex的配置以及TS在vue2.x中的使用說明

vue2.x 事件修飾符 <button click.stop.self"handleDelete(item)"></button>在使用 $confirm 時&#xff0c;使用 await 方式時&#xff0c;需要添加 catch 回調&#xff0c;否則無法獲取 $confirm 關閉和取消時的標識值&#xff0c;并且后續代碼停止執…

騰訊微服務平臺TSF學習筆記(二)--如何使用spring cloud zuul實現線上流量復制

需求提了n遍了&#xff0c;好好好&#xff0c;那這個需求就由我測試來做 1.在zuul端配置&#xff1a; ●假設provider-mirror是provider-demo的灰度應用 package com.tencent.tsf.msgw.zuul1.filter;import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.Re…

北航計算機學院 嵌入式系統實驗踩坑

今天上課在實驗室配置交叉編譯環境時&#xff0c;用機房的電腦一次就配成功了&#xff0c;但是下課后用自己的電腦裝了一個虛擬機安裝了Ubuntu 22.04系統&#xff0c;卻怎樣也配不成功&#xff0c;后面仔細閱讀文檔才發現&#xff0c;交叉編譯環境arm-linux-gcc居然是32位的&am…

PHP反序列化簡單使用

注&#xff1a;比較簡陋&#xff0c;僅供參考。 編寫PHP代碼&#xff0c;實現反序列化的時候魔法函數自動調用計算器 PHP反序列化 serialize(); 將對象序列化成字符串 unserialize(); 將字符串反序列化回對象 創建類 class Stu{ public $name; public $age; public $sex; publi…

智慧儲能邊緣計算網關應用,提升能源效率

智慧儲能通過邊緣計算網關物聯網技術來實現對儲能電池等設備的在線監控和遠程管理。邊緣計算網關可以將儲能數據轉化為可用的信息&#xff0c;并傳輸到儲能系統中&#xff0c;為儲能管理提供優化與調度等數據支持。 邊緣計算網關在智慧儲能系統中起到了關鍵的作用。IR4000邊緣計…

NSAttributedString設置折行方式NSLineBreakByTruncatingTail,計算高度出錯,高度返回異常。

iOS13上&#xff0c;NSAttributedString設置折行方式NSLineBreakByTruncatingTail&#xff0c;計算高度出錯&#xff0c;只返回一行的高度。 NSMutableParagraphStyle *style [[NSMutableParagraphStyle alloc]init]; style.hyphenationFactor 1; // 設置每行的最后單詞是…

探究Kafka原理-1.初識Kafka

&#x1f44f;作者簡介&#xff1a;大家好&#xff0c;我是愛吃芝士的土豆倪&#xff0c;24屆校招生Java選手&#xff0c;很高興認識大家&#x1f4d5;系列專欄&#xff1a;Spring源碼、JUC源碼、Kafka原理&#x1f525;如果感覺博主的文章還不錯的話&#xff0c;請&#x1f44…

音視頻項目—基于FFmpeg和SDL的音視頻播放器解析(十九)

介紹 在本系列&#xff0c;我打算花大篇幅講解我的 gitee 項目音視頻播放器&#xff0c;在這個項目&#xff0c;您可以學到音視頻解封裝&#xff0c;解碼&#xff0c;SDL渲染相關的知識。您對源代碼感興趣的話&#xff0c;請查看基于FFmpeg和SDL的音視頻播放器 如果您不理解本…

Postman API Enterprise 10.18.1 Crack

適合您企業的 Postman API 平臺 掌控您的 API 環境。構建更好的 API。加快產品開發。 無論您處于 API 之旅的哪個階段&#xff0c;Postman 都會為您提供幫助 想讓您團隊的 API 更容易被發現嗎&#xff1f;希望減少開發和質量檢查之間的滯后時間&#xff1f;想要更快地讓新開發…