【安卓筆記】RxJava的使用+修改功能+搭配retrofit+RxView防快速點擊

0. 環境:

電腦:Windows10

Android Studio: 2024.3.2

編程語言: Java

Gradle version:8.11.1

Compile Sdk Version:35

Java 版本:Java11

1. 介紹RxJava

GitHub開源地址:https://github.com/ReactiveX/RxJava

依賴庫:(兩個都要)

implementation "io.reactivex.rxjava3:rxjava:3.1.10"

implementation "io.reactivex.rxjava3:rxandroid:3.0.2"

Rx即為響應式思想。GitHub上、網絡上已經有很多介紹了。這邊不贅述。

2. 使用RxJava加載圖片案例

功能拆解:

1. 獲得圖片地址
2. 拿到圖片地址后,下載圖片。2.1下載為耗時操作,需要loading框2.2 通過網絡請求,下載圖片
3. 下載完成后,dismiss loading,并且使用imageView顯示出來3.1 隱藏loading框3.2 imageView setImage

根據這個功能,來寫代碼:(了解觀察者、被觀察者、整條邏輯鏈路)

String PATH = "https://c-ssl.dtstatic.com/uploads/blog/202405/03/73SmDPGxIeB0Gel.thumb.1000_0.jpg"; // 圖片地址
ProgressDialog progressDialog; //loading可以改為自定義的loading框
public void rxJavaDownloadImage() {// observable 為被觀察者。被觀察者為圖片地址StringObservable.just(PATH)// 拿到圖片地址后,通過網絡請求下載圖片.map(new Function<String, Bitmap>() {@Overridepublic Bitmap apply(String s) throws Throwable {// 網絡下載圖片URL url = new URL(PATH);HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();httpURLConnection.setConnectTimeout(5000);int responseCode = httpURLConnection.getResponseCode();if (responseCode == HttpURLConnection.HTTP_OK) {InputStream inputStream = httpURLConnection.getInputStream();Bitmap bitmap = BitmapFactory.decodeStream(inputStream);return bitmap;} else {Log.i("TAG", "apply: " + responseCode);}return null;}}).subscribeOn(Schedulers.io()) //切換到子線程.observeOn(AndroidSchedulers.mainThread()) // 將觀察者,切換到主線程.subscribe(// observer為觀察者,觀察上一個動作結束時的結果new Observer<Bitmap>() {//訂閱剛開始時@Overridepublic void onSubscribe(@NonNull Disposable d) {//加載loading框progressDialog = new ProgressDialog(getActivity());progressDialog.setTitle("downloading...");progressDialog.show();}// 獲取到上個事件的結果時@Overridepublic void onNext(@NonNull Bitmap bitmap) {// imageView setBitmapbinding.imageView.setImageBitmap(bitmap);}// 出現錯誤時@Overridepublic void onError(@NonNull Throwable e) {// 如果出現錯誤,則顯示裂開圖片 error.pngif (progressDialog != null) {progressDialog.dismiss();}Log.i("----log----", "onError: ");e.printStackTrace();}// 事件結束時@Overridepublic void onComplete() {// 隱藏loading框if (progressDialog != null) {progressDialog.dismiss();}}});
}

我們再來回顧一下剛剛拆解的功能:

// 這邊設置成常量PATH,實際應用中為變量
// Observable.just(PATH) 傳遞給下一個卡片String對象
1. 獲得圖片地址。// 在 .map(new Function<String, Bitmap>() 中操作,并且傳遞給下一個卡片bitmap對象
2. 拿到圖片地址后,下載圖片。// 這邊使用ProgressDialog,實際應用中,會使用自定義UI// 在onSubscribe中操作,即訂閱開始時2.1下載為耗時操作,需要loading框// 這邊使用HttpURLConnection,實際應用中,會使用網絡框架2.2 通過網絡請求,下載圖片// 在 subscribe中,new Observer<Bitmap>()新建一個觀察者,用于觀察上一個卡片給的bitmap對象
3. 下載完成后,dismiss loading,并且使用imageView顯示出來// 在onComplete中操作,即事件完成時、事件結束時。3.1 隱藏loading框// 這邊使用了binding來操作:binding.imageView.setImageBitmap(bitmap);詳情請框ViewBinding框架// 在onNext中操作,即拿到上一張卡片給的bitmap對象3.2 imageView setImage

當然,代碼中的方法:rxJavaDownloadImage(),我們通過按鈕的點擊事件來實現就好了。

這樣,就完成了RxJava來加載圖片的簡單功能。

3. RxJava的修改案例

僅僅只是使用,還不夠。

3.1 增加需求時的修改(了解.map)

此時有一個新需求:需要給圖片增加水印。又該如何修改呢?

功能拆解

1. 獲得圖片地址
2. 拿到圖片地址后,下載圖片。2.1下載為耗時操作,需要loading框2.2 通過網絡請求,下載圖片
3. 下載完成后,dismiss loading,3.1 隱藏loading框
4. 給圖片設置水印,并且使用imageView顯示出來 //顯示圖片之前,增加“設置水印”的動作4.1 設置水印 //增加設置水印的動作4.2 imageView setImage

增加水印的功能,只需要在下載完圖片后,插入“給圖片增加水印”的map即可

// 增加水印的卡片
.map(new Function<Bitmap, Bitmap>() {@Overridepublic Bitmap apply(Bitmap bitmap) throws Throwable {// 在這里增加自定義的水印Paint paint = new Paint();paint.setTextSize(88);paint.setColor(Color.RED);return drawTextToBitmap(bitmap, "水印設置", paint, 88, 88);}
})

?完整代碼如下:

    String PATH = "https://c-ssl.dtstatic.com/uploads/blog/202405/03/73SmDPGxIeB0Gel.thumb.1000_0.jpg"; // 圖片地址ProgressDialog progressDialog; //loading可以改為自定義的loading框public void rxJavaDownloadImage() {// observable 為被觀察者。被觀察者為圖片地址StringObservable.just(PATH)// 拿到圖片地址后,通過網絡請求下載圖片.map(new Function<String, Bitmap>() {@Overridepublic Bitmap apply(String s) throws Throwable {// 網絡下載圖片URL url = new URL(PATH);HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();httpURLConnection.setConnectTimeout(5000);int responseCode = httpURLConnection.getResponseCode();if (responseCode == HttpURLConnection.HTTP_OK) {InputStream inputStream = httpURLConnection.getInputStream();Bitmap bitmap = BitmapFactory.decodeStream(inputStream);return bitmap;} else {Log.i("TAG", "apply: " + responseCode);}return null;}})// 增加水印的卡片.map(new Function<Bitmap, Bitmap>() {@Overridepublic Bitmap apply(Bitmap bitmap) throws Throwable {// 在這里增加自定義的水印Paint paint = new Paint();paint.setTextSize(88);paint.setColor(Color.RED);return drawTextToBitmap(bitmap, "水印設置", paint, 88, 88);}}).subscribeOn(Schedulers.io()) //切換到子線程.observeOn(AndroidSchedulers.mainThread()) // 將觀察者,切換到主線程.subscribe(// observer為觀察者,觀察上一個動作結束時的結果new Observer<Bitmap>() {//訂閱剛開始時@Overridepublic void onSubscribe(@NonNull Disposable d) {//加載loading框progressDialog = new ProgressDialog(getActivity());progressDialog.setTitle("downloading...");progressDialog.show();}// 獲取到上個事件的結果時@Overridepublic void onNext(@NonNull Bitmap bitmap) {// imageView setBitmapbinding.imageView.setImageBitmap(bitmap);}// 出現錯誤時@Overridepublic void onError(@NonNull Throwable e) {// 如果出現錯誤,則顯示裂開圖片 error.pngif (progressDialog != null) {progressDialog.dismiss();}Log.i("----log----", "onError: ");e.printStackTrace();}// 事件結束時@Overridepublic void onComplete() {// 隱藏loading框if (progressDialog != null) {progressDialog.dismiss();}}});}/*** 增加水印的函數。(不是這篇文章的重點)* @return bitmap*/public static Bitmap drawTextToBitmap(Bitmap bitmap,String gText,Paint paint,int x,int y) {android.graphics.Bitmap.Config bitmapConfig =bitmap.getConfig();if(bitmapConfig == null) {bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;}bitmap = bitmap.copy(bitmapConfig, true);Canvas canvas = new Canvas(bitmap);Rect bounds = new Rect();paint.getTextBounds(gText, 0, gText.length(), bounds);canvas.drawText(gText, x, y, paint);return bitmap;}

我們可以發現:需要增加功能,僅僅只需要在該鏈路中增加一個.map來修改,完全不會破壞原有的代碼邏輯。而且該map也可以直接復制到其他代碼去使用。這個就是優勢了

3.2 封裝相同代碼(了解ObservableTransformer)

我們發現,每一條邏輯都會包含線程切換。相同代碼比較多。我們可以將其進行封裝

引入一個ObservableTransformer<Upstream, Downstream>對象

?查閱源碼發現,ObservableTransformer 需要compose接口來調用。

Upstream:上游

Downstream:下游

所以,我們可以封裝代碼:

private final static <UD>ObservableTransformer<UD, UD> rxud() {return new ObservableTransformer<UD, UD>() {@Overridepublic @NonNull ObservableSource<UD> apply(@NonNull Observable<UD> upstream) {return upstream.subscribeOn(Schedulers.io()) //切換到子線程.observeOn(AndroidSchedulers.mainThread()) // 將觀察者,切換到主線程;.map(new Function<UD, UD>() {@Overridepublic UD apply(UD ud) throws Throwable {// 甚至可以增加日志功能,此處為偽代碼System.out.println("圖片下載的時間" + System.currentTimeMillis());return ud;}});}};
}

可以看到return返回值 就是上游切換為子線程,下游切換為主線程。同時,我甚至可以在封裝代碼中,增加“日志功能”的卡片。這樣每次下載圖片的時間,都會被記錄到日志當中。

要如何使用封裝代碼呢?使用.compose(rxud())即可。

請看下面的示例:

public void rxJavaDownloadImage() {// observable 為被觀察者。被觀察者為圖片地址StringObservable.just(PATH)// 拿到圖片地址后,通過網絡請求下載圖片.map(new Function<String, Bitmap>() {@Overridepublic Bitmap apply(String s) throws Throwable {// 網絡下載圖片URL url = new URL(PATH);HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();httpURLConnection.setConnectTimeout(5000);int responseCode = httpURLConnection.getResponseCode();if (responseCode == HttpURLConnection.HTTP_OK) {InputStream inputStream = httpURLConnection.getInputStream();Bitmap bitmap = BitmapFactory.decodeStream(inputStream);return bitmap;} else {Log.i("TAG", "apply: " + responseCode);}return null;}})// 增加水印的卡片.map(new Function<Bitmap, Bitmap>() {@Overridepublic Bitmap apply(Bitmap bitmap) throws Throwable {// 在這里增加自定義的水印Paint paint = new Paint();paint.setTextSize(88);paint.setColor(Color.RED);return drawTextToBitmap(bitmap, "水印設置", paint, 88, 88);}}).compose(rxud()) // 此處調用封裝代碼即可.subscribe(// observer為觀察者,觀察上一個動作結束時的結果new Observer<Bitmap>() {//訂閱剛開始時@Overridepublic void onSubscribe(@NonNull Disposable d) {//加載loading框progressDialog = new ProgressDialog(getActivity());progressDialog.setTitle("downloading...");progressDialog.show();}// 獲取到上個事件的結果時@Overridepublic void onNext(@NonNull Bitmap bitmap) {// imageView setBitmapbinding.imageView.setImageBitmap(bitmap);}// 出現錯誤時@Overridepublic void onError(@NonNull Throwable e) {// 如果出現錯誤,則顯示裂開圖片 error.pngif (progressDialog != null) {progressDialog.dismiss();}Toast.makeText(getActivity(), "download error", Toast.LENGTH_SHORT).show();Log.i("----log----", "onError: ");e.printStackTrace();}// 事件結束時@Overridepublic void onComplete() {// 隱藏loading框if (progressDialog != null) {progressDialog.dismiss();}}});}

這樣我們就學會了封裝代碼。

后續開發過程中,如果出現功能A:下載圖片、功能B:網絡請求、?功能C:上傳頭像,我們都可以通過調用封裝的代碼來實現線程切換。

4. 網絡請求替換成Retrofit

4.1 準備工作

依賴庫:

// retrofit 核心依賴

implementation "com.squareup.retrofit2:retrofit:3.0.0"

// json解析工具依賴

implementation "com.squareup.retrofit2:converter-gson:3.0.0"

// rxjava轉換處理工具

implementation "com.squareup.retrofit2:adapter-rxjava3:3.0.0"

項目api:即為網絡請求接口

例子1:不帶參數的網絡請求

https://wanandroid.com/project/tree/json

例子2:帶參數的網絡請求

https://wanandroid.com/project/list/1/json?cid=294

其中,1為pageIndex;cid=294為body參數

4.2 創建bean

這里我使用插件(GsonFormatPlus)生成。沒有安裝過的,需要在marketplace搜索安裝

?安裝完成后,新建一個bean的Java文件,然后按快捷鍵,快捷鍵是alt+s (win), option + s(mac)

粘貼進json數據后,(左下角Setting可以自定義格式)?點完成OK,就會自動生成bean的內容

4.3 創建NetApi接口

比較簡單,我直接貼代碼:

package com.liosen.androidnote.api;import com.liosen.androidnote.bean.ItemBean;
import com.liosen.androidnote.bean.ProjectBean;import io.reactivex.rxjava3.core.Observable;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;public interface NetApi {// https://wanandroid.com/project/tree/json// 其中base為 wanandroid.com/// 所以只需要后續部分即可@GET("project/tree/json")Observable<ProjectBean> getProject();// https://wanandroid.com/project/list/1/json?cid=294// 1為動態頁碼,通過@Path 傳參// cid為網址參數,通過@Query 傳參@GET("project/list/{pageIndex}/json")Observable<ItemBean> getProjectItem(@Path("pageIndex") int pageIndex, @Query("cid") int cid);
}

4.4 網絡工具類

通過okhttp來進行網絡請求。封裝成工具類即可。

以下代碼復制就好了。?

package com.liosen.androidnote.util;import com.google.gson.Gson;import java.util.concurrent.TimeUnit;import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;public class HttpUtils {public static String BASE_URL = "https://wanandroid.com/";public static Retrofit getOnlineCookieRetrofit() {OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder();OkHttpClient client = httpBuilder.readTimeout(15, TimeUnit.SECONDS).connectTimeout(15, TimeUnit.SECONDS).writeTimeout(15, TimeUnit.SECONDS).build();return new Retrofit.Builder().baseUrl(BASE_URL)// okhttp請求.client(client)// rxJava 處理// 添加一個json解析工具.addConverterFactory(GsonConverterFactory.create(new Gson()))// 添加 RxJava處理工具.addCallAdapterFactory(RxJava3CallAdapterFactory.create()).build();}
}

4.5 網絡請求

    /*** 獲取項目的網絡請求*/public void getProjectHttp() {netApi.getProject().compose(rxud()) // 此處用到 3.2中封裝的代碼.subscribe(new Consumer<ProjectBean>() {@Overridepublic void accept(ProjectBean projectBean) throws Throwable {Log.i(TAG, "accept: " + projectBean);}});}/*** 獲取item的網絡請求*/public void getProjectItemHttp() {//實際項目中,需要傳入這兩個參數。暫時先用常量表示getProjectItemHttp(1, 294);}public void getProjectItemHttp(int pageIndex, int cid) {netApi.getProjectItem(pageIndex,cid).compose(rxud()) // 此處用到 3.2中封裝的代碼//同理,如果還封裝了日志功能,此處一樣可以插入卡片// .map() 這樣插入即可。詳情查看3.1.subscribe(new Consumer<ItemBean>() {@Overridepublic void accept(ItemBean itemBean) throws Throwable {Log.i(TAG, "accept: " + itemBean);}});}

?其中Consumer觀察者為簡易觀察者,不像Observer一樣,需要實現以下四種方法:

onSubscribe

onNext

onError

onComplete

僅需要實現accept() 即可。等同于onNext?

5. 防快速點擊(RxJava實現)

5.1 依賴庫

implementation 'com.jakewharton.rxbinding4:rxbinding:4.0.0'

5.2 功能實現案例?

功能描述:點擊button,點擊事件觸發獲取項目信息的http

要求:防快速點擊(防手指抖動)避免服務器連續收到http請求

代碼關鍵部分:

// clicks 傳入view, 也就是button這個view。此處是使用viewBinding框架
// Button btn = findViewById(R.id.button); 此處傳入btn也是一樣的
RxView.clicks(binding.buttonRequest).throttleFirst(2000, TimeUnit.MILLISECONDS) //防抖動,2秒內只響應第1次.subscribe(new Consumer<Unit>() {//此處的Unit可以不用接收@Overridepublic void accept(Unit unit) throws Throwable {// 網絡請求,獲取項目http。與getProjectHttp() 函數一樣netApi.getProject().compose(rxud()).subscribe(new Consumer<ProjectBean>() {@Overridepublic void accept(ProjectBean projectBean) throws Throwable {Log.i(TAG, "accept: " + projectBean);// 此處可以通過獲得的projectBean,繼續請求Itemfor (ProjectBean.DataDTO data : projectBean.getData()) {getProjectItemHttp(1, data.getId());}}});}})
;

6. 寫在最后

至此,我們學會了:

修改RxJava的修改(增加卡片、刪除卡片)、

封裝操作線程代碼、

RxJava + Retrofit、

RxView實現防快速點擊。

以上功能,基本上可以在項目中使用了。

關于RxJava,可以查看我其他文章:

【安卓筆記】RxJava的使用+修改功能+搭配retrofit+RxView防快速點擊:https://blog.csdn.net/liosen/article/details/149340103

【安卓筆記】RxJava之flatMap的使用:https://blog.csdn.net/liosen/article/details/149343166

【安卓筆記】RxJava的onNextDo的使用:https://blog.csdn.net/liosen/article/details/149343321

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

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

相關文章

Windows 下原生使用 claude code + Kimi K2

搞定了kimi k2 claude code在windows下原生使用 Windows下使用claude code的障礙是shell環境&#xff08;命令行&#xff09;&#xff0c;非posix風格shell無法正常讓claude code讀取到url和key, 導致無法使用。解決問題的本質是使用符合posix風格的shell環境&#xff0c;我們…

Leetcode Easy題小解(C++語言描述)1

Leetcode Easy題小解&#xff08;C語言描述&#xff09; 相交鏈表 給你兩個單鏈表的頭節點 headA 和 headB &#xff0c;請你找出并返回兩個單鏈表相交的起始節點。如果兩個鏈表不存在相交節點&#xff0c;返回 null 。 圖示兩個鏈表在節點 c1 開始相交**&#xff1a;**題目數據…

EP01:【NLP 第二彈】自然語言處理概述

一、NLP通向智能之路 1.1 圖靈測試 1.1.1 提出背景 由計算機科學家阿蘭?圖靈于 1950 年提出&#xff0c;是早期衡量機器智能水平的重要概念。 1.1.2 提出目的 判斷機器是否能表現出與人類相當的智能行為。 1.1.3 測試原理 場景設定&#xff1a;測試中存在一位人類測試者&#…

Ansible 查看PostgreSQL的版本

Ansible的基礎知識就不說了直接貼劇本- name: Check PostgreSQL versionhosts: db_serversbecome: yesvars:ansible_python_interpreter: /usr/bin/python3db_name: postgresdb_user: postgresdb_password: your_passwordtasks:- name: Install psycopg2ansible.builtin.packag…

【視覺SLAM筆記】第9章 后端1

一、理論1. 狀態估計的概率解釋我們來深入探討一下視覺SLAM中狀態估計的概率解釋。這可以說是理解現代SLAM算法&#xff08;尤其是后端優化&#xff09;的基石1. 問題的核心&#xff1a;不確定性SLAM&#xff08;同步定位與建圖&#xff09;的本質是在一個未知環境中&#xff0…

(數據結構)復雜度

基本概念說明 數據結構 定義&#xff1a;數據結構(Data Structure)是計算機存儲、組織數據的方式&#xff0c;指相互之間存在?種或多種特定關系的數據元素的集合。沒有?種單?的數據結構對所有用途都有用&#xff08;要考慮適配、效率問題&#xff0c;在不同情況下使用合適的…

玩轉Docker | 使用Docker部署bender個人導航頁工具

玩轉Docker | 使用Docker部署bender個人導航頁工具 前言 一、bender介紹 Bender 簡介 Bender 的主要特點 二、系統要求 環境要求 環境檢查 Docker版本檢查 檢查操作系統版本 三、部署bender服務 下載bender鏡像 編輯部署文件 創建容器 檢查容器狀態 檢查服務端口 安全設置 四、…

解決了困擾我的upload靶場無法解析phtml等后綴的問題

本文章為解決困擾我的 upload 靶場無法解析 phtml 問題 ? 這個問題直接讓我過不了Upload-Pass-03這一關&#xff0c;一直卡著。 ? 痛太痛了 &#xff0c;為什么無法解析上傳之后的 phtml 后綴文件&#xff01;這塊兒折磨了博主一天多&#xff0c;太不容易了&#xff0c;查找…

Leetcode百題斬-二分搜索

二分搜索也是一個很有趣的專題&#xff0c;被做過的題中&#xff0c;剛好一個Easy&#xff0c;一個Medium和一個Hard&#xff0c;剛好可以看看&#xff0c;二分搜索的三個難度等級都是啥樣的。 124. Binary Tree Maximum Path Sum[Hard]&#xff08;詳見二叉樹專題&#xff09;…

【IDEA】格式化代碼工具配置

格式化代碼快捷鍵&#xff1a; CtrlAltL格式代碼的時候不會再方法名與參數中間添加空格默認不勾選的情況下&#xff1a;代碼樣例&#xff1a;勾選之后的樣例&#xff1a;選擇不勾選&#xff0c;IDEA默認情況下就是不勾選的狀態忽略加載文件有些非必要加載到開發工具中的文件我們…

驅動開發(3)|rk356x驅動GPIO基礎應用之點亮led燈

點亮LED燈看似是一個基礎的操作&#xff0c;但實際上&#xff0c;許多高級應用也依賴于高低電平的切換。例如&#xff0c;脈沖寬度調制&#xff08;PWM&#xff09;信號可以用來精確控制電機的轉速&#xff0c;通過改變脈沖的頻率和占空比&#xff0c;實現對電機的精確調節&…

手動搭建PHP環境:步步為營,解鎖Web開發

目錄一、引言二、準備工作2.1 明確所需軟件2.2 下載軟件三、Windows 系統搭建步驟3.1 安裝 Apache 服務器3.2 安裝 PHP3.3 集成 Apache 與 PHP3.4 安裝 MySQL3.5 配置 PHP 連接 MySQL四、Linux 系統搭建步驟&#xff08;以 Ubuntu 為例&#xff09;4.1 更新系統4.2 安裝 Apache…

DrissionPage:一款讓網頁自動化更簡單的 Python 庫

在網頁自動化領域&#xff0c;Selenium 和 Playwright 早已是開發者耳熟能詳的工具。但今天要給大家介紹一款更輕量、更易用的 Python 庫 ——DrissionPage。它以 "融合 selenium 和 requests 優勢" 為核心設計理念&#xff0c;既能像 requests 一樣高效處理靜態網頁…

理解Grafana中`X-Scope-OrgID`的作用與配置

X-Scope-OrgID的作用 該HTTP Header用于標識Loki日志數據的所屬租戶&#xff08;組織&#xff09;。在多租戶模式下&#xff0c;Loki通過此Header隔離不同團隊或用戶的數據&#xff0c;確保查詢和存儲的獨立性。數據隔離&#xff1a; 租戶A的日志標記為X-Scope-OrgID: team-a&a…

【PycharmPyqt designer桌面程序設計】

在 main.py 中調用 Qt Designer 生成的 windows.py&#xff08;假設它是 PySide2 版&#xff09;。 只要把兩個文件放在同一目錄即可直接運行。 ──────────────────── 1?? windows.py&#xff08;Qt Designer 生成&#xff0c;已轉碼&#xff09; # -*-…

Unity Android Logcat插件 輸出日志中文亂碼解決

背景之前安卓真機調試看日志&#xff0c;一直用的是Android Studio自帶的adb命令進行看日志&#xff0c;不太方便&#xff0c;改用Unity自帶的安卓日志插件時&#xff0c;存在中文日志亂碼問題。插件安裝基于Unity6000.1.11版本&#xff1a;Window -> Package Management -&…

Halcon雙相機單標定板標定實現拼圖

1.Halcon圖像拼接算法在之前的文章里也寫過&#xff0c;主要是硬拼接和特征點拼接兩種方式&#xff0c;今天增加另一種拼接圖像的方式。應用場景是多個相機聯合一起拍大尺寸的物體&#xff0c;并且相機視野之間存在重疊區域。通過在同一個標定板上面標定&#xff0c;計算兩個相…

動物世界一語乾坤韻芳華 人工智能應用大學畢業論文 -仙界AI——仙盟創夢IDE

提示詞在一個奇幻的童話森林里&#xff0c;所有的動物都像人類一樣直立行走&#xff0c;穿著各種搞怪的衣服。 一只戴著超大眼鏡、穿著背帶褲的烏龜&#xff0c;正一本正經地站在一個蘑菇舞臺上&#xff0c;拿著一根樹枝當作麥克風&#xff0c;準備唱歌。它的眼鏡總是往下滑&am…

SpringBoot(原理篇)

大家好&#xff0c;這里是 盛碼筆記。 本篇我們來聊一聊 Spring Boot 的“魔法”是如何實現的。你可能已經用過 Spring Boot 快速搭建項目&#xff0c;但有沒有想過&#xff1a;為什么只需要引入幾個 starter&#xff0c;Spring Boot 就能自動配置好整個應用環境&#xff1f; …

數據結構:棧(區間問題)

碼蹄集OJ-小碼哥的棧 #include<bits/stdc.h> using namespace std; #define int long long const int N1e67; struct MOOE {int ll,rr; }; stack<MOOE>st; signed main( ) {ios::sync_with_stdio(false);cin.tie(nullptr);int n;cin>>n;while(n--){int opt…