RecyclerView与ListView的优化
RecyclerView与ListView的优化
一、基础概念对比
1.1 ListView与RecyclerView概述
ListView和RecyclerView都是Android中用于展示列表数据的重要控件,但RecyclerView是更现代化的解决方案,提供了更多的灵活性和性能优势。
ListView特点
- Android早期提供的列表控件
- 使用简单,上手容易
- 内置了常见的分割线、选择模式等功能
- 性能优化相对有限
RecyclerView特点
- Android Support Library(现AndroidX)提供的现代列表控件
- 更加灵活,支持多种布局方式
- 强制使用ViewHolder模式
- 提供了丰富的动画API
- 通过LayoutManager实现不同的布局效果
1.2 基本使用对比
ListView基本使用
// 定义Adapter
class MyListAdapter(context: Context, data: List<String>) : ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, data) {// 可以重写getView方法进行优化
}// 在Activity中使用
val listView = findViewById<ListView>(R.id.list_view)
val data = listOf("Item 1", "Item 2", "Item 3")
listView.adapter = MyListAdapter(this, data)
RecyclerView基本使用
// 定义ViewHolder和Adapter
class MyAdapter(private val data: List<String>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {val textView: TextView = view.findViewById(R.id.text_view)}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent, false)return ViewHolder(view)}override fun onBindViewHolder(holder: ViewHolder, position: Int) {holder.textView.text = data[position]}override fun getItemCount() = data.size
}// 在Activity中使用
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(this)
val data = listOf("Item 1", "Item 2", "Item 3")
recyclerView.adapter = MyAdapter(data)
二、ListView优化技巧
2.1 ViewHolder模式
在ListView中,ViewHolder模式不是强制的,但使用它可以显著提高性能:
class OptimizedAdapter(context: Context, private val data: List<String>) : ArrayAdapter<String>(context, R.layout.list_item, data) {private class ViewHolder {var textView: TextView? = null}override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {var view = convertViewval holder: ViewHolderif (view == null) {view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false)holder = ViewHolder()holder.textView = view.findViewById(R.id.text_view)view.tag = holder} else {holder = view.tag as ViewHolder}holder.textView?.text = data[position]return view!!}
}
2.2 其他ListView优化技巧
-
合理设置ListView高度
- 避免在ScrollView中嵌套ListView
- 使用
android:layout_height="wrap_content"
时需谨慎
-
减少getView()中的复杂操作
- 避免在getView()中进行耗时操作
- 图片加载使用异步方式
-
使用分页加载
- 实现滑动到底部加载更多数据
- 避免一次性加载大量数据
三、RecyclerView优化技巧
3.1 布局优化
- 使用DiffUtil进行高效更新
class MyDiffCallback(private val oldList: List<String>, private val newList: List<String>) : DiffUtil.Callback() {override fun getOldListSize() = oldList.sizeoverride fun getNewListSize() = newList.sizeoverride fun areItemsTheSame(oldPos: Int, newPos: Int) = oldList[oldPos] == newList[newPos]override fun areContentsTheSame(oldPos: Int, newPos: Int) = oldList[oldPos] == newList[newPos]
}// 使用DiffUtil更新数据
fun updateData(newData: List<String>) {val diffResult = DiffUtil.calculateDiff(MyDiffCallback(data, newData))data.clear()data.addAll(newData)diffResult.dispatchUpdatesTo(this)
}
- 使用setHasFixedSize
recyclerView.setHasFixedSize(true) // 当列表项大小固定时使用
- 使用RecycledViewPool共享ViewHolder
// 在嵌套RecyclerView的场景中
val viewPool = RecyclerView.RecycledViewPool()
parentRecyclerView.setRecycledViewPool(viewPool)
3.2 数据处理优化
- 异步加载数据
CoroutineScope(Dispatchers.IO).launch {val data = loadDataFromDatabase()withContext(Dispatchers.Main) {adapter.updateData(data)}
}
- 分页加载
使用Paging库实现高效分页:
// 定义DataSource
class MyDataSource : PageKeyedDataSource<Int, Item>() {override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, Item>) {// 加载初始数据val items = fetchDataFromNetwork(1, params.requestedLoadSize)callback.onResult(items, null, 2)}override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Item>) {// 加载后续页面val items = fetchDataFromNetwork(params.key, params.requestedLoadSize)callback.onResult(items, params.key + 1)}override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Item>) {// 通常不需要实现}
}
3.3 滑动优化
- 预加载
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {super.onScrolled(recyclerView, dx, dy)val layoutManager = recyclerView.layoutManager as LinearLayoutManagerval lastVisibleItem = layoutManager.findLastVisibleItemPosition()val totalItemCount = layoutManager.itemCount// 当滑动到倒数第5个item时预加载下一页数据if (lastVisibleItem >= totalItemCount - 5) {loadMoreData()}}
})
- 滑动时暂停加载
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {super.onScrollStateChanged(recyclerView, newState)if (newState == RecyclerView.SCROLL_STATE_IDLE) {// 滑动停止时加载图片imageLoader.resumeLoading()} else {// 滑动时暂停图片加载imageLoader.pauseLoading()}}
})
四、实战案例
4.1 多类型列表实现
class MultiTypeAdapter(private val items: List<Any>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {companion object {const val TYPE_HEADER = 0const val TYPE_NORMAL = 1}override fun getItemViewType(position: Int): Int {return if (position == 0) TYPE_HEADER else TYPE_NORMAL}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {return when (viewType) {TYPE_HEADER -> {val view = LayoutInflater.from(parent.context).inflate(R.layout.item_header, parent, false)HeaderViewHolder(view)}else -> {val view = LayoutInflater.from(parent.context).inflate(R.layout.item_normal, parent, false)NormalViewHolder(view)}}}override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {when (holder) {is HeaderViewHolder -> holder.bind(items[position] as Header)is NormalViewHolder -> holder.bind(items[position] as NormalItem)}}override fun getItemCount() = items.sizeclass HeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {fun bind(header: Header) {// 绑定头部数据}}class NormalViewHolder(view: View) : RecyclerView.ViewHolder(view) {fun bind(item: NormalItem) {// 绑定普通项数据}}
}
4.2 网格布局与瀑布流实现
// 网格布局
val gridLayoutManager = GridLayoutManager(this, 3) // 3列网格
recyclerView.layoutManager = gridLayoutManager// 设置跨列显示的项
gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {override fun getSpanSize(position: Int): Int {return if (adapter.getItemViewType(position) == MultiTypeAdapter.TYPE_HEADER) {3 // 头部占据3列} else {1 // 普通项占据1列}}
}// 瀑布流布局
val staggeredGridLayoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL) // 2列瀑布流
recyclerView.layoutManager = staggeredGridLayoutManager
五、性能监测与调优
5.1 性能监测工具
-
Systrace
- 分析UI渲染性能
- 检测帧率和卡顿问题
-
Android Profiler
- 监控内存使用情况
- 分析CPU使用率
-
自定义性能监测
class PerformanceMonitorAdapter<VH : RecyclerView.ViewHolder>(private val wrappedAdapter: RecyclerView.Adapter<VH>) : RecyclerView.Adapter<VH>() {override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {val startTime = System.nanoTime()val holder = wrappedAdapter.onCreateViewHolder(parent, viewType)val endTime = System.nanoTime()Log.d("Performance", "onCreateViewHolder took ${(endTime - startTime) / 1000000}ms")return holder}override fun onBindViewHolder(holder: VH, position: Int) {val startTime = System.nanoTime()wrappedAdapter.onBindViewHolder(holder, position)val endTime = System.nanoTime()Log.d("Performance", "onBindViewHolder for position $position took ${(endTime - startTime) / 1000000}ms")}override fun getItemCount() = wrappedAdapter.itemCount
}// 使用方式
recyclerView.adapter = PerformanceMonitorAdapter(myAdapter)
5.2 常见性能问题及解决方案
-
布局层级过深
- 使用Hierarchy Viewer分析布局层级
- 使用ConstraintLayout减少嵌套
-
频繁创建对象
- 使用对象池复用临时对象
- 避免在onBindViewHolder中创建新对象
-
主线程阻塞
- 耗时操作放到后台线程
- 使用协程或RxJava处理异步任务
六、面试题解析
Q1:RecyclerView相比ListView有哪些优势?
答:RecyclerView相比ListView的主要优势:
- 强制使用ViewHolder模式,提高性能
- 通过LayoutManager支持多种布局方式(线性、网格、瀑布流)
- 提供了ItemAnimator实现丰富的动画效果
- 通过ItemDecoration自定义分割线和装饰
- 支持局部刷新,减少不必要的重绘
- 提供了更好的事件处理机制
- 与DiffUtil结合,高效处理数据变化
Q2:如何优化RecyclerView的性能?
答:优化RecyclerView性能的主要方法:
- 使用DiffUtil进行高效的数据更新
- 对于固定大小的列表,使用setHasFixedSize(true)
- 复杂布局使用多级缓存和RecycledViewPool
- 避免在onBindViewHolder中进行耗时操作
- 使用异步加载和图片缓存
- 实现分页加载,避免一次加载大量数据
- 滑动时暂停加载图片等耗时操作
- 优化item布局,减少嵌套和过度绘制
Q3:ListView和RecyclerView的缓存机制有什么区别?
答:ListView和RecyclerView的缓存机制区别:
-
ListView的缓存机制:
- 一级缓存:mActiveViews,屏幕内可见的View
- 二级缓存:mScrapViews,离开屏幕的View
-
RecyclerView的缓存机制:
- 一级缓存:mAttachedScrap,屏幕内可见的ViewHolder
- 二级缓存:mCachedViews,离开屏幕的ViewHolder,默认大小为2
- 三级缓存:ViewCacheExtension,开发者自定义缓存
- 四级缓存:RecycledViewPool,缓存不同类型的ViewHolder,可以在多个RecyclerView间共享
-
主要区别:
- RecyclerView缓存粒度更细,缓存层次更多
- RecyclerView支持多个RecyclerView共享缓存池
- RecyclerView缓存ViewHolder而不仅是View
- RecyclerView支持自定义缓存策略
七、开源项目实战
7.1 使用Epoxy实现复杂列表
Airbnb的Epoxy是一个用于构建复杂RecyclerView的库,它使用了类似于React的组件化思想:
// 定义Model
@EpoxyModelClass
abstract class HeaderModel : EpoxyModelWithHolder<HeaderHolder>() {@EpoxyAttribute lateinit var title: Stringoverride fun getDefaultLayout() = R.layout.item_headeroverride fun bind(holder: HeaderHolder) {holder.titleView.text = title}
}// 定义Controller
class MyEpoxyController : TypedEpoxyController<List<Item>>() {override fun buildModels(data: List<Item>) {// 添加头部header {id("header")title("我的列表")}// 添加列表项data.forEach { item ->itemModel {id(item.id)title(item.title)description(item.description)clickListener { _ -> onItemClicked(item) }}}}private fun onItemClicked(item: Item) {// 处理点击事件}
}// 在Activity中使用
val controller = MyEpoxyController()
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.adapter = controller.adapter// 更新数据
controller.setData(items)
项目地址:Epoxy
7.2 使用Paging3实现无限滚动列表
Jetpack Paging3库提供了一种更现代化的分页加载方案:
// 定义PagingSource
class MyPagingSource(private val api: MyApi
) : PagingSource<Int, Item>() {override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> {return try {val page = params.key ?: 1val response = api.getItems(page, params.loadSize)LoadResult.Page(data = response.items,prevKey = if (page == 1) null else page - 1,nextKey = if (response.items.isEmpty()) null else page + 1)} catch (e: Exception) {LoadResult.Error(e)}}override fun getRefreshKey(state: PagingState<Int, Item>): Int? {return state.anchorPosition?.let { anchorPosition ->state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)}}
}// 在ViewModel中使用
class MyViewModel : ViewModel() {val items = Pager(config = PagingConfig(pageSize = 20,enablePlaceholders = false,maxSize = 100),pagingSourceFactory = { MyPagingSource(api) }).flow.cachedIn(viewModelScope)
}// 在Activity中使用
class MyActivity : AppCompatActivity() {private val viewModel: MyViewModel by viewModels()private val adapter = MyPagingAdapter()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_my)val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)recyclerView.adapter = adapterlifecycleScope.launch {viewModel.items.collectLatest { pagingData ->adapter.submitData(pagingData)}}}
}
项目地址:Paging
总结
本文详细介绍了ListView和RecyclerView的优化技巧,从基础概念到高级应用,系统地讲解了如何提高列表性能和用户体验。RecyclerView作为Android现代列表控件,提供了更多的灵活性和性能优势,是开发高性能列表界面的首选。
在实际开发中,应根据具体需求选择合适的优化策略,如使用DiffUtil进行高效更新、实现分页加载、优化布局结构等。同时,结合Epoxy、Paging等优秀的开源库,可以更轻松地构建复杂且高性能的列表界面。
下一篇文章将介绍Fragment的生命周期与使用,敬请期待!
相关文章:
RecyclerView与ListView的优化
RecyclerView与ListView的优化 一、基础概念对比 1.1 ListView与RecyclerView概述 ListView和RecyclerView都是Android中用于展示列表数据的重要控件,但RecyclerView是更现代化的解决方案,提供了更多的灵活性和性能优势。 ListView特点 Android早期…...
【人工智能】GPT-4 vs DeepSeek-R1:谁主导了2025年的AI技术竞争?
前言 2025年,人工智能技术将迎来更加激烈的竞争。随着OpenAI的GPT-4和中国初创公司DeepSeek的DeepSeek-R1在全球范围内崭露头角,AI技术的竞争格局开始发生变化。这篇文章将详细对比这两款AI模型,从技术背景、应用领域、性能、成本效益等多个方…...
2025年Cursor最新安装使用教程
Cursor安装教程 一、Cursor下载二、Cursor安装三、Cursor编辑器快捷键(1) 基础编辑快捷键(2) 导航快捷键(3) 其他常用快捷键 一、Cursor下载 Cursor官方网站(https://www.cursor.com/ ) 根据自己电脑操作系统选择对应安装包 二、Cursor安装 下载完成后…...
原码、反码和补码的介绍和区别
在计算机中,有符号整数的表示方法主要有 原码、反码和补码,它们解决了二进制数表示正负数及简化运算的问题。以下是分步说明: 1. 原码(Sign-Magnitude) 定义:最高位为符号位(0正1负)…...
STM32 进阶 定时器
在stm32中定时器大概分为4类 1、系统定时器:属于arm内核,内嵌在NVIC中 2、高级定时器:可以用来刹车和死区 3、通用定时器:可以用来输出pwm方波 4、基本定时器:只能记数 系统定时器注意: 1、系统定时器…...
山东大学:《DeepSeek应用与部署》
大家好,我是吾鳴。 今天吾鳴要给大家分享一份由山东大学出版的DeepSeek报告——《DeepSeek应用与部署》,这份报告讲述了AIGC的发展历程,DeepSeek应用场景和DeepSeek如何本地化部署。报告一共80页PPT,文末有完整版下载地址。 内容摘…...
【无标题】FrmImport
文章目录 前言一、问题描述二、解决方案三、软件开发(源码)四、项目展示五、资源链接 前言 我能抽象出整个世界,但是我不能抽象你。 想让你成为私有常量,这样外部函数就无法访问你。 又想让你成为全局常量,这样在我的…...
Android14 OTA升级
因Vendor Freeze的缘故,若开启Non-AB OTA, 则会遇到交叉编译vendor和system的增量升级包时需要检查fingerprint而导致编译失败,从而无法做到增量升级包升级。高版本一般都是打开AB模式。 AB 和 non AB 切换相关宏 /vendor_ap_s0/device/mediatek/system/mssi_64_cn/SystemCo…...
监听 RabbitMQ 延时交换机的消息数、OpenFeign 路径参数传入斜杠无法正确转义
背景 【MQ】一套为海量消息和高并发热点消息,提供高可用精准延时服务的解决方案 我现在有一个需求,就是监听 RabbitMQ 一个延时交换机的消息数,而 RabbitTemplate 是不存在对应的方法来获取的。 而我们在 RabbitMQ 的控制台却可以发现延时交…...
宇树科技嵌入式面试题及参考答案(春晚机器人的公司)
目录 设计一个带看门狗(Watchdog)的嵌入式系统,描述故障恢复流程 在资源受限的 MCU 上实现 OTA 升级功能,描述关键设计点 如何实现 OTA(空中升级)功能?描述固件校验和回滚机制的设计要点 推挽输出与开漏输出的区别?举例说明其在 GPIO 控制中的应用 UART、SPI、I2C …...
Linux内核自定义协议族开发指南:理解net_device_ops、proto_ops与net_proto_family
在Linux内核中开发自定义协议族需要深入理解网络协议栈的分层模型。net_device_ops、proto_ops和net_proto_family是三个关键结构体,分别作用于不同的层次。本文将详细解析它们的作用、交互关系及实现方法,并提供一个完整的开发框架。 一、核心结构体的作用与层级关系 struct…...
【Go语言快速上手】第一部分:数据类型(数组、切片、映射)与控制语句
文章目录 一、复合类型Ⅰ 数组1. 语法2. 示例3. 特点4. 数组的传递 Ⅱ 切片1. 定义2. 语法3. 示例4. 特点5. 切片的创建6. 切片的操作切片的扩展切片的拷贝 Ⅲ 映射1. 定义2. 语法3. 示例4. 特点5. 映射的创建6. 映射的操作示例:插入、访问和删除判断键是否存在示例…...
系统架构评估中的重要概念
(1)敏感点(Sensitivity Point) 和权衡点 (Tradeoff Point)。敏感点和权衡点是关键的架构 决策。敏感点是一个或多个构件(和/或构件之间的关系)的特性。研究敏感点可使设计人员 或分析员明确在搞清楚如何实现质量目标时应注意什么。权衡点是影响多个质量属性的特性, …...
shell逐行读取文件 远程操作服务器
代码示例 while read ip; doecho "uninstalling test programs in $line" ssh root$ip bash -s < remote_remove_tool.shdone < installed_ips总结 ✅ 作用: 逐行读取 installed_ips 文件中的 IP 地址通过 SSH 连接到远程服务器ÿ…...
盛铂科技SCP4000射频微波功率计与SPP5000系列脉冲峰值 USB功率计 区别
在射频(RF)和微波测试领域,快速、精准的功率测量是确保通信系统、雷达、卫星设备等高性能运行的核心需求。无论是连续波(CW)信号的稳定性测试,还是脉冲信号的瞬态功率分析,工程师都需要轻量化、…...
【每日八股】计算机网络篇(三):IP
目录 DNS 查询服务器的基本流程DNS 采用 TCP 还是 UDP,为什么?默认使用 UDP 的原因需要使用 TCP 的场景?总结 DNS 劫持是什么?解决办法?浏览器输入一个 URL 到显示器显示的过程?URL 解析TCP 连接HTTP 请求页…...
vtk 3D坐标标尺应用 3D 刻度尺
2d刻度尺 : vtk 2D 刻度尺 2D 比例尺-CSDN博客 简介: 3D 刻度尺,也是常用功能,功能强大 3D 刻度尺 CubeAxesActor vtkCubeAxes调整坐标轴的刻度、原点和显示效果,包括关闭小标尺、固定坐标轴原点,以及设置FlyMode模…...
探秘基带算法:从原理到5G时代的通信变革【十】基带算法应用与对比
文章目录 三、算法在现代通信系统中的应用3.1 5G 通信中的应用3.1.1 信道编码与调制解调3.1.2 大规模 MIMO 技术3.1.3 案例分析:5G 基站与终端实现 3.2 卫星通信中的应用3.2.1 抗干扰与纠错编码3.2.2 信号处理与调制解调3.2.3 案例分析:卫星通信系统实例…...
消费级、工业级、汽车级、军工级、航天级芯片区别对比
汽车电子行业,经常会由于降本原因,听到“消规、工规、车规”方面的讨论。常见的芯片等级一般是按照使用温度、辐射、抗干扰等来分级。等级分为以下5类: 民用级(消费级)、工业级、汽车级(车规级)、军工级、航…...
迷你世界脚本背包接口:Backpack
背包接口:Backpack 彼得兔 更新时间: 2023-10-25 10:29:21 具体函数名及描述如下: 序号 函数名 函数描述 1 getBackpackBarIDRange(...) 获取道具背包栏ID范围(起始ID~结束ID) 2 getBackpackBarSize(...) 获取道具背包栏大小 3 setGridItem(.…...
javaSE基础
java跨平台性: Java 语言编写的程序,一次编译后,可以在多个操作系统上运行。是由于其增加了一个中间件 JVM,JVM 负责将 Java 字节码转换为特定平台的机器码,并执行。 Java 程序从源代码到运行需要经过三步:…...
电脑的系统版本是windows7的,下载pycharm的哪个版本比较好呢?
李升伟 整理 在Windows 7系统上选择PyCharm版本时,需综合考虑系统兼容性、Python版本适配性以及开发需求。以下是具体建议和操作指南: 1. 选择PyCharm的兼容版本 推荐版本:PyCharm 2020.3.5及之前的旧版本。 原因:自2021年起&a…...
【前端基础】3、HTML的常用元素(h、p、img、a、iframe、div、span)、不常用元素(strong、i、code、br)
HTML结构 一个HTML包含以下部分: 文档类型声明html元素 head元素body元素 例(CSDN): 一、文档类型声明 HTML最一方的文档称为:文档类型声明,用于声明文档类型。即:<!DOCTYPE html>…...
安装mysql
1、安装数据库 下载链接 https://downloads.mysql.com/archives/community/ 下载zip安装包,解压到某个路径下,将bin文件夹添加到系统环境变量 。 然后终端输入指令 mysql --version 验证 2、初始化数据库 打开命令提示符(以管理员身份&am…...
关于 QPalette设置按钮背景未显示出来 的解决方法
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/146047054 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
记一次ScopeSentry搭建
介绍 Scope Sentry是一款具有资产测绘、子域名枚举、信息泄露检测、漏洞扫描、目录扫描、子域名接管、爬虫、页面监控功能的工具,通过构建多个节点,自由选择节点运行扫描任务。当出现新漏洞时可以快速排查关注资产是否存在相关组件。 目前功能 插件系…...
【每日学点HarmonyOS Next知识】Web Header更新、状态变量嵌套问题、自定义弹窗、stack圆角、Flex换行问题
【每日学点HarmonyOS Next知识】Web Header更新、状态变量嵌套问题、自定义弹窗、stack圆角、Flex换行问题 1、HarmonyOS 有关webview Header无法更新的问题? 业务A页面 打开 webivew B页面,第一次打开带了header请求,然后退出webview B页面…...
优选算法的智慧之光:滑动窗口专题(二)
专栏:算法的魔法世界 个人主页:手握风云 目录 一、例题讲解 1.1. 最大连续1的个数 III 1.2. 找到字符串中所有字母异位词 1.3. 串联所有单词的子串 1.4. 最小覆盖子串 一、例题讲解 1.1. 最大连续1的个数 III 题目要求是二进制数组&am…...
Android ChatOn-v1.66.536-598-[构建于ChatGPT和GPT-4o之上]
ChatOn 链接:https://pan.xunlei.com/s/VOKYnq-i3C83CK-HJ1gfLf4gA1?pwdwzwc# 添加了最大无限积分 删除了所有调试信息 语言:全语言支持...
十一、Redis Sentinel(哨兵)—— 高可用架构与配置指南
Redis Sentinel(哨兵)—— 高可用架构与配置指南 在分布式应用中,Redis 主从复制(Master-Slave)虽然能提供读写分离的能力,但它 无法自动故障转移(failover)。如果主节点(Master)发生故障,系统管理员需要手动将某个从节点(Slave)提升为主节点,并重新配置所有从节…...
【STM32】玩转IIC之驱动MPU6050及姿态解算
目录 前言 一.MPU6050模块介绍 1.1MPU6050简介 1.2 MPU6050的引脚定义 1.3MPU6050寄存器解析 二.MPU6050驱动开发 2.1 配置寄存器 2.2对MPU6050寄存器进行读写 2.2.1 写入寄存器 2.2.2读取寄存器 2.3 初始化MPU6050 2.3.1 设置工作模式 2.3.2 配置采样率 2.3.3 启…...
《张一鸣,创业心路与算法思维》
张一鸣,多年如一日的阅读习惯。 爱读人物传记,称教科书式人类知识最浓缩的书,也爱看心理学,创业以及商业管理类的书。 冯仑,王石,联想,杰克韦尔奇,思科。 《乔布斯传》《埃隆马斯…...
深入浅出:UniApp 从入门到精通全指南
https://juejin.cn/post/7440119937644101684 uni-app官网 uniapp安卓离线打包流程_uniapp离线打包-CSDN博客 本文是关于 UniApp 从入门到精通的全指南,涵盖基础入门(环境搭建、创建项目、项目结构、编写运行)、核心概念与进阶知识&#x…...
低空经济-飞行数据平台 搭建可行方案
搭建一个飞行数据平台是低空经济中至关重要的一环,它能够实现对飞行器的实时监控、数据分析、路径优化以及安全管理。以下是搭建飞行数据平台的详细步骤和技术方案: 一、平台的核心功能 实时监控: 实时获取飞行器的位置、速度、高度、电池状态等数据。提供可视化界面,展示飞…...
【四.RAG技术与应用】【12.阿里云百炼应用(下):RAG的云端优化与扩展】
在上一篇文章中,我们聊了如何通过阿里云百炼平台快速搭建一个RAG(检索增强生成)应用,实现文档智能问答、知识库管理等基础能力。今天咱们继续深入,聚焦两个核心问题:如何通过云端技术优化RAG的效果,以及如何扩展RAG的应用边界。文章会穿插实战案例,手把手带你踩坑避雷。…...
3-7 WPS JS宏 工作表移动复制实例-2(多工作簿的多工作表合并)学习笔记
************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…...
【智能机器人开发全流程:硬件选型、软件架构与ROS实战,打造高效机器人系统】
文章目录 1. 硬件层设计(1) 传感器选型(2) 计算平台 2. 软件架构设计(1) 核心模块划分(2) 通信框架 3. 关键实现步骤(1) 硬件-软件接口开发(2) SLAM与导航实现(3) 仿真与测试 4. 典型框架示例基于ROS的移动机器人分层架构 5. 优化与扩展6. 开源项目参考 1. 硬件层设计 (1) 传感…...
【CSS—前端快速入门】CSS 选择器
CSS 1. CSS介绍 1.1 什么是CSS? CSS(Cascading Style Sheet),层叠样式表,用于控制页面的样式; CSS 能够对网页中元素位置的排版进行像素级精确控制,实现美化页面的效果;能够做到页面的样式和 结构分离; 1…...
二、QT和驱动模块实现智能家居-----5、通过QT控制LED
在QT界面,我们要实现点击“LED”按钮就可以控制板子上的LED。LED接线图如下: 在Linux 系统里,我们可以使用2种方法去操作上面的LED: ① 使用GPIO SYSFS系统:这需要一定的硬件知识,需要设置引脚的方向、数值…...
在UI设计中使用自定义控件
生成: 自定义控件完成: 看控件的父类是谁: 在想使用的窗口中: 拖动一个与他父类相同类型的控件: 点击控件右键 这样就是你自定义的控件了 运行后: //点击QSpinBox,滑块跟着移动void (QSpinBox::…...
docker 离线安装redis(离线)
docker离线安装redis时,我找了挺多资料都是需要先在另一台能联网的机器上先下载镜像,然后移动内网中的docker服务器进行部署,我也是这么操作的,但是必须拥有能上网的docker环境才能下载,我在github上找到了一种可以直接…...
利用python实现对Excel文件中数据元组的自定义排序
问题引入: 假设你是一个浙江省水果超市的老板,统筹11个下辖地市的水果产量。假设11个地市生产的水果包括:苹果、香蕉和西瓜。你如何快速得到某种水果产量突出(排名前几)的地市?产量落后(排名后…...
基于 Python 深度学习的电影评论情感分析可视化系统(2.0 全新升级)
基于 Python 深度学习的电影评论情感分析可视化系统,基于 Flask 深度学习,构建了一个 影评情感分析系统,能够 自动分析影评、计算情感趋势 并 可视化展示,对于电影行业具有重要参考价值! 基于 Python 深度学习的电影评…...
【MYSQL数据库异常处理】执行SQL语句报超时异常
MYSQL执行SQL语句异常:The last packet successfully received from the server was 100,107 milliseconds ago. The last packet sent successfully to the server was 100,101 milliseconds ago. 这个错误表明 MySQL 服务器与 JDBC 连接之间的通信超时了。通常由…...
docker拉取失败
备份原始配置文件 sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak 清理或修复 daemon.json 文件 sudo nano /etc/docker/daemon.json 删除 文件中的所有内容,确保文件为空。 cv下面这个文件内容 { "registry-mirrors": [ &…...
Linux的一些配置(网络建设与运维)
for i in 的指令使用集 传输内容指令 for i in {1..7};do ssh 10.4.220.10${i} "指令";done 传输文件指令 for i in {1..7};do scp 文件 root10.4.220.10${i}:文件位置;done DNS循环内容指令 for i in {1..7};do echo "linux$i A 10.4.220.10$i" >> …...
嵌入式L6计算机网络
Telnet不加密 socket是应用层和下面的内核...
大型语言模型演变之路:从Transformer到DeepSeek-R1
大型语言模型的崛起被认为是人工智能领域的一次革命,从2017年Transformer架构的引入开始,到2025年DeepSeek-R1的推出,每一步都在不断改变着人机交互的方式,推动着学术界与产业界的深度融合。 1. Transformer的引领(201…...
Idea配置注释模板
一、配置类注释模板 打开IDEA,打开settings(快捷键:Ctrl Alt s),选择Editor,找到File and Code Templates 这里以设置class文件为例,点击Class,在右侧配置以下内容 #if (${PACKAGE_NAME} && $…...
通过计费集成和警报监控 Elasticsearch Service 成本
作者:来自 Elastic Alexis Charveriat 使用 Elasticsearch 服务计费集成来跟踪、定制和提醒 Elasticsearch 服务费用。 监控和管理你的Elasticsearch服务(ESS)使用情况和成本对高效运营至关重要。 Elasticsearch服务计费集成提供了一种简化的…...