当前位置: 首页 > news >正文

【Android】画面卡顿优化列表流畅度五之下拉刷新上拉加载更多组件RefreshLayout修改

之前也写过类似组件的介绍:
地址:下拉刷新&上拉加载更多组件SmartRefreshLayout
在这里插入图片描述
本来打算用这个替换的,但在进行仔细研究发现不太合适。功能都很好,但嵌入不了当前的工程体系里。原因就是那啥体制懂的都懂。这样的组件需要改的工程配置参数会有不兼容。所以也就暂时用不了。
如果能用这个替换也不会组件问题了,大概是这样吧。
当前也是一款开源组件
回顾一下列表布局和逻辑处理:
xml布局

 <android.support.v4.widget.NestedScrollViewandroid:id="@+id/nestedScrollView"android:layout_width="match_parent"android:layout_height="match_parent"android:fillViewport="true"app:layout_behavior="@string/appbar_scrolling_view_behavior"><live.bingoogolapple.refreshlayout.BGARefreshLayoutandroid:id="@+id/mRefreshLayout"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"><android.support.v7.widget.RecyclerViewandroid:id="@+id/recycleView_playback"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#FFFFFFFF"android:nestedScrollingEnabled="false"android:paddingLeft="20dp"android:paddingRight="10dp"android:paddingBottom="8dp"app:layout_behavior="@string/appbar_scrolling_view_behavior" /></live.bingoogolapple.refreshlayout.BGARefreshLayout></android.support.v4.widget.NestedScrollView>

