基於Avalonia 11.0.0+ReactiveUI 的跨平臺項目開發1-通用框架

来源:https://www.cnblogs.com/raok/archive/2023/07/17/17560854.html
-Advertisement-
Play Games

# 基於Avalonia 11.0.0+ReactiveUI 的跨平臺項目開發1-通用框架 ### Avalonia簡介: Avalonia是.NET的一個跨平臺UI框架,提供了一個靈活的樣式系統,支持廣泛的操作系統,如Windows、Linux、macOS,並對Android、iOS和WebAss ...


基於Avalonia 11.0.0+ReactiveUI 的跨平臺項目開發1-通用框架

Avalonia簡介:

Avalonia是.NET的一個跨平臺UI框架,提供了一個靈活的樣式系統,支持廣泛的操作系統,如Windows、Linux、macOS,並對Android、iOS和WebAssembly提供了實驗性支持。

為什麼使用Avalonia:

之前已經瞭解了基於Avalonia的項目在國產麒麟系統中運行的案例。正是Avalonia在跨平臺的出色表現,學習和瞭解Avalonia這個UI框架顯得十分有必要。本項目採用的是最新穩定版本11.0.0-rc1.1。希望通過該項目瞭解和學習Avalonia開發的朋友可以在我的github上拉取代碼,同時希望大家多多點點star。

https://github.com/raokun/TerraMours.Chat.Ava

項目需求:

Web端的AI應用我已經開發了一個AI聊天平臺了。希望開發一個跨平臺的AI聊天和其他功能的客戶端平臺。有個面試邀請是要求avalonia應用經驗要求。寫這樣一個項目來學習和瞭解Avalonia。同時麒麟系統的開放版本也發佈了也想後面部署一個將這個項目部署在openKylin 1.0 的系統上。

開發環境:

.net 7

篇幅有限,創建項目的部分跳過,需要瞭解的可以看我之前的基礎博客:https://www.raokun.top/archives/chuang-jian-avalonia-mo-ban-xiang-mu---ji-chu

下麵我會直接以TerraMours.Chat.Ava項目為例子 來介紹項目開發過程和各技術的應用

1.nuget包引用

image-20230717150959484

引用包介紹:

  • Avalonia 版本11.0.0-rc1.1,穩定版本,其他基於avalonia的包要選用支持11.0.0-rc1.1的版本

  • Avalonia.ReactiveUI MVVM 架構模式的工具庫,創建avalonia項目時會提示選擇。

  • DialogHost.Avalonia 它提供了一種簡單的方式來顯示帶有信息的對話框或在需要信息時提示用戶。

  • FluentAvaloniaUI UI庫,並將更多WinUI控制項引入Avalonia

  • System.Data.SQLite 本地資料庫SQLite

  • CsvHelper Csv導入導出工具庫

  • Markdown.Avalonia 用於顯示markdown文本的工具,用於展示聊天結果的渲染

  • Betalgo.OpenAI 調用ChatGpt的擴展庫

<PackageReference Include="Avalonia" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.0-rc1.1" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.Xaml.Interactivity" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.0.0-rc1.1" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.0.0-rc1.1" />
<PackageReference Include="DialogHost.Avalonia" Version="0.7.4" />
<PackageReference Include="FluentAvaloniaUI" Version="2.0.0-rc1" />
<PackageReference Include="System.Data.SQLite" Version="1.0.117" />
<PackageReference Include="CsvHelper" Version="30.0.1" />
<PackageReference Include="Markdown.Avalonia" Version="11.0.0-d1" />
<PackageReference Include="Markdown.Avalonia.SyntaxHigh" Version="11.0.0-d1" />
<PackageReference Include="Markdown.Avalonia.Tight" Version="11.0.0-d1" />
<PackageReference Include="Betalgo.OpenAI" Version="7.1.2-beta" />

2.功能介紹

項目開發的功能分為如下:

1.通用框架:

  • VMLocator: ViewModel 定位器。方便地獲取和管理 ViewModel 實例,從而實現界面和數據的解耦和模塊化,提高代碼的可維護性和可測試性。
  • 國際化: 使用 CultureInfo.CurrentCulture 來實現多語言支持和本地化
  • 本地化數據:通過SQLite實現數據本地化
  • CSV導入導出:實現數據的遷移和補充
  • 自定義快捷鍵: 自定義快捷鍵,方便操作。發揮客戶端的按鍵優勢。
  • 自定義字體
  • 全局樣式

