Android MVVM demo(使用DataBinding,LiveData,Fresco,RecyclerView,Room,ViewModel 完成)

使用DataBinding,LiveData,Fresco,RecyclerView,Room,ViewModel 完成

玩Android 开放API-玩Android - wanandroid.com

接口使用的是下面的两个:

https://www.wanandroid.com/banner/jsonicon-default.png?t=O83Ahttps://www.wanandroid.com/banner/json

wanandroid.com/project/list/1/json?cid=294icon-default.png?t=O83Ahttps://www.wanandroid.com/project/list/1/json?cid=294

需求列表:

现在我需要使用kotlin 来完成下面的需求,使用mvvm的模式,要求使用databinding,viewmodel,livedata,fresco,room,retrofit来完成1:主页显示https://www.wanandroid.com/banner/json 的数据
使用recyclerView 来展示每一个banner,其中banner内部使用databinding
使用fresco 来加载对应的图片
使用retrofit 来下载数据,下载后要求数据保存在room里面,如果数据在数据库中没有,那么就添加,如果已经有了就更新当前的数据,primarykey 是id
使用viewmode 有一个按钮“刷新banner” 会再次拉取https://www.wanandroid.com/banner/json  来刷新,使用databinding来刷新2:主页还要显示https://www.wanandroid.com/project/list/1/json?cid=294的数据
使用recyclerView 来展示每一个project,其中project内部使用databinding
使用fresco 来加载对应的图片
使用retrofit 来下载数据,下载后要求数据保存在room里面,如果数据在数据库中没有,那么就添加,如果已经有了就更新当前的数据,primarykey 是id
使用viewmode 有一个按钮“刷新banner” 会再次拉取 https://www.wanandroid.com/project/list/1/json?cid=294 来刷新,使用databinding来刷新1:https://www.wanandroid.com/banner/json
数据格式如下:
{"data": [{"desc": "我们支持订阅啦~","id": 30,"imagePath": "https://www.wanandroid.com/blogimgs/42da12d8-de56-4439-b40c-eab66c227a4b.png","isVisible": 1,"order": 2,"title": "我们支持订阅啦~","type": 0,"url": "https://www.wanandroid.com/blog/show/3352"}],"errorCode": 0,"errorMsg": ""
}2:https://www.wanandroid.com/project/list/1/json?cid=294
数据格式如下:
{"data": {"curPage": 1,"datas": [{"adminAdd": false,"apkLink": "","audit": 1,"author": "qianyue0317","canEdit": false,"chapterId": 294,"chapterName": "完整项目","collect": false,"courseId": 13,"desc": "玩Android flutter版本","descMd": "","envelopePic": "https://www.wanandroid.com/blogimgs/89868c9a-e793-46f3-a239-751246951b7f.png","fresh": false,"host": "","id": 27961,"isAdminAdd": false,"link": "https://www.wanandroid.com/blog/show/3618","niceDate": "2024-01-29 22:10","niceShareDate": "2024-01-29 22:10","origin": "","prefix": "","projectLink": "https://github.com/qianyue0317/wan_android_flutter","publishTime": 1706537457000,"realSuperChapterId": 293,"selfVisible": 0,"shareDate": 1706537457000,"shareUser": "","superChapterId": 294,"superChapterName": "开源项目主Tab","tags": [{"name": "项目","url": "/project/list/1?cid=294"}],"title": "玩Android-flutter项目","type": 0,"userId": -1,"visible": 1,"zan": 0}],"offset": 0,"over": false,"pageCount": 20,"size": 15,"total": 289},"errorCode": 0,"errorMsg": ""
}

0:在应用模块的 build.gradle 文件中,确保启用了数据绑定:

android {//...buildFeatures {dataBinding = true}
}

1. 依赖项配置

在项目的 build.gradle 文件中添加以下依赖项:

plugins {alias(libs.plugins.android.application)alias(libs.plugins.kotlin.android)
}android {namespace = "com.example.mykotlin"compileSdk = 34defaultConfig {applicationId = "com.example.mykotlin"minSdk = 33targetSdk = 34versionCode = 1versionName = "1.0"testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {isMinifyEnabled = falseproguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"),"proguard-rules.pro")}}compileOptions {sourceCompatibility = JavaVersion.VERSION_1_8targetCompatibility = JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = "1.8"}dataBinding{enable = true}
}dependencies {implementation(libs.androidx.core.ktx)implementation(libs.androidx.appcompat)implementation(libs.material)implementation(libs.androidx.activity)implementation(libs.androidx.constraintlayout)implementation(libs.com.facebook.fresco.fresco4)implementation(libs.androidx.lifecycle.livedata.ktx) // 这里的版本号可能需要根据实际情况调整implementation(libs.androidx.lifecycle.viewmodel.ktx) // 同上implementation(libs.com.squareup.retrofit2.retrofit)implementation(libs.com.squareup.retrofit2.converter.gson)//noinspection UseTomlInsteadimplementation("androidx.room:room-runtime:2.5.2")annotationProcessor("androidx.room:room-compiler:2.5.2")testImplementation(libs.junit)androidTestImplementation(libs.androidx.junit)androidTestImplementation(libs.androidx.espresso.core)implementation("androidx.databinding:databinding-runtime:7.4.0")
}

2: 数据模型类

创建数据模型类来表示 Banner 和 Project 的数据:

data class BannerItem(val id: Int,val desc: String,val imagePath: String,val title: String,val url: String
)data class ProjectItem(val id: Int,val title: String,val desc: String,val envelopePic: String,// 其他属性
)

3:数据库相关

创建数据库和 DAO:

@Database(entities = [BannerItem::class, ProjectItem::class], version = 1)
abstract class AppDatabase : RoomDatabase() {abstract fun bannerDao(): BannerDaoabstract fun projectDao(): ProjectDao
}@Dao
interface BannerDao {@Insert(onConflict = OnConflictStrategy.REPLACE)suspend fun insertBanners(banners: List<BannerItem>)@Query("SELECT * FROM BannerItem")suspend fun getAllBanners(): List<BannerItem>
}@Dao
interface ProjectDao {@Insert(onConflict = OnConflictStrategy.REPLACE)suspend fun insertProjects(projects: List<ProjectItem>)@Query("SELECT * FROM ProjectItem")suspend fun getAllProjects(): List<ProjectItem>
}

4. Retrofit 服务接口

package com.example.mykotlin.model.dataimport android.app.Application
import android.util.Log
import androidx.lifecycle.MutableLiveData
import com.example.mykotlin.model.dao.BannerDao
import com.example.mykotlin.model.dao.ProjectDao
import com.example.mykotlin.model.data.network.WanAndroidApi
import com.example.mykotlin.model.db.AppDatabase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.security.KeyManagementException
import java.security.NoSuchAlgorithmException
import java.security.SecureRandom
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManagerclass RetrofitSingleton private constructor() {companion object {private var instance: retrofit2.Retrofit? = nullfun getInstance(): retrofit2.Retrofit {if (instance == null) {synchronized(RetrofitSingleton::class.java) {if (instance == null) {try {val trustAllCerts = arrayOf<TrustManager>(UnsafeTrustManager())val sslContext = SSLContext.getInstance("SSL")sslContext.init(null, trustAllCerts, SecureRandom())val client = okhttp3.OkHttpClient.Builder().sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager).hostnameVerifier(UnsafeHostnameVerifier()).build()instance = retrofit2.Retrofit.Builder().baseUrl("https://www.wanandroid.com/").addConverterFactory(retrofit2.converter.gson.GsonConverterFactory.create()).client(client).build()} catch (e: NoSuchAlgorithmException) {e.printStackTrace()} catch (e: KeyManagementException) {e.printStackTrace()}}}}return instance!!}}
}class UnsafeTrustManager : X509TrustManager {override fun checkClientTrusted(chain: Array<out java.security.cert.X509Certificate>?, authType: String?) {}override fun checkServerTrusted(chain: Array<out java.security.cert.X509Certificate>?, authType: String?) {}override fun getAcceptedIssuers(): Array<java.security.cert.X509Certificate> = arrayOf()
}class UnsafeHostnameVerifier : javax.net.ssl.HostnameVerifier {override fun verify(hostname: String?, sslSession: javax.net.ssl.SSLSession?): Boolean = true
}class DataRepository(private val application: Application) {private val TAG = "DataRepository-Kodulf"
//    val database = AppDatabase.getInstance(application)//    private val bannerDao: BannerDao = database.bannerDao()
//    private val projectDao: ProjectDao  = database.projectDao()val bannerList = MutableLiveData<MutableList<BannerItem>>()val projectList = MutableLiveData<List<ProjectItem>>()private val executorService = CoroutineScope(Dispatchers.IO)
//    loadBannersFromDatabase()
//    loadProjectsFromDatabase()init {}//    private fun loadBannersFromDatabase() {
//        executorService.launch {
//            val banners = bannerDao.getAllBanners()
//            if (banners!= null && banners.isNotEmpty()) {
//                bannerList.postValue(banners)
//            }
//        }
//    }//    private fun loadProjectsFromDatabase() {
//        executorService.launch {
//            val projects = projectDao.getAllProjects()
//            if (projects!= null && projects.isNotEmpty()) {
//                projectList.postValue(projects)
//            }
//        }
//    }fun fetchBanners(){val retrofit = Retrofit.Builder().baseUrl("https://www.wanandroid.com/").addConverterFactory(GsonConverterFactory.create()).build()val apiService = retrofit.create(WanAndroidApi::class.java)val call = apiService.getBanners()call.enqueue(object : retrofit2.Callback<BannerResponse> {override fun onResponse(call: Call<BannerResponse>,response: retrofit2.Response<BannerResponse>) {if (response.isSuccessful) {val bannerResponse = response.body()// 处理返回的数据Log.d(TAG,"Banner network request fetchBanners " + bannerResponse)bannerList.postValue(bannerResponse?.data)}}override fun onFailure(call: Call<BannerResponse>, t: Throwable) {// 处理请求失败的情况Log.e(TAG,"Banner network request fetchBanners onFailure ",t)Log.d(TAG,t.toString())}})}//    fun fetchBanners2() {
//        Log.d(TAG,"Banner network request fetchBanners")
//        val apiService = RetrofitSingleton.getInstance().create(WanAndroidApi::class.java)
//
//        runBlocking {
//            launch {
//                val data = apiService.getBanners().data
//
//                Log.d(TAG, "Banner network request fetchBanners data = " + data)
//
//                data?.let {
//                    Log.d(TAG, "Banner network request fetchBanners doBannerUpdate")
//doBannerUpdate(data)
//                    try {bannerDao.insertBanners(bannerItems)
//                        // 更新 LiveData 的值
//                        Log.d(
//                            TAG,
//                            "Banner network request fetchBanners doBannerUpdate bannerList.postValue(bannerItems)"
//                        )
//
//                        bannerList.postValue(data)
//                    } catch (e: Exception) {
//                        println("Error updating or inserting banners: ${e.message}")
//                    }
//                }
//            }
//        }
//    }private fun doBannerUpdate(bannerItems: MutableList<BannerItem>) {executorService.launch {try {
//                bannerDao.insertBanners(bannerItems)// 更新 LiveData 的值Log.d(TAG,"Banner network request fetchBanners doBannerUpdate bannerList.postValue(bannerItems)")bannerList.postValue(bannerItems)} catch (e: Exception) {println("Error updating or inserting banners: ${e.message}")}}}
//
//    fun fetchProjects() {
//        val apiService = RetrofitSingleton.getInstance().create(WanAndroidApi::class.java)
//        executorService.launch {
//            val data = apiService.getProjects().data;
//            data?.let{
//                doProjectUpdate(data)
//            }
//        }
//    }
//
//    private fun doProjectUpdate(datas: List<ProjectItem>) {
//        executorService.launch {
//            try {
//                projectDao.insertProjects(datas)
//                // 更新 LiveData 的值
//                projectList.postValue(datas)
//            } catch (e: Exception) {
//                println("Error updating or inserting projects: ${e.message}")
//            }
//        }
//    }
}

5:ViewModel

package com.example.mykotlin.viewmodelimport android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.mykotlin.model.data.BannerItem
import com.example.mykotlin.model.data.DataRepository//注意这里application 前面没有var
class HomeViewModel(application: Application) : AndroidViewModel(application) {init {}private val dataRepository:DataRepository = DataRepository(application)private val bannerList:MutableLiveData<MutableList<BannerItem>> = dataRepository.bannerListfun refreshBanner(){dataRepository.fetchBanners();}fun getBannerList():MutableLiveData<MutableList<BannerItem>>{return bannerList}}

6. 布局文件

创建主布局文件 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout><data><import type="com.example.mykotlin.viewmodel.HomeViewModel"/><variablename="viewModel"type="HomeViewModel" /></data><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/main"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".view.MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/jumpXieCheng"android:onClick="jumpXieCheng"android:text="跳转到协程" /><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/refreshBannerButton"android:onClick="refreshBanner"android:text="刷新banner" /><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/refreshProjectButton"android:onClick="refreshProject"android:text="刷新project" /></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="10dp"android:background="#990000"/><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/bannerRecyclerView"android:layout_width="match_parent"android:layout_height="wrap_content"/><Viewandroid:layout_width="match_parent"android:layout_height="10dp"android:background="#009900"/><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/projectRecyclerView"android:layout_width="match_parent"android:layout_height="wrap_content"/></LinearLayout>
</layout>

创建 Banner 项布局文件 banner_item.xml

<?xml version="1.0" encoding="utf-8"?>
<layout><data><import type="com.example.mykotlin.model.data.BannerItem"/><variablename="banner"type="BannerItem" /></data><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:orientation="vertical"android:layout_height="200dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/des"android:text="123"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/title"android:text="1234"/><Viewandroid:layout_width="match_parent"android:layout_height="10dp"android:background="@color/black"/></LinearLayout>
</layout>

创建 Project 项布局文件 project_item.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"><data><variablename="project"type="com.example.yourpackage.ProjectItem" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><com.facebook.drawee.view.SimpleDraweeViewandroid:id="@+id/projectImage"android:layout_width="match_parent"android:layout_height="150dp"app:srcCompat="@{project.envelopePic}" /><TextViewandroid:id="@+id/projectTitle"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{project.title}"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/projectImage" /></androidx.constraintlayout.widget.ConstraintLayout></layout>

7. Activity

package com.example.mykotlin.viewimport android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.mykotlin.R
import com.example.mykotlin.databinding.ActivityMainBinding
import com.example.mykotlin.model.data.BannerItem
import com.example.mykotlin.viewmodel.HomeViewModel
import com.example.mykotlin.xiecheng.XieChengActivityclass MainActivity : AppCompatActivity() {lateinit var activityMainBinding:ActivityMainBindinglateinit var homeViewModel:HomeViewModel//初始化为空的列表var list:MutableList<BannerItem> = mutableListOf()var bannerAdapter: BannerAdapter = BannerAdapter(list)var TAG:String = "kodulf-Mainactivity"override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);homeViewModel = ViewModelProvider(viewModelStore,//这个对象只有在Activity创建之和才会有defaultViewModelProviderFactory).get(HomeViewModel::class.java)homeViewModel.getBannerList().observe(this, Observer { value ->Log.d(TAG, "getBannerListLiveData onchanged + $value")bannerAdapter.setBanners(value)})activityMainBinding.bannerRecyclerView.adapter = bannerAdapteractivityMainBinding.bannerRecyclerView.layoutManager = LinearLayoutManager(this)}fun jumpXieCheng(view: View) {val intent = Intent(this,XieChengActivity::class.java)startActivity(intent)}fun refreshBanner(view:View){homeViewModel.refreshBanner()}
}

8. 适配器

创建 Banner 适配器和 Project 适配器:

package com.example.mykotlin.viewimport android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.mykotlin.R
import com.example.mykotlin.databinding.ItemBannerBinding
import com.example.mykotlin.model.data.BannerItem
class BannerAdapter(private val banners: MutableList<BannerItem>) : RecyclerView.Adapter<BannerAdapter.BannerViewHolder>() {class BannerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {fun bind(bannerItem: BannerItem) {// 绑定数据到视图的逻辑itemView.findViewById<TextView>(R.id.des).setText(bannerItem.desc)itemView.findViewById<TextView>(R.id.title).setText(bannerItem.title)}}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {val view = LayoutInflater.from(parent.context).inflate(R.layout.item_banner, parent, false)return BannerViewHolder(view)}override fun onBindViewHolder(holder: BannerViewHolder, position: Int) {holder.bind(banners[position])}override fun getItemCount(): Int {return banners.size}fun setBanners(newBanners: MutableList<BannerItem>) {banners.clear()banners.addAll(newBanners)notifyDataSetChanged()}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/468927.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++11(一)

c11&#xff08;一&#xff09; 1. C11的发展历史2. 列表初始化2.1 C98传统的{}2.2 C11中的{}2.3 C11中的std::initializer_list 3. 右值引⽤和移动语义3.1 左值和右值3.2 左值引⽤和右值引⽤3.3 引⽤延⻓⽣命周期3.4 左值和右值的参数匹配3.5 右值引⽤和移动语义的使⽤场景3.5…

‍️代码的华尔兹:在 Makefile 的指尖上舞动自动化的诗篇

文章目录 &#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️背景——一个优秀工程师必备技能&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️一、&#x1f929;&#x1f929;快速了解…

SpringBoot中使用Thymeleaf模板引擎

和使用freemarker差不多的方式 1、导入thymeleaf的启动器 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> 2、编写Controller类 3、编写模板页面 注…

vue之子组件向父组件传值

参考博客先挂上 vue3中子传父&#xff08;emit&#xff09;、父传子&#xff08;props&#xff09;一篇文章拿下第一次写文章&#xff0c;告诉你vue3中如何实现父子相传&#xff0c;一篇文章帮 - 掘金 父组件通过 props 向子组件传值 1.子组件使用 $emit 触发事件 2.在父组件…

第26天 安全开发-PHP应用模板引用Smarty渲染MVC模型数据联动RCE安全

时间轴&#xff1a; 演示案例 新闻列表&模板引用-代码RCE安全 知识点 1、PHP 新闻显示-数据库操作读取显示 2、PHP 模版引用-自写模版&Smarty 渲染 3、PHP 模版安全-RCE 代码执行&三方漏洞 新闻列表 1.数据库创建新闻存储 2.代码连接数据库读取 3.页面进行自定…

【微服务】Docker 容器化

一、初识Docker 1. 为什么需要 Docker 大型项目组件较多&#xff0c;运行环境也较为复杂&#xff0c;部署时会遇到一些问题&#xff1a; 依赖关系复杂&#xff0c;容易出现兼容性的问题开发、测试、生产环境有差异 Docker 如何解决依赖的兼容问题 将应用的Libs&#xff08;…

(十四)JavaWeb后端开发——MyBatis

目录 1.MyBatis概述 2.MyBatis简单入门 3.JDBC&#xff08;了解即可&#xff09; 4.数据库连接池​ 5.lombok 6.MyBatis基本操作 7.XML映射文件 8.动态SQL 8.1 if标签 8.2 foreach标签 8.3 sql/include标签​ 1.MyBatis概述 MyBatis是一款优秀的持久层&#xff08…

pytorch实现深度神经网络DNN与卷积神经网络CNN

DNN概述 深度神经网络DNN来自人脑神经元工作的原理&#xff0c;通过在计算机中逻辑抽象出多个节点&#xff0c;接收处理并向后传递信息&#xff0c;实现计算机的自我学习&#xff0c;类比结构见下图&#xff1a; 该方法通过预测输出与实际值的差异不断调整节点参数&#xff0…

私域流量圈层在新消费时代的机遇与挑战:兼论开源 AI 智能名片、2 + 1 链动模式、S2B2C 商城小程序的应用

摘要&#xff1a;本文剖析了私域流量圈层在新消费时代呈现出的独特温度与信任优势&#xff0c;阐述了从传统销售到新消费转型中用户心理的变化。同时&#xff0c;强调了内容对于私域流量的关键作用&#xff0c;并分析开源 AI 智能名片、2 1 链动模式、S2B2C 商城小程序在私域流…

1.4 配置 Android 构建系统

Android 构建系统会编译应用资源和源代码&#xff0c;然后将它们打包成 APK 或 Android App Bundle 文件&#xff0c;供您测试、部署、签名和分发。 创建自定义 build 配置需要您对一个或多个 build 配置文件做出更改。这些纯文本文件使用领域特定语言 (DSL) 通过 Kotlin 脚本&…

containerd配置私有仓库registry

机器ip端口regtisry192.168.0.725000k8s-*-------k8s集群 1、镜像上传 rootadmin:~# docker push 192.168.0.72:5000/nginx:1.26.1-alpine The push refers to repository [192.168.0.72:5000/nginx] 6961f0b8531c: Pushed 3112cd521249: Pushed d3f50ce9b5b5: Pushed 9efaf2eb…

ABAP:SET CURSOR FIELD设置鼠标焦点

SET CURSOR FIELD <字段名>&#xff1a;设置鼠标焦点到该字段 SET CURSOR 设置到鼠标焦点列还是行 SET CURSOR LINE 设置鼠标焦点到行 GET CURSOR field <字段名> &#xff1a;这个相对应的获取鼠标焦点得到的字段

PHP和Python脚本的性能监测方案

目录 1. 说明 2. PHP脚本性能监测方案 2.1 安装xdebug 2.2 配置xdebug.ini 2.3 命令行与VS Code中使用 - 命令行 - VS Code 2.4 QCacheGrind 浏览 3. Python脚本性能监测方案 3.1 命令行 4. 工具 5.参考 1. 说明 获取我们的脚本程序运行时的指标&#xff0c;对分析…

VS code 远程连接到docker容器

1.需要在vscode中下载remote 、docker、dev container插件。 如下图&#xff1a; 有小鲸鱼标志&#xff0c;说明已经成功。 右键可以运行或者停止容器运行

阿里1688 阿里滑块 231滑块 x5sec分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 有相关问题请第一时间头像私信联系我删…

Spring Validation数据校检

文章目录 Spring Validation1 关于Spring Validation2 使用流程3 快速入门4 运行异常处理4.1 说明4.2 处理异常4.3 明确提示消息 5 常用注解5.1 NotNull注解5.2 NotEmpty 注解5.3 NotBlank 注解5.4 Size 注解5.5 Range 注解 6 非POJO参数校验6.1 使用流程6.2 使用示例 Spring V…

‌STAR法则

一&#xff1a;STAR法则 STAR法则是一种简单而实用的表现技巧&#xff0c;常被用于求职过程中的个人经历描述&#xff0c;富有条理性&#xff0c;可以帮助你在职场中脱颖而出。“STAR”分别对应的是situation-task-action-result&#xff0c;通过情境、目标、行动和结果四个方面…

uniapp—android原生插件开发(1环境准备)

本篇文章从实战角度出发&#xff0c;将UniApp集成新大陆PDA设备RFID的全过程分为四部曲&#xff0c;涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程&#xff0c;轻松应对安卓原生插件开发与打包需求&#xff01; 项目背景&#xff1a; UniApp集成新大陆P…

国标GB28181设备管理软件EasyGBS国标GB28181视频平台:GB/T28181中的流类型

在当今的视频监控领域&#xff0c;GB/T28181协议作为中国国家标准委员会发布的重要技术规范&#xff0c;发挥着举足轻重的作用。这一标准不仅为视频监控系统的设备接入、视频流传输、设备控制等功能提供了明确的技术指导&#xff0c;还极大地促进了不同厂家设备之间的兼容性和互…

使用pip安装项目时,遇到以下错误的解决方案:error: [Errno 13] Permission denied

我是在虚拟环境下出现了这个错误 出现这种情况大概率是conda环境没有下载用户路径下的python解释器&#xff0c;你可以使用下面命令来检查 which python3这里如果出现的路径不是你用户目录下的&#xff0c;就是这个原因&#xff0c;你的conda环境在用户目录下&#xff0c;但是…