java逻辑处理:

 BGARefreshViewHolder bgaNormalRefreshViewHolder = new BGANormalRefreshViewHolder(this, true);mRefreshLayout.setRefreshViewHolder(bgaNormalRefreshViewHolder);nestedScrollView = findViewById(R.id.nestedScrollView);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {nestedScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {@Overridepublic void onScrollChange(View view, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {NestedScrollView toNesstedScrollView = (NestedScrollView) view;if (scrollY < 5|| toNesstedScrollView.getChildAt(0).getMeasuredHeight()== view.getMeasuredHeight()) {return;}int height = toNesstedScrollView.getChildAt(0).getMeasuredHeight()- view.getMeasuredHeight();if (scrollY == height) {// 为BGARefreshLayout 设置代理if(mRefreshLayout.getDelegate()==null){mRefreshLayout.setDelegate(XXXXActivity.this);}mRefreshLayout.beginLoadingMore();}}});}

这个布局是为了达到类似如下图这样的头部效果的:
在这里插入图片描述
这个之前也有过这样布局的博客介绍:【Android】折叠效果CoordinatorLayout+AppBarLayout首页效果&& CoordinatorLayout抖动问题解决方案–100个经典UI设计模板(95/100)

问题症结点

NestedScrollView嵌套子组件BGARefreshLayout;BGARefreshLayout嵌套子组件:RecyclerView;
滑动控制监听器是NestedScrollView组件里的OnScrollChangeListener:

nestedScrollView = findViewById(R.id.nestedScrollView);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {nestedScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {@Overridepublic void onScrollChange(View view, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {NestedScrollView toNesstedScrollView = (NestedScrollView) view;if (scrollY < 5|| toNesstedScrollView.getChildAt(0).getMeasuredHeight()== view.getMeasuredHeight()) {return;}int height = toNesstedScrollView.getChildAt(0).getMeasuredHeight()- view.getMeasuredHeight();if (scrollY == height) {// 为BGARefreshLayout 设置代理if(mRefreshLayout.getDelegate()==null){mRefreshLayout.setDelegate(XXXXActivity.this);mRefreshLayout.setParentView(nestedScrollView);}mRefreshLayout.beginLoadingMore();}}});}

导致了上拉刷新和下拉加载更多出现了监听问题
BGARefreshLayout里监听逻辑如下:

@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();// 被添加到窗口后再设置监听器,这样开发者就不必烦恼先初始化RefreshLayout还是先设置自定义滚动监听器if (!mIsInitedContentViewScrollListener && mLoadMoreFooterView != null) {setRecyclerViewOnScrollListener();setAbsListViewOnScrollListener();addView(mLoadMoreFooterView, getChildCount());mIsInitedContentViewScrollListener = true;}}

预期setRecyclerViewOnScrollListener()里的设置就没有生效:

/**** 具体效果要看xml布局结构* 比如下面这样的就不适用:* NestedScrollView*          BGARefreshLayout*                  RecyclerView** */private void setRecyclerViewOnScrollListener() {if (mRecyclerView != null) {mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic void onScrollStateChanged(RecyclerView recyclerView, int newState) {if ((newState == RecyclerView.SCROLL_STATE_IDLE|| newState == RecyclerView.SCROLL_STATE_SETTLING)&& shouldHandleRecyclerViewLoadingMore(mRecyclerView)) {beginLoadingMore();return;}}/*** dx : 水平滚动距离* dy : 垂直滚动距离* */@Overridepublic void onScrolled(RecyclerView recyclerView, int dx, int dy) {super.onScrolled(recyclerView, dx, dy);
//                    Log.d(TAG, "dx = " + dx + " ,dy= " + dy);if (dy < 0) {//时为手指向下滚动,列表滚动显示上面的内容mLoadMoreFooterView.setVisibility(GONE);}}});}}

找谁说理去,不生效就算了,问题是如果不留意。根本就发现不了这样的组件问题
NestedScrollView组件里的OnScrollChangeListener和RecyclerView.OnScrollListener效果是一致的都是开始加载更多逻辑beginLoadingMore():

/*** 开始上拉加载更多,会触发delegate的onBGARefreshLayoutBeginRefreshing方法*/public void beginLoadingMore() {Log.d(TAG, "beginLoadingMore: called!");if (!mIsLoadingMore && mLoadMoreFooterView != null&& mDelegate != null&& mDelegate.onBGARefreshLayoutBeginLoadingMore(this)) {mIsLoadingMore = true;Log.d(TAG, "run:mIsLoadingMore=" + mIsLoadingMore);if (mIsShowLoadingMoreView) {showLoadingMoreView();}}}/*** 显示上拉加载更多控件*/public void showLoadingMoreView() {mRefreshViewHolder.changeToLoadingMore();mLoadMoreFooterView.setVisibility(VISIBLE);mLoadMoreFooterView.findViewById(R.id.layout_loading).setVisibility(VISIBLE);mLoadMoreFooterView.findViewById(R.id.tv_normal_refresh_footer_status_finish).setVisibility(GONE);BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView);BGARefreshScrollingUtil.scrollToBottom(mScrollView);BGARefreshScrollingUtil.scrollToBottom(mRecyclerView);BGARefreshScrollingUtil.scrollToBottom(mAbsListView);if (mStickyNavLayout != null) {mStickyNavLayout.scrollToBottom();}}

BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView) 这个是优化后新加的;
如果没有这个就会出现了滑到底部就直接进行加载更多了,不会出现加载更多进度条的提示。需要在滑动到列表底部后再次向上拉一下才能有提示UI画面。这个太隐蔽了,每次感觉怪怪的,但就是没有发现这个交互画面有情况。主要是也不会朝这方面去想。因为看上去都很自然且正常。

showLoadingMoreView里这句代码
BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView)是告诉列表当滑动到底部的时候显示提示mLoadMoreFooterView视图后再自动的向上滑动一下,把LoadMoreFooterView显示在屏幕里。

BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView)逻辑如下:

 /*** nestedScrollView 滚动组件设置滚动到底部* 采用post(new runnable)方式在滚动组件渲染完成之后滚动到底部** @param nestedScrollView 滚动组件* */public static void scrollToBottom(final NestedScrollView nestedScrollView) {if (nestedScrollView != null) {nestedScrollView.post(new Runnable() {@Overridepublic void run() {nestedScrollView.fullScroll(ScrollView.FOCUS_DOWN);}});}}

小结一下

就是因为这个滑动效果不兼容所以导致了后面一系列的魔幻情况:
1、加载更多上拉交互的时候看不到加载更多提示UI,因为没有自动向上滑动到底;所以很多时候是没有看到
在这里插入图片描述
2、然后就会导致发起新一页数据的api请求调用的间隔时间混乱,有在短时间内多次调用的情况发生,然后再这个时间段内加载了大量的数据导致了页面卡住了。页面越卡,发起请求连续性导致的问题就越严重。然后用户会滑动更多次。陷入了死循环里了。检测到的某次调试的时候发起的连续的和预期不符的api数据请求记录如下图。
在这里插入图片描述
3、然后必然的内存消耗急剧加大,内存压力在很短的时间陡然上升(事实上优化到最后和内存的关系不是特别大,优化完以后也不过是使用了clearMemory

以上这些问题都是RefreshLayout使用不当导致的。但不投入大量的精力去仔细的分析网络数据、内存、交互等几乎发现不了。因为手机画面表现的很像是内存问题,因此在内存上折腾了两三天也没起到缓解卡顿的预期。

解决方案

最后附上优化后的RefreshLayout逻辑处理:

import live.bingoogolapple.refreshlayout.util.BGARefreshScrollingUtil;/*** 作者:王浩 邮件:bingoogolapple@gmail.com* 创建时间:15/5/21 22:35* 描述:下拉刷新、上拉加载更多、可添加自定义(固定、可滑动)头部控件(例如慕课网app顶部的广告位)*/
public class BGARefreshLayout extends LinearLayout {/*** 目前已经适配的滚动组件有:*  AbsListView*  ScrollView*  NestedScrollView*  RecyclerView**  在滚动到底部时自动在底部增加弹出"正在加载中的"进度条提示* */private AbsListView mAbsListView;private ScrollView mScrollView;private NestedScrollView mParentNestedScrollView;// 外层父组件嵌套 NestedScrollViewprivate RecyclerView mRecyclerView;private View mNormalView;private WebView mWebView;private BGAStickyNavLayout mStickyNavLayout;private View mContentView;private float mInterceptTouchDownX = -1;private float mInterceptTouchDownY = -1;/*** 按下时整个头部控件的paddingTop*/private int mWholeHeaderViewDownPaddingTop = 0;/*** 记录开始下拉刷新时的downY*/private int mRefreshDownY = -1;/*** 是否已经设置内容控件滚动监听器*/
。。。/*** xml布局中构造* */public BGARefreshLayout(Context context, AttributeSet attrs) {super(context, attrs);setOrientation(LinearLayout.VERTICAL);mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();mHandler = new Handler(Looper.getMainLooper());initWholeHeaderView();}。。。/*** {@link BGARefreshLayout} 外层嵌套一个父滚动组件适配* 目前适配了NestedScrollView 作为父组件** */public void setParentView(View view) {if (null == view)return;/*** 布局嵌套为* NestedScrollView*          BGARefreshLayout*                  RecyclerView* */if (view instanceof NestedScrollView) {mParentNestedScrollView = (NestedScrollView) view;}}/*** 初始化上拉加载更多控件** @return*/private void initLoadMoreFooterView() {mLoadMoreFooterView = mRefreshViewHolder.getLoadMoreFooterView();if (mLoadMoreFooterView != null) {// 测量上拉加载更多控件的高度mLoadMoreFooterView.measure(0, 0);mLoadMoreFooterViewHeight = mLoadMoreFooterView.getMeasuredHeight();mLoadMoreFooterView.setVisibility(GONE);mLoadMoreFooterView.findViewById(R.id.layout_loading).setVisibility(GONE);mLoadMoreFooterView.findViewById(R.id.tv_normal_refresh_footer_status_finish).setVisibility(GONE);}}/**** 具体效果要看xml布局结构* 比如下面这样的就不适用:* NestedScrollView*          BGARefreshLayout*                  RecyclerView** */private void setRecyclerViewOnScrollListener() {if (mRecyclerView != null) {mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic void onScrollStateChanged(RecyclerView recyclerView, int newState) {if ((newState == RecyclerView.SCROLL_STATE_IDLE|| newState == RecyclerView.SCROLL_STATE_SETTLING)&& shouldHandleRecyclerViewLoadingMore(mRecyclerView)) {beginLoadingMore();return;}}/*** dx : 水平滚动距离* dy : 垂直滚动距离* */@Overridepublic void onScrolled(RecyclerView recyclerView, int dx, int dy) {super.onScrolled(recyclerView, dx, dy);
//                    Log.d(TAG, "dx = " + dx + " ,dy= " + dy);if (dy < 0) {//时为手指向下滚动,列表滚动显示上面的内容mLoadMoreFooterView.setVisibility(GONE);}}});}}/**/*** 开始上拉加载更多,会触发delegate的onBGARefreshLayoutBeginRefreshing方法*/public void beginLoadingMore() {Log.d(TAG, "beginLoadingMore: called!");if (!mIsLoadingMore && mLoadMoreFooterView != null&& mDelegate != null&& mDelegate.onBGARefreshLayoutBeginLoadingMore(this)) {mIsLoadingMore = true;Log.d(TAG, "run:mIsLoadingMore=" + mIsLoadingMore);if (mIsShowLoadingMoreView) {showLoadingMoreView();}}}/*** 显示上拉加载更多控件*/public void showLoadingMoreView() {mRefreshViewHolder.changeToLoadingMore();mLoadMoreFooterView.setVisibility(VISIBLE);mLoadMoreFooterView.findViewById(R.id.layout_loading).setVisibility(VISIBLE);mLoadMoreFooterView.findViewById(R.id.tv_normal_refresh_footer_status_finish).setVisibility(GONE);BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView);BGARefreshScrollingUtil.scrollToBottom(mScrollView);BGARefreshScrollingUtil.scrollToBottom(mRecyclerView);BGARefreshScrollingUtil.scrollToBottom(mAbsListView);if (mStickyNavLayout != null) {mStickyNavLayout.scrollToBottom();}}/*** 结束上拉加载更多*/public void endLoadingMore() {if (mIsShowLoadingMoreView) {// 避免WiFi环境下请求数据太快,加载更多控件一闪而过mRecyclerView.postDelayed(mDelayHiddenLoadingMoreViewTask, 300);}}public void setStatusFinish() {mLoadMoreFooterView.setVisibility(VISIBLE);mLoadMoreFooterView.findViewById(R.id.tv_normal_refresh_footer_status_finish).setVisibility(VISIBLE);BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView);BGARefreshScrollingUtil.scrollToBottom(mScrollView);BGARefreshScrollingUtil.scrollToBottom(mRecyclerView);BGARefreshScrollingUtil.scrollToBottom(mAbsListView);if (mStickyNavLayout != null) {mStickyNavLayout.scrollToBottom();}}

主要是新增了对NestedScrollView的处理逻辑;也是为了适配如下这样的xml布局:

 /*** 布局嵌套为* NestedScrollView*          BGARefreshLayout*                  RecyclerView* */

再加上 BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView);处理完成了这个上拉加载更多的数据分页加载逻辑衔接处理。
优化这个组件之后加载顺滑度立马就干到数据量800条以内滑动和加载都没有明显的卡顿感了。
但问题还没有彻底解决,因为数据量干到1000条左右就出现了ANR问题和OOM内存问题了。虽然这两个问题没有得到彻底的解决,但大致的解决方案也有方向。
先到这里歇一歇,后面还有一篇

smartApi接口开发工具推荐

历时一年半多开发终于smartApi-v1.0.0版本在2023-09-15晚十点正式上线
smartApi是一款对标国外的postman的api调试开发工具,由于开发人力就作者一个所以人力有限,因此v1.0.0版本功能进行精简,大功能项有:

  • api参数填写
  • api请求响应数据展示
  • PDF形式的分享文档
  • Mock本地化解决方案
  • api列表数据本地化处理
  • 再加上UI方面的打磨

下面是一段smartApi使用介绍:
在这里插入图片描述

下载地址:

https://pan.baidu.com/s/1kFAGbsFIk3dDR64NwM5y2A?pwd=csdn

相关文章:

【Android】画面卡顿优化列表流畅度五之下拉刷新上拉加载更多组件RefreshLayout修改

之前也写过类似组件的介绍&#xff1a; 地址&#xff1a;下拉刷新&上拉加载更多组件SmartRefreshLayout 本来打算用这个替换的&#xff0c;但在进行仔细研究发现不太合适。功能都很好&#xff0c;但嵌入不了当前的工程体系里。原因就是那啥体制懂的都懂。这样的组件需要改…...

【Android】导入三方jar包/系统的framework.jar

1.Android.mk导包 1).jar包位置 与res和src同一级的libs中(没有就新建) 2).Android.mk文件 LOCAL_STATIC_ANDROID_LIBRARIES&#xff1a;android静态库&#xff0c;经常用于一些support的导包 LOCAL_JAVA_LIBRARIES&#xff1a;依赖的java库&#xff0c;一般为系统的jar…...

在线升级 redis 到7.2.2

1. 操作环境与升级思路 先安装新的版本新版本设置主从备份&#xff0c;将老版本与新版本的数据进行同步新启动一个服务&#xff0c;连接新版本redis&#xff0c;切换到新服务&#xff0c;关闭主从备份kill 老服务, 卸载老版本redis 因为我需要 RedisSearch 所以直接安装 Redi…...

社区新零售:改变生活方式的创新商业模式

社区新零售&#xff1a;改变生活方式的创新商业模式 社区新零售&#xff0c;顾名思义&#xff0c;以社区为核心&#xff0c;利用互联网、大数据、人工智能等先进技术&#xff0c;将线上购物和线下体验有机结合&#xff0c;形成一种全新的零售模式。它特别强调地理位置的便利性&…...

MySQL/SQLServer判断字符是纯数字或者是其它字符

如下是MySQL表结构设计&#xff08;演示所用&#xff09;&#xff1a; MySQL表关联数据如下所示&#xff1a; 【场景&#xff1a;查询所有数字&#xff0c;包含小数点】&#xff0c;SQL如下所示&#xff1a; SELECT * FROM data WHERE message not REGEXP [^0-9].[^0-9] My…...

Threejs_02 父子位移+缩放改变

threejs中如何做出一堆父子来呢&#xff1f; 父子制作 1.做一个父元素 想要做一个元素 需要材质和模型&#xff0c;然后使用threejs的方法THREE.Mesh就可以制作出来 // 创建一个集合体 (立方体) const geometry new THREE.BoxGeometry(1, 1, 1); // 创建材质 (16进制颜色…...

LuatOS-SOC接口文档(air780E)--nimble - 蓝牙BLE库(nimble版)

示例 -- 本库当前支持Air101/Air103/ESP32/ESP32C3/ESP32S3 -- 用法请查阅demo, API函数会归于指定的模式-- 名称解释: -- peripheral 外设模式, 或者成为从机模式, 是被连接的设备 -- central 中心模式, 或者成为主机模式, 是扫描并连接其他设备 -- ibeacon 周期性的be…...

医疗器械展示预约小程序的效果如何

医疗器械行业涵盖的内容非常广&#xff0c;市场中大小从业的品牌/门店也很多&#xff0c;比如我们常见的轮椅、康复器械、拐杖、血压仪等产品市场需求都非常高&#xff0c;当然还有医院里用的器械等。 医疗器械市场呈现多品牌、多门店的发展趋势&#xff0c;虽然这些东西不是必…...

【Vue原理解析】之异步与优化

引言 Vue是一款流行的JavaScript框架&#xff0c;它提供了一些强大的特性来提升应用程序的性能和用户体验。在本文中&#xff0c;我们将深入探讨Vue的异步更新机制和一些优化技巧&#xff0c;帮助您更好地理解和应用这些特性。 异步更新机制 Vue使用异步更新机制来提高渲染性…...

mybatis、mysql 创建时间(create_time)异常自动更新为当前时间

目录标题 一、问题二、原因三、解决 一、问题 bug: mybatis更新代码没有修改时间&#xff0c;但是时间会自动更新为当前时间。 。。。 被坑了挺久 二、原因 可能是创建表的时候&#xff0c; Navicat Premium 等可视化工具给你整活了。。。 三、解决 取消勾选。 注意&…...

shardingsphere 加载慢 优化

shardingsphere加载慢 优化 原因&#xff1a; 启动速度变慢(元数据扫描耗时较长) 占用内存增多(大量单表和元数据对象) 那是因为默认扫描1张表.一张一张加载巨慢,添加以下配置增加到20张表同时扫描 错误&#xff1a; 如果你数据库最大连接不到20就会报错&#xff0c;请按照数据…...

我这些年对于自动化测试的理解

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…...

Java安全架构 JCA、JCE、JSSE、JAAS

Java语言拥有三大特征&#xff1a;平台无关性、网络移动性和安全性&#xff0c;而Java安全体系结构对这三大特征提供了强大的支持和保证&#xff0c; Java安全体系结构总共分为4个部分&#xff1a; &#xff08;1&#xff09;JCA&#xff08; Java Cryptography Architecture…...

面试经典(4/150)删除有序数组中的重复项 II

面试经典&#xff08;4/150&#xff09;删除有序数组中的重复项 II 给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c; 返回删除后数组的新长度。不要使用额外的数组空间&#xff0c;你必须在 原…...

使用WildCard充值ChatGPT Plus 会员

登录 wildCard官网 基于国内手机号注册账号&#xff0c;使用支付宝验证付款即可自动申请国外银行卡&#xff0c;WildCard的开卡费是9.9美元, 没有后续的月费用.订阅chatgpt plus会员服务的操作图文指南见链接 chatgpt plus会员订阅指南...

element-plus使用el-date-picker组件时,如何禁止用户选择当前时间之后的日时分秒

element-plus使用el-date-picker组件时&#xff0c;如何禁止用户选择当前时间之后的日时分秒 例&#xff1a; 当前时间为2023-11-15 14.24&#xff0c;不能选择这之后的时分秒。&#xff08;禁止用户选择2023-11-15 14.28&#xff09; <el-date-pickerv-model"form.s…...

keepalived安装配置(服务器主备、负载均衡)

系统拓扑 安装keepalived 主备服务器上都需要安装 在线安装 yum install -y keepalived 离线安装 # todo 服务器准备 虚拟机ip&#xff1a;192.168.11.56 主服务器&#xff1a;192.168.11.53 备服务器&#xff1a;192.168.11.54 配置文件修改 keepalived安装之后&…...

盘点一款制作电子杂志的网站,小白也能快速上手

​电子杂志作为一种时尚、环保、便捷的宣传形式&#xff0c;越来越受到各行各业的青睐。无论是企业宣传、产品推广&#xff0c;还是个人分享&#xff0c;电子杂志都能展现出独特的魅力。而制作电子杂志&#xff0c;不再是专业人士的专属&#xff0c;现在小白也能快速上手&#…...

全域全自主建设,亚信科技AntDB数据库助力广电5G业务上线运行

自2019年6月&#xff0c;中国广电成功获得5G牌照以来&#xff0c;迅速推进网络建设目标&#xff0c;成为5G网络覆盖广、应用场景多、用户体验出色的第四大运营商。其依托全球独有的700MHz频谱资源&#xff0c;具备覆盖能力强、容量足、速率高的优势。通过不断深化和中国移动的共…...

使用 SSH 密钥进行身份验证

使用 SSH 密钥进行身份验证可以提高安全性&#xff0c;并免去每次登录时输入密码的麻烦。以下是使用 SSH 密钥进行身份验证的步骤&#xff1a; 生成密钥对&#xff1a;在本地计算机上生成 SSH 密钥对。打开终端并执行以下命令&#xff1a; ssh-keygen -t rsa -b 4096这将生成…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...