2.界面交互

  • LoadView.axaml 載入界面:系統打開時候的載入界面,用於首頁替換的技術實踐。可改造成登陸界面。
  • MainWindow.axaml 首頁
  • MainView.axaml 主界面
  • DataGridView.axaml 會話列表
  • ChatView.axaml 聊天界面
  • ApiSettingsView.axaml API配置

3.功能開發

1.通用功能開發

1.VMLocator ViewModel 定位器

VMLocator 類在 Avalonia 項目中的作用是作為一個靜態的 ViewModel 定位器,用於管理和提供各個 ViewModel 類的實例。ViewModel 是 MVVM 模式中用於處理界面邏輯和數據的類,而 ViewModel 定位器則負責管理 ViewModel 的實例,供界面進行數據綁定和交互。

優點:
  1. 提供了一種集中管理 ViewModel 的機制,使得整個應用程式可以方便地訪問和使用各個 ViewModel 實例。
  2. 通過使用靜態屬性和延遲初始化的方式,避免了頻繁創建 ViewModel 實例的開銷,提高了程式的性能和效率。
  3. 可以在需要的時候動態獲取 ViewModel 實例,而不需要手動實例化 ViewModel 類。
  4. 可以在不同的界面和組件之間共用同一個 ViewModel 實例,實現數據的共用和一致性
1.創建資源類VMLocator

image-20230717153901312

2.註入資源

app.axaml.cs中OnFrameworkInitializationCompleted方法加入

var VMLocator = new VMLocator();
Resources.Add("VMLocator", VMLocator);

image-20230717153945682

2.國際化

1.添加不同語言的資源文件
1.創建個語言的資源文件

image-20230717160806336

2.文件內容

image-20230717160909481

代碼如下:

<ResourceDictionary xmlns="https://github.com/avaloniaui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
					xmlns:system="clr-namespace:System;assembly=System.Runtime">
    <!-- Add Resources Here -->
	<system:String x:Key="My.Strings.ConversationHitoryInfo">
		"conversation history limit" is a client option, not an API parameter.
		When the set value (tokens) is exceeded,
		the conversation history will be automatically summarized.
	</system:String>
</ResourceDictionary>

資源文件中定義了各個配置的說明文本的內容,通過使用 CultureInfo.CurrentCulture 來實現多語言支持和本地化

2.添加Application.Resources

App.axaml中添加資源文件配置

image-20230717161135925

<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceInclude Source="/Assets/lang/zh-CN.axaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
3.添加AvaloniaXaml

在csproj中添加AvaloniaXaml

image-20230717161801378

<AvaloniaXaml Update="Assets\lang\zh-CN.axaml">
    <SubType>Designer</SubType>
</AvaloniaXaml>
什麼是AvaloniaXaml:

AvaloniaXaml 是 Avalonia 框架中用於定義用戶界面的 XAML 格式。它具有以下作用和特點:

作用:

  1. 聲明式定義用戶界面:AvaloniaXaml 允許開發人員使用 XAML 標記語言來聲明用戶界面的結構和外觀。它提供了一種簡潔、可讀性強的方式來描述應用程式的用戶界面。
  2. 分離視圖與邏輯:通過使用 AvaloniaXaml,開發人員可以將用戶界面的定義與應用程式的邏輯代碼進行分離。這種分離可以提高代碼的組織性、可維護性和可測試性。
  3. 支持樣式和模板:AvaloniaXaml 提供了強大的樣式和模板機制,使開發人員能夠輕鬆地定製和重用用戶界面的外觀和行為。這樣,可以實現更靈活和可擴展的界面設計。
4.自動判斷語言

通過CultureInfo.CurrentCulture 實現系統隨機器的語言系統自動切換顯示語言實現國際化配置。

CultureInfo.CurrentCulture 是一個表示當前線程所使用的區域設置(Culture)的屬性。它提供了關於當前文化信息(如語言、國家/地區、日期和時間格式等)的訪問和管理。

在MainWindow的構造函數中添加

image-20230717162806170

代碼如下:

 var cultureInfo = CultureInfo.CurrentCulture;
if (cultureInfo.Name == "zh-CN") {
    Translate("zh-CN");
}
Translate 方法

image-20230717162923588

代碼如下:

#region 國際化
    public void Translate(string targetLanguage) {
    var translations = App.Current.Resources.MergedDictionaries.OfType<ResourceInclude>().FirstOrDefault(x => x.Source?.OriginalString?.Contains("/Lang/") ?? false);

    if (translations != null)
        App.Current.Resources.MergedDictionaries.Remove(translations);

    App.Current.Resources.MergedDictionaries.Add(
        (ResourceDictionary)AvaloniaXamlLoader.Load(
            new Uri($"avares://TerraMours.Chat.Ava/Assets/lang/{targetLanguage}.axaml")
        )
    );
}
#endregion

3.本地化數據

本地化數據採用了SQLite本地資料庫,直接使用SQLite,用sql查詢,簡單高效,但是需要開發人員對sql的瞭解程度高。當然,也可以其他ORM框架調用SQLite。

1.SQLite特點

SQLite 是一種嵌入式關係型資料庫管理系統(RDBMS),有以下優點,這些優點也是為什麼客戶端廣泛使用它的原因:

  1. 簡單易用:SQLite 的設計目標之一是簡化資料庫系統的使用和管理。它有一個簡潔的操作介面,易於學習和使用,無需繁瑣的配置和管理步驟。因此,開發人員可以很快上手並快速開發出功能豐富的應用程式。
  2. 無伺服器架構:與大多數資料庫管理系統不同的是,SQLite 是一個無伺服器的資料庫引擎,資料庫以一個文件的形式存儲在磁碟上。這種架構使得 SQLite 的部署和維護變得非常簡單,不需要安裝和配置額外的伺服器。
  3. 輕量級和高性能:由於 SQLite 的設計目標是資源消耗低、性能高效,它被認為是一個輕量級的資料庫引擎。SQLite 資料庫文件通常較小,並且可以在資源受限的環境中快速運行。同時,SQLite 使用了精簡的 SQL 語法和優化技術,提供了快速的查詢和高效的數據讀寫性能。
  4. 跨平臺支持:SQLite 是一個跨平臺資料庫引擎,可以在多種操作系統上運行,包括 Windows、Linux、macOS 和嵌入式系統等。這種跨平臺的特性使得開發人員可以方便地在不同的環境中使用 SQLite,並輕鬆共用和遷移資料庫文件。
  5. 高度可移植:SQLite 資料庫文件是獨立於操作系統和硬體的二進位文件,可以在不同的平臺之間自由傳輸和共用。這種可移植性使得 SQLite 成為一個理想的選擇,特別是在需要在不同系統之間進行數據共用或遷移的情況下。
  6. ACID 事務支持:SQLite 支持事務處理和完整性約束,遵循 ACID(原子性、一致性、隔離性和持久性)原則。這意味著開發人員可以使用 SQLite 進行可靠的數據處理,並確保數據的正確性和一致性。
2.創建資料庫操作類 DatabaseProcess
1.資料庫連接
using var connection = new SQLiteConnection($"Data Source={AppSettings.Instance.DbPath}");
2.創建表和索引

image-20230717164117157

代碼如下:

public void CreateDatabase() {
            using var connection = new SQLiteConnection($"Data Source={AppSettings.Instance.DbPath}");
            string sql = "CREATE TABLE phrase (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL DEFAULT '', phrase TEXT NOT NULL DEFAULT '');";

            using var command = new SQLiteCommand(sql, connection);
            // phrase創建表格
            connection.Open();
            command.ExecuteNonQuery();

            // phrase索引
            sql = "CREATE INDEX idx_text ON phrase (phrase);";
            command.CommandText = sql;
            command.ExecuteNonQuery();
}
3.查詢列表(例)

image-20230717164249204

代碼如下:

public async Task<List<string>> GetPhrasesAsync() {
    List<string> phrases = new List<string>();
    string sql = "SELECT name FROM phrase ORDER BY name COLLATE NOCASE";

    using (var command = new SQLiteCommand(sql, memoryConnection)) {
        using var reader = await command.ExecuteReaderAsync();
        while (await reader.ReadAsync()) {
            phrases.Add(reader.GetString(0));
        }
    }
    return phrases;
}
4.新增(例)

image-20230717164637454

public async Task SavePhrasesAsync(string name, string phrasesText) {
    using var connection = new SQLiteConnection($"Data Source={AppSettings.Instance.DbPath}");
    await connection.OpenAsync();

    using var transaction = connection.BeginTransaction();
    try {
        string sql = $"INSERT INTO phrase (name, phrase) VALUES (@name, @phrase)";

        using var command = new SQLiteCommand(sql, connection);
        command.Parameters.AddWithValue("@name", name);
        command.Parameters.AddWithValue("@phrase", phrasesText);

        await command.ExecuteNonQueryAsync();

        transaction.Commit();
    }
    catch (Exception) {
        transaction.Rollback();
        throw;
    }
    await memoryConnection.CloseAsync();
    await DbLoadToMemoryAsync();
}

4.CSV導入導出

通過CsvHelper實現數據的導入導出

1.選擇文件

彈出選擇文件框,限制文件類型為CSV

image-20230717165356117

代碼如下:

private async Task ImportChatLogAsync() {
    var dialog = new FilePickerOpenOptions {
        AllowMultiple = false,
        Title = "Select CSV file",
        FileTypeFilter = new List<FilePickerFileType>
        {new("CSV files (*.csv)") { Patterns = new[] { "*.csv" } },
         new("All files (*.*)") { Patterns = new[] { "*" } }}
    };

    var result = await (Application.Current!.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)!.MainWindow!.StorageProvider.OpenFilePickerAsync(dialog);

    if (result.Count > 0) {
        var selectedFilePath = result[0].Path.LocalPath;
        try {
            var msg = await _dbProcess.ImportCsvToTableAsync(selectedFilePath);
            var cdialog = new ContentDialog() { Title = msg, PrimaryButtonText = "OK" };
            await ContentDialogShowAsync(cdialog);
        }
        catch (Exception ex) {
            var cdialog = new ContentDialog() { Title = "Failed to import log." + Environment.NewLine + "Error: " + ex.Message, PrimaryButtonText = "OK" };
            await ContentDialogShowAsync(cdialog);
        }
        VMLocator.DataGridViewModel.ChatList = await _dbProcess.SearchChatDatabaseAsync();
    }
}
2.導入到資料庫

CSV從文件導入數據,跳過標題行,取得數據,將數據插入資料庫

image-20230717165224366

代碼如下:

 // CSV從文件導入數據
using var reader = new StreamReader(fileName, System.Text.Encoding.UTF8);
var config = new CsvConfiguration(CultureInfo.InvariantCulture) {
    HasHeaderRecord = true,
    Delimiter = ","
};
using var csvReader = new CsvReader(reader, config);
csvReader.Read(); // 跳過標題行

using var con = new SQLiteConnection($"Data Source={AppSettings.Instance.DbPath}");
await con.OpenAsync();
using (var transaction = con.BeginTransaction()) {
    try {
        while (await csvReader.ReadAsync()) // 導入數據行
        {

            // 數據取得
            var rowData = new List<string>();
            for (int i = 1, loopTo = columnEnd; i <= loopTo; i++) // 從第二排到第八排
                rowData.Add(csvReader.GetField(i));
            // 創建插入語句
            string values = string.Join(", ", Enumerable.Range(0, rowData.Count).Select(i => $"@value{i}"));

            string insertQuery = $"INSERT INTO {tableName} ({columnNames}) VALUES ({values});";

            // 將數據插入資料庫
            using (var command = new SQLiteCommand(insertQuery, con)) {
                for (int i = 0, loopTo1 = rowData.Count - 1; i <= loopTo1; i++)
                    command.Parameters.AddWithValue($"@value{i}", rowData[i]);
                await command.ExecuteNonQueryAsync();
            }
            processedCount += 1;
        }

        transaction.Commit();
        msg = $"Successfully imported log. ({processedCount} Records)";
    }
    catch (Exception) {
        transaction.Rollback();
        throw;
    }
}
await con.CloseAsync();

5.自定義快捷鍵

1.CustomNumericUpDown
  1. 提供了一種自定義的 NumericUpDown 控制項,可以用於在用戶界面中顯示和編輯數字值。NumericUpDown 控制項通常用於允許用戶輸入數值或選擇數值的場景。
  2. 通過重寫 OnApplyTemplate 方法,該類可以在控制項的模板應用後,獲取到控制項內部的 TextBox 控制項,並訂閱其 KeyDown 事件。
  3. 在 TextBox_KeyDown 事件處理程式中,實現了自定義的鍵盤輸入邏輯,只允許在 TextBox 中輸入數字、小數點以及一些控制鍵。
  4. 在 DetachedFromVisualTree 事件中,清理了事件的訂閱,以避免記憶體泄漏。
  5. 通過實現 IStyleable 介面,可以定義該控制項的樣式(StyleKey)。

