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

Android imageView.setImageXXX() 引发的卡顿问题

在 Android 开发中,ImageView 是一个用户界面控件,用于在应用中显示图片。它是 Android UI 组件库中一个非常基础和常用的部分。使用 ImageView,你可以在屏幕上显示来自不同来源的图像,比如位图文件、绘图资源 drawable、网络来源或者相机拍摄的图片。

在实际的开发过程中,我们会在 Java 或 Kotlin 代码中调用 setImageResource()、setImageBitmap()、setImageDrawable() 等方法来设置或改变图片。

但我最近在检测应用的性能时,发现 imageView 在加载图片竟有一些耗时,于是进入源码来看看这几个给 imageView 设置图片的方法都有什么区别


imageView.setImageResource():

    public void setImageResource(@DrawableRes int resId) {final int oldWidth = mDrawableWidth;final int oldHeight = mDrawableHeight;updateDrawable(null);mResource = resId;mUri = null;resolveUri();if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {requestLayout();}invalidate();}

在 setImageResource 方法中,首先 updateDrawable() 做了重置操作,后面给成员变量 mResource 赋值,接着执行 resolveUri() 这个方法对 mResource 进行解析

    private void resolveUri() {Drawable d = null;if (mResource != 0) {try {// 根据传进来的资源ID去获取对应的Drawable(耗时)d = mContext.getDrawable(mResource); } catch (Exception e) {// Don't try again.mResource = 0;}} else if (mUri != null) {d = getDrawableFromUri(mUri);if (d == null) {// Don't try again.mUri = null;}} else {return;}updateDrawable(d);}

resolveUri() 方法中会将刚刚传进来的 mResource 去获取对应的 Drawable,获取到 Drawble 后通过调用 updateDrawable() 来更新 imageView 中的图像


imageView.setImageBitmap():

    public void setImageBitmap(Bitmap bm) {mDrawable = null;if (mRecycleableBitmapDrawable == null) {mRecycleableBitmapDrawable = new BitmapDrawable(mContext.getResources(), bm);} else {mRecycleableBitmapDrawable.setBitmap(bm);}setImageDrawable(mRecycleableBitmapDrawable);}

setImageBitmap 代码非常少,首先确定有一个 BitmapDrawable 对象,将传进来的 Bitmap 赋值于此,然后调用 setImageDrawable() 方法


imageView.setImageDrawable():

    public void setImageDrawable(@Nullable Drawable drawable) {if (mDrawable != drawable) {mResource = 0;mUri = null;final int oldWidth = mDrawableWidth;final int oldHeight = mDrawableHeight;updateDrawable(drawable);if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {requestLayout();}invalidate();}}

在 setImageDrawable 方法中,直接将传进来的 Drawable 来调用 updateDrawable() 方法来更新imageView() 中的图像


总结:
用这三种方法去更新 imageView 最终都会调用到 updateDrawable() 这个方法,但是在 setImageResource() 中的 resolveUri() 方法涉及到了资源获取:mContext.getDrawable(),这个是耗时的,所以在短时间内调用大量的 setImageResource 可能会造成应用卡顿。

解决方法:
将资源 ID 获取到的 Drawable 进行缓存或者设置为成员变量,再调用 setImageDrawable() 即可。这样子能避免资源获取而造成的卡顿。


此外,ImageView 还提供了其他方法,如 setImageURI(Uri uri),用于通过 URI 设置图像,但无论哪种设置图像的方法,最终都是通过 Drawable 来实现图像的渲染。所以在短时间内大量设置imageView 图像时,需要优先缓存 Drawable 来加载图像来保证性能是最佳的

http://www.lryc.cn/news/290229.html

相关文章:

  • MavenGradle等引入jSerialComm
  • 热门技术问答 | 请 GaussDB 用户查收
  • 【C/C++ 01】初级排序算法
  • Android Settings 显示电池点亮百分比
  • Windows记事本不显示下划线的原因及解决方法
  • 嵌入式软件工程师面试题——2025校招社招通用(C/C++)(四十六)
  • 【学网攻】 第(13)节 -- 动态路由(OSPF)
  • Asp.Net Core 获取应用程序相关目录
  • 文献速递:人工智能医学影像分割--- 深度学习分割骨盆骨骼:大规模CT数据集和基线模型
  • PaddleNLP的简单使用
  • 2. MySQL 多实例
  • 两个五层决策树和一个十层决策树的区别
  • 案例分析技巧-软件工程
  • 如何使用docker compose安装APITable并远程访问登录界面
  • 深入了解Matplotlib中的子图创建方法
  • 云计算运维 · 第三阶段 · git
  • 【幻兽帕鲁】开服务器,高性能高带宽(100mbps),免费!!!【学生党强推】
  • 微信小程序|推箱子小游戏
  • 【Linux】—— 信号的产生
  • 【算法】Hash 算法-关注优化细节
  • 回归预测 | Matlab实现CPO-SVR冠豪猪优化支持向量机的数据多输入单输出回归预测
  • Idea设置代理后无法clone git项目
  • tkMapper 通用mapper的批量更新 批量新增 官方实现 springboot项目 依赖引入
  • 【leetcode刷刷】回溯:77.组合
  • 【OOP】Python的OOP编程笔记
  • 一进一出模拟量信号隔离变送器
  • Mybatis-plus原生pages分页未生效的解决方案
  • 【linux】-centos7版本前后-变化篇
  • 001集—shapefile(.shp)格式详解——arcgis
  • ssrf服务器请求伪造漏洞(个人学习)