Android開發補充內容

Android開發補充內容

  • fragment
    • 通信
    • 生命周期
  • Okhttp
    • 基本使用
    • websocket
  • Retrofit
    • 基本使用
  • RxJava
    • 基本使用
    • 定時任務
  • Hilt
    • 基本使用
    • 進階使用
    • 例子
  • 組件庫
    • Material Components
    • Jetpack Compose

fragment

通信

fragmentactivity通信的一種原生方法是使用Bundle

Bundle bundle = new Bundle();
bundle.putString('msg', "數據");
BlankFragment bf = new BlankFragment();
bf.setArguments(bundle);

生命周期

  1. 第一次顯示:onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart -> onResume
  2. 按home:onPause -> onStop(界面顯示的fragment不變)
  3. 重新顯示:onStart -> onResume
  4. 按返回:onPause -> onStop -> onDestroyView -> onDestroy -> onDetach

使用了FragmentTransactionaddToBackStack方法

  1. 切換fragment:onPause -> onStop -> onDestroyView(但沒銷毀時,同棧切換)
  • 返回原fragment:onCreateView -> onActivityCreated -> onStart -> onResume(同棧返回)

Okhttp

基本使用

模塊級的build.gradle導入依賴:

implementation 'com.squareup.okhttp3:okhttp:4.9.1'

創建客戶端:

client = OkHttpClient.Builder().addInterceptor {val request = it.request()val response = it.proceed(request)Log.d("biluo", request.url.toString())response}.connectTimeout(20, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).build()

創建和使用請求:

val request = Request.Builder().url("http://localhost/user/list").build()
// 阻塞方式
val response = client.newCall(request).execute()
// 異步方式
val response = client.newCall(request).enqueue(object : Callback {override fun onFailure(call: Call, e: IOException) {TODO("Not yet implemented")}override fun onResponse(call: Call, response: Response) {TODO("Not yet implemented")}
})

websocket

val observable = Observable.create<String> { emitter ->val request = Request.Builder().url("${AppConstant.WS_URL}/${user.username}").build()val ws = client.newWebSocket(request, object : WebSocketListener() {override fun onOpen(webSocket: WebSocket, response: Response) {wsObservable.ws = webSocketLog.d("biluo", "socket連接成功")}override fun onMessage(webSocket: WebSocket, text: String) {Log.d("biluo", "接收到消息:$text")emitter.onNext(text)}override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {Log.d("biluo", "socket連接準備斷開")}override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {wsObservable.ws = nullLog.d("biluo", "socket連接已經斷開")//emitter.onComplete()}override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {Log.e("biluo", "異常:${t.message}", t)emitter.onError(t)}})emitter.setDisposable(object : Disposable {override fun dispose() {Log.d("biluo", "dispose...")ws.close(1000, "Closing by dispose")}override fun isDisposed(): Boolean {return ws.close(1000, null)}})
}
wsObservable.observable = observable
return wsObservable

Retrofit

基于OkHttp,同時支持了RESTful API風格設計

基本使用

模塊級的build.gradle導入依賴:

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'

創建Retrofit實例:

添加了GsonConvert后,會自動把響應回來的Json字符串轉換為對象。

val retrofit = Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).client(client).build()

定義Api類:

interface UserApi {@GET("$USER_URL/{username}")fun getByUsername(@Path("username") username: String): Call<MsgResult<User>>@POST("$USER_URL/register")fun register(@Body user: User): Call<MsgResult<Nothing>>
}

創建Api類:

UserApi = retrofit.create(UserApi::class.java)

RxJava

可以結合Retrofit一起使用。

基本使用

前提:依賴在Retrofit中已經導入,并創建了RxJavaConvert到Retrofit中。

之前定義Api的返回值可以改為RxJava提供的類型。

它提供了:

  • Observable:流式數據類型,用于訪問多個項的異步序列。

  • Flowable:與Observable類似,支持背壓(backpressure)機制,即當數據生產速度超過消費速度時,能夠控制數據的流動。

  • Single:單發數據類型,只能且必須發射一個數據。

  • Maybe:單發數據類型,可以發射零個或一個數據。

  • Completable:不發射任何數據,只通知流的結束。

之前的UserApi類變為:

interface UserApi {@GET("$USER_URL/{username}")fun getByUsername(@Path("username") username: String): Single<MsgResult<User>>@POST("$USER_URL/register")fun register(@Body user: User): Single<MsgResult<Nothing>>
}

使用:

val disposable: Disposable = single.subscribeOn(Schedulers.io()).observeOn(AndroidScheduler.mainScheduler).subscribe({ res ->//成功獲取結果res,做什么}, { e ->//出現異常后做些什么})

Retrofix下的RxJava沒有AndroidScheduler類,可以自己定義一個:

object AndroidScheduler : Executor {val mainScheduler: Scheduler = Schedulers.from(this)private val handler: Handler = Handler(Looper.getMainLooper())override fun execute(command: Runnable) {handler.post(command)}
}

定時任務

val disposable = Observable.interval(15L, TimeUnit.MINUTES).subscribe({ _ ->val json = Gson().toJson(Message("ping", null, appUser.username))wsObservable.ws?.send(json)Log.d("biluo", "發送了一個心跳包")}) { t ->Log.e("biluo", "異常:", t)wsObservable.ws?.close(1000, "心跳續約失敗")}

Hilt

可以進行實例的管理,并進行依賴注入。類似spring IOC

項目級build.gradle導入插件:

id 'com.google.dagger.hilt.android' version '2.51.1' apply false

模塊級build.gradle導入插件:

id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'

模塊級build.gradle導入依賴:

implementation 'com.google.dagger:hilt-android:2.51.1'kapt 'com.google.dagger:hilt-compiler:2.51.1'

基本使用

參考教程:https://blog.csdn.net/Mr_Tony/article/details/124516871

使用Hilt必須要先用@HiltAndroidApp綁定Application

哪個類需要進行依賴注入,就得加上@AndroidEntryPoint進行綁定,然后注入的地方需要使用@Inject

  • @HiltAndroidApp:用于標注 Application 類,觸發 Hilt 的代碼生成操作,生成應用級別的組件。

  • @AndroidEntryPoint:用于標注 Android 組件(如 ActivityFragment 等),告知 Hilt 這些組件可以接收依賴注入。

  • @Inject

    • 用于標注需要注入的依賴項,可以是字段、構造函數或方法。
    • 對于字段,Hilt 會自動注入相應的依賴;對于構造函數,Hilt 會使用它來創建類的實例

注:@AndroidEntryPoint不僅僅可以綁定到Activity,還可以綁定到其他地方,請參考:https://developer.android.google.cn/training/dependency-injection/hilt-android

@HiltAndroidApp
class App: Application()// 類似spring的 @Component
class DateFormatter @Inject constructor() {fun testDateFormatter(){Log.e("YM--->","---->獲取DateFormatter")}
}// 類似spring在類中進行依賴注入也需要當前類被spring管理
@AndroidEntryPoint
class HiltActivity : AppCompatActivity() {@Inject	// 類似spring的 @Autowirelateinit var dateFormatter: DateFormatteroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_hilt)dateFormatter.testDateFormatter()}
}

進階使用

  • @Module:用于標注提供依賴項的類。
  • @Provides:用于標注 Module 類中的提供依賴項的方法,Hilt 會在需要時調用這些方法。
  • @Binds:用于在Module類中綁定接口和實現類,告知 Hilt 在需要提供接口的實例時要使用哪種實現。
  • @InstallIn:用于標注 ModuleEntryPoint,指定其作用范圍。
  • @Singleton:用于標注提供的依賴項為單例,即在整個應用程序的生命周期內只存在一個實例。
  • @HiltViewModel
    • 用于標注 ViewModel 類,使其可以使用 Hilt 進行依賴注入。
    • 注意:ViewModel 不能直接使用 @Inject 注解,需要使用 @HiltViewModel
  • @ActivityScoped:用于標注提供的依賴項為 Activity 級別的作用域,即依賴項的生命周期與 Activity 相同。

補充:

  • @HiltViewModel

    • 用于標注 ViewModel 類,使其可以使用 Hilt 進行依賴注入。

    • 注意:ViewModel 不能直接使用 @Inject 注解,需要使用 @HiltViewModel

  • @ViewModelScoped:用于標注提供的依賴項為 ViewModel 級別的作用域,即依賴項的生命周期與 ViewModel 相同。

  • @EntryPoint:用于獲取 Hilt 提供的實例,特別是在不能直接使用 @AndroidEntryPoint 的類中(如 ContentProviderBroadcastReceiver)。

  • @Provides舉例:
class HelloClass {fun hello() = "Hello"
}@Module
// 表示整個應用程序的生命周期內都是單例
@InstallIn(SingletonComponent::class)
object AppModule {@Provides@Singleton	// 單例fun provideSomeOtherClass(): HelloClass {return HelloClass()}
}@AndroidEntryPoint
class MainActivity : AppCompatActivity() {@Injectlateinit var helloClass: HelloClassoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)helloClass.hello()}
}
  • @Binds舉例:在這個示例中,@Binds 注解用于將 ApiServiceImpl 綁定到 ApiService 接口上,這樣當需要 ApiService 的實例時,Hilt 會提供 ApiServiceImpl 的實例。
interface ApiService {fun doSomething()
}class ApiServiceImpl @Inject constructor() : ApiService {override fun doSomething() {println("Doing something in ApiServiceImpl")}
}@Module
@InstallIn(SingletonComponent::class)
abstract class ApiServiceModule {@Bindsabstract fun bindApiService(apiServiceImpl: ApiServiceImpl): ApiService
}
  • @ActivityScope例子:
@Module
@InstallIn(ActivityComponent::class)
object ActivityModule {@Provides@ActivityScopedfun provideActivityDependency(): ActivityDependency {return ActivityDependency()}
}

例子

Application類:

@HiltAndroidApp
class MyApplication : Application() {}

模塊類:

@InstallIn(SingletonComponent::class)
@Module
class AppModule {@Provides@Singletonfun okHttpClient(): OkHttpClient {return OkHttpClient.Builder().addInterceptor {val request = it.request()val response = it.proceed(request)Log.d("biluo", request.url.toString())response}.connectTimeout(20, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).retryOnConnectionFailure(false).build()}@Provides@Singletonfun retrofit(client: OkHttpClient): Retrofit {return Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).client(client).build()}@Provides@Singletonfun userApi(retrofit: Retrofit): UserApi = retrofit.create(UserApi::class.java)
}

使用:

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {@Injectlateinit var userApi: UserApi
}

組件庫

Material Components

Material Components for Android:Google 官方提供的 Material Design 組件庫。

  • 特點
    • 完全遵循 Material Design 規范。
    • 提供豐富的組件(如 ButtonCardViewBottomNavigationView 等)。
    • 與 AndroidX 庫無縫集成。
  • 適用場景:需要遵循 Material Design 規范的項目。
  • GitHub:https://github.com/material-components/material-components-android

舉例:BottomNavigationView——底部導航欄

  1. 編寫菜單xml文件bottom_nav_menu.xml

    <?xml version="1.0" encoding="utf-8" ?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/nav_home"android:icon="@drawable/home"android:title="@string/tab1" /><itemandroid:id="@+id/nav_tab2"android:icon="@drawable/tab2"android:title="@string/tab2" /><itemandroid:id="@+id/nav_tb3"android:icon="@drawable/tb3"android:title="@string/tab3" />
    </menu>
    
  2. 在相應的布局文件中引入BottomNavigationView,例如MainActivity。

    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><androidx.fragment.app.FragmentContainerViewandroid:id="@+id/fragment_container"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" /><com.google.android.material.bottomnavigation.BottomNavigationViewandroid:id="@+id/bottomNavigationView"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="bottom"android:background="@color/purple_200"app:menu="@menu/bottom_nav_menu"/>
    </LinearLayout>
    
  3. 準備好相應的Fragment,為BottomNavigationView設置點擊事件,根據點擊的項切換Fragment

    class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_navigation)val fragmentContainer = supportFragmentManager.beginTransaction()// 默認加載 HomeFragmentfragmentContainer.replace(R.id.fragment_container, HomeFragment())fragmentContainer.commit()bottomNavigationView.setOnItemSelectedListener { item ->when (item.itemId) {R.id.nav_home -> {supportFragmentManager.beginTransaction().replace(R.id.fragment_container, HomeFragment()).commit()true}R.id.nav_tb2 -> {supportFragmentManager.beginTransaction().replace(R.id.fragment_container, NavTb2Fragment()).commit()true}R.id.nav_tb3 -> {supportFragmentManager.beginTransaction().replace(R.id.fragment_container, NavTb3Fragment()).commit()true}else -> false}}}
    }
    

Jetpack Compose

Jetpack Compose Material:Jetpack Compose 的 Material Design 組件庫。

  • 特點
    • 聲明式 UI 開發。
    • 提供 Material Design 風格的組件(如 ScaffoldButtonTextField 等)。
    • 與 Jetpack Compose 生態完全兼容。
  • 適用場景:使用 Jetpack Compose 開發的項目。
  • 文檔:Jetpack Compose 使用入門 | Android Developers (google.cn)

舉例:

@AndroidEntryPoint
class LoginActivity : AppCompatActivity() {private lateinit var shared: SharedPreferences@Inject lateinit var userApi: VehicleOwnerApioverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)shared = getSharedPreferences("user", MODE_PRIVATE)val id = shared.getString("id", "")!!val password = shared.getString("password", "")!!setContent {MaterialTheme { loginScreen(id, password) }}}@Composablefun loginScreen(originId: String, originPwd: String) {val ID_REGEX = Regex("^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$")val PWD_REGEX = Regex("^[a-zA-Z\\d]{4,16}$")var id by remember { mutableStateOf(originId) }var password by remember { mutableStateOf(originPwd) }var idErrorMsg by remember { mutableStateOf("") }var pwdErrorMsg by remember { mutableStateOf("") }var checked by remember { mutableStateOf(false) }fun checkIdFormat(): Boolean {idErrorMsg = if (id.isEmpty()) "身份證號不能為空" else {if (!ID_REGEX.matches(id)) "身份證號格式錯誤" else ""}return idErrorMsg.isEmpty()}fun checkPwdFormat(): Boolean {pwdErrorMsg = if (password.isEmpty()) "密碼不能為空" else {if (!PWD_REGEX.matches(password)) "密碼必須由4-16位的字母或數字組成" else ""}return pwdErrorMsg.isEmpty()}fun login() {if (!checkIdFormat() || !checkPwdFormat()) returnUtils.handleSingle(this, "token", userApi.login(VehicleOwner(id, password))) {GlobalData.token = it.toString()// 如果選擇了記住用戶,將身份證號和密碼寫入sharePreferencesif (checked) {shared.edit().putString("id", id).apply()shared.edit().putString("password", password).apply()} else {shared.edit().remove("id").apply()shared.edit().remove("password").apply()}// 登錄成功,跳轉到主頁Utils.showToast(this, "登錄成功")val intent = Intent(this, MainActivity::class.java)intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASKstartActivity(intent)}}Column(modifier = Modifier.padding(16.dp)) {TextField(  // 身份證輸入框value = id,onValueChange = { id = it },label = { Text("身份證號") },placeholder = { Text("請輸入身份證號") },isError = idErrorMsg.isNotEmpty(),trailingIcon = {if (idErrorMsg.isNotEmpty()) {    // 如果有錯誤提示,則顯示錯誤圖標Icon(Icons.Filled.Error, contentDescription = "Error")}},supportingText = { Text(idErrorMsg) },    // 顯示在下方的錯誤提示modifier = Modifier.fillMaxWidth()/*.onFocusChanged { focusState -> // 進入頁面時會直接顯示錯誤提示,不友好;改為點擊登錄時再檢查格式if (!focusState.isFocused) {idErrorMsg = if (id.isEmpty()) "身份證號不能為空" else {if (!ID_REGEX.matches(id)) "身份證號格式錯誤" else ""}}}*/)TextField(  // 密碼輸入框value = password,onValueChange = { password = it },label = { Text("密碼") },placeholder = { Text("請輸入密碼") },isError = pwdErrorMsg.isNotEmpty(),trailingIcon = {if (pwdErrorMsg.isNotEmpty()) {    // 如果有錯誤提示,則顯示錯誤圖標Icon(Icons.Filled.Error, contentDescription = "Error")}},supportingText = { Text(pwdErrorMsg) },    // 顯示在下方的錯誤提示modifier = Modifier.fillMaxWidth().padding(top = 4.dp))Row(verticalAlignment = Alignment.CenterVertically, // 行內元素垂直居中horizontalArrangement = Arrangement.spacedBy((-6).dp),  // 行內元素間距modifier = Modifier.clickable(interactionSource = remember { MutableInteractionSource() },indication = null   // 移除點擊效果) { // 點擊整個 Row 切換選中狀態checked = !checked}) {Checkbox(checked = checked, onCheckedChange = { checked = it })	// 復選框Text("記住用戶")	// 文本}Button(	// 按鈕onClick = { login() },modifier = Modifier.fillMaxWidth()) {Text("登     錄")}}}
}

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

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

相關文章

隱私計算框架FATE二次開發心得整理(工業場景實踐)

文章目錄 版本介紹隱私計算介紹前言FATE架構總體架構FateBoard架構前端架構后端架構 FateClient架構創建DAG方式DAG生成任務管理python SDK方式 FateFlow架構Eggroll架構FATE算法架構Cpn層FATE ML層 組件新增流程新增組件流程新增算法流程 版本介紹 WeBank的FATE開源版本 2.2.…

AI驅動的制造工藝:系統化探索與創新

DeepSeek 技術全景 在當今 AI 技術蓬勃發展的時代,DeepSeek 已成為該領域中一顆耀眼的明星。自 2023 年 7 月 17 日成立以來,這家由知名私募巨頭幻方量化孕育而生的公司,迅速在 AI 領域嶄露頭角 。DeepSeek 的目標是開發頂尖的大語言模型(LLM),并利用數據蒸餾技術打造更精…

【嵌入式開發-LCD】

嵌入式開發-LCD ■ LCD簡介 ■ LCD簡介

java反射(2)

package 反射;import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays;public class demo {public static void main(String[] args) throws Exception {// 通過類的全限定名獲取對應的 Class 對象…

使用 Cesium 構建 3D 地圖應用的實踐

CesiumJS 是一個功能強大的開源 JavaScript 庫&#xff0c;能夠幫助開發者快速構建高性能、高精度的 3D 地球和地圖應用 。本文將介紹如何使用 Cesium 構建一個基本的 3D 地圖應用&#xff0c;并加載自定義的 3D Tiles 模型。 初始化 Cesium Viewer 首先&#xff0c;在 Vue 的…

結合Splash與Scrapy:高效爬取動態JavaScript網站

在當今的Web開發中&#xff0c;JavaScript的廣泛應用使得許多網站的內容無法通過傳統的請求-響應模式直接獲取。為了解決這個問題&#xff0c;Scrapy開發者經常需要集成像Splash這樣的JavaScript渲染引擎。本文將詳細介紹Splash JS引擎的工作原理&#xff0c;并探討如何將其與S…

企業級可觀測性實現:OpenObserve云原生平臺的本地化部署與遠程訪問解析

文章目錄 前言1. 安裝Docker2. 創建并啟動OpenObserve容器3. 本地訪問測試4. 公網訪問本地部署的OpenObserve4.1 內網穿透工具安裝4.2 創建公網地址 5. 配置固定公網地址 前言 嘿&#xff0c;各位小伙伴們&#xff0c;今天要給大家揭秘一個在云原生領域里橫掃千軍的秘密法寶—…

將本地項目提交到新建的git倉庫

方式一: # 登錄git&#xff0c;新建git倉庫和指定的分支&#xff0c;如master、dev# 下載代碼&#xff0c;默認下載master分支 git clone http://10.*.*.67/performance_library/pfme-*.git # 切換到想要提交代碼的dev分支 git checkout dev# 添加想要提交的文件 git add .#…

.NET平臺用C#在PDF中創建可交互的表單域(Form Field)

在日常辦公系統開發中&#xff0c;涉及 PDF 處理相關的開發時&#xff0c;生成可填寫的 PDF 表單是一種常見需求&#xff0c;例如員工信息登記表、用戶注冊表、問卷調查或協議確認頁等。與靜態 PDF 不同&#xff0c;帶有**表單域&#xff08;Form Field&#xff09;**的文檔支持…

在macOS上安裝windows系統

使用Boot Camp 1. 準備工作&#xff1a;確認Mac滿足Boot Camp系統要求&#xff0c;準備好Windows安裝光盤或ISO映像文件&#xff0c;以及一個至少8GB的空白USB閃存驅動器用于保存驅動程序。 2. 打開Boot Camp助理&#xff1a;在“應用程序”文件夾的“實用工具”中找到“Boot…

683SJBH基于J2EE的廣州旅游管理系統

第1章  緒論 課題背景 自互聯網internet成為一種革命性的大眾媒體以來&#xff0c;其發展速度之快令人驚嘆。而作為世界最大朝陽產業的旅游&#xff0c;當它與電子商務這一新興模式相結合時&#xff0c;其潛藏的商業價值表露無遺。根據CNN&#xff08;美國有線電視新聞網&…

前端面試每日三題 - Day 27

這是我為準備前端/全棧開發工程師面試整理的第27天每日三題練習&#xff0c;涵蓋了&#xff1a; CSS選擇器的優先級與權重計算機制Angular中的依賴注入&#xff08;Dependency Injection&#xff09;機制設計一個支持實時協作編輯&#xff08;如Google Docs&#xff09;的前端…

PostgreSQL數據庫操作SQL

數據庫操作SQL 創建 創建數據庫 create database db_test;創建并指定相關參數 with owner : 所有者encoding : 編碼connection limit &#xff1a;連接限制 create database db_test1 with owner postgresencoding utf-8connection limit 100;修改 修改數據庫名稱 renam…

JSP HTTP 狀態碼詳解

JSP HTTP 狀態碼詳解 引言 HTTP 狀態碼是 HTTP 協議的一部分,用于表示客戶端與服務器之間請求與響應的狀態。在 JavaServer Pages (JSP) 技術中,HTTP 狀態碼同樣扮演著重要的角色。本文將詳細解析 JSP 中的 HTTP 狀態碼,幫助開發者更好地理解和應用這些狀態碼。 HTTP 狀態…

文件一鍵解密軟件工具(支持pdf、word、excel、ppt、rar、zip格式文件)

一鍵解密解鎖神器支持解密pdf、doc、docx、xls、xlsx、ppt、pptx、rar、zip格式文件&#xff0c;Excel表格、Word文檔、PPT演示、RAR、ZIP壓縮包、PDF文檔一鍵輕松解密&#xff01;簡單/高效/安全。這款軟件由密碼帝官方提供&#xff0c;確保了其合法性和安全性&#xff0c;用戶…

Banana Pi BPI-CM6 是一款八核 RISC-V 模塊,兼容 Raspberry Pi CM 載板

Banana Pi BPI-CM6 是一款 SpacemIT K1 八核 RISC-V 系統級模塊&#xff0c;遵循 Raspberry Pi CM5 的設計&#xff0c;并提供高達 16GB LPDDR4 RAM、高達 128GB eMMC 閃存、千兆以太網控制器和 WiFi 6 藍牙 5.2 模塊。 BPI-CM6 雖然與 Raspberry Pi CM5 基本兼容&#xff0c…

【項目篇之統一硬盤操作】仿照RabbitMQ模擬實現消息隊列

統一硬盤操作 創建出實例封裝交換機的操作封裝隊列的操作封裝綁定的操作封裝消息的操作總的完整代碼&#xff1a; 我們之前已經使用了數據庫去管理交換機&#xff0c;綁定&#xff0c;隊列 還使用了數據文件去管理消息 此時我們就搞一個類去把上述兩個部分都整合在一起&#…

快速上手SpringBoot開發指南

文章目錄 1. 項目整體架構2. SpringBoot核心注解詳解2.1 應用程序入口注解SpringBootApplication 2.2 控制器層注解RestControllerRequestMappingPostMappingRequestBody 2.3 服務層注解ServiceAutowired 2.4 數據訪問層注解Repository 2.5 實體類注解JPA相關注解Lombok注解 3.…

Unity WebGL、js發布交互

官網參考 Unity3D開發之WebGL平臺上 unity和js前端通信交互 WebFun.jslib mergeInto(LibraryManager.library, {JSLog: function (str) { var strsUTF8ToString(str); Log(str); Log(strs);}, Hello: function () {var strs"Hello, world!"; Log(strs); Log(UTF8ToS…

Spark 之 YarnCoarseGrainedExecutorBackend

YarnCoarseGrainedExecutorBackend executor ID , 在日志里也有體現。 25/05/06 12:41:58 INFO YarnCoarseGrainedExecutorBackend: Successfully registered with driver 25/05