image-20230717170706649

6.自定義字體

1.添加 AvaloniaResource

在csproj中添加

<AvaloniaResource Include="Assets\Lato-Regular.ttf" /> 
<AvaloniaResource Include="Assets\migu-1m-regular.ttf" />
2.設置控制項對應的字體

image-20230717171046642

<Style Selector="TextBlock">
    <Setter Property="FontFamily" Value="avares://TmCGPTD/Assets/Lato-Regular.ttf#Lato" />
    <Setter Property="Foreground" Value="rgb(220, 220, 220)" />
</Style>

7.全局樣式

1.添加Styles.axaml

Styles.axaml的作用是全局定義樣式,控制整個系統的樣式風格

image-20230717172307513

2.Application.Styles

app.axaml中添加

image-20230717172420489

代碼如下:

<Application.Styles>
    <StyleInclude Source="avares://TerraMours.Chat.Ava/Assets/Styles.axaml" />
</Application.Styles>
3.添加AvaloniaResource

csproj添加AvaloniaResource

  <ItemGroup>
	<AvaloniaResource Include="Assets\Styles.axaml" />
  </ItemGroup>

項目截圖:

image-20230717163231985

篇幅有限,功能開發部分請跳轉下篇

基於Avalonia 11.0.0+ReactiveUI 的跨平臺項目開發2-功能開發

閱讀如遇樣式問題,請前往個人博客瀏覽: https://www.raokun.top
擁抱ChatGPT:https://ai.terramours.site
開源項目地址:https://github.com/raokun/TerraMours.Chat.Ava

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • CheckStyle作為檢驗代碼規範的插件,除了可以使用配置預設給定的開發規範,如Sun的,Google的開發規範啊,也可以導入像阿裡的開發規範的插件。 事實上,每一個公司都存在不同的開發規範要求,所以大部分公司會給定自己的check規範,一般導入給定的 checkstyle.xml 文件即可實現。 ...
  • # AbstractJsonUserAttributeMapper 它是一個抽象類,用來更新條件更新用戶屬性(user_attribute)的信息,我們在實現自己的mapper時,需要關註3個方法,下麵分別介紹一下: ## getCompatibleProviders方法 它用來直指你的mapper ...
  • # 構造方法參數Autowire - BeanClass可以在構造方法上標註@Autowired註解,Spring在創建Bean實例時將自動為其註入依賴參數 - Spring會優先使用標註@Autowired註解的構造方法 - 當一個構造方法標註了@Autowired註解且required=true ...
  • 在 Maven 中,`-SNAPSHOT` 尾碼是用於標識項目版本為快照(Snapshot)版本的約定。快照版本是處於開發和演進中的版本,通常用於開發人員在`構建和測試過程中進行頻繁的版本迭代`;反之,如果不是Snapshot尾碼的包,例如v1.1.0,這說明它是一個相對穩定的版本了,這個版本一經發 ...
  • ## 教程簡介 JFreeChart是JAVA平臺上的一個開放的圖表繪製類庫。它完全使用JAVA語言編寫,是為applications, applets, servlets 以及JSP等使用所設計。JFreeChart可生成餅圖(pie charts)、柱狀圖(bar charts)、散點圖(sca ...
  • ## 教程簡介 cPanel虛擬主機管理系統提供一個簡單但卻非常直觀的圖形化界面來幫助伺服器管理人員管理伺服器。伺服器管理人員可以通過cPanel虛擬主機管理系統的EasyApache功能來進行Apache的編譯,輕鬆選擇想要載入的模塊,整個編譯過程十分簡單,從而避免了從命令行來進行編譯的繁瑣。 c ...
  • 瞭解一下線程模型還是很有必要的,如果不清楚語言層面上的線程在操作系統層面怎麼映射使用,在使用過程中就會不清不楚,可能會踩一些坑 ...
  • ## 引言 **yield**關鍵字是 C# 中的一種語言特性,用於在枚舉器中簡化迭代器的實現。它使得開發人員可以通過定義自己的迭代器來簡化代碼,而不必手動實現 IEnumerable 和 IEnumerator 介面。 使用 `yield` 關鍵字,可以將迭代器中的值一次一個地返回,而不必使用一個 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...