Android进阶:ListView性能优化异步加载图片 使滑动效果流畅

这篇具有很好参考价值的文章主要介绍了Android进阶:ListView性能优化异步加载图片 使滑动效果流畅。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ListView 是一种可以显示一系列项目并能进行滚动显示的 View,每一行的Item可能包含复杂的结构,可能会从网络上获取icon等的一些图标信息,就现在的网络速度要想保持ListView运行的很好滚动流畅是做不到的

所以这里就需要把这些信息利用多线程实现异步加载

实现这样功能的类

  1. public class AsyncImageLoader {
  2. private HashMap<String, SoftReference<Drawable>> imageCache;
  3. public AsyncImageLoader() {
  4. imageCache = new HashMap<String, SoftReference<Drawable>>();
  5. }
  6. public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
  7. if (imageCache.containsKey(imageUrl)) {
  8. SoftReference<Drawable> softReference = imageCache.get(imageUrl);
  9. Drawable drawable = softReference.get();
  10. if (drawable != null) {
  11. return drawable;
  12. }
  13. }
  14. final Handler handler = new Handler() {
  15. @Override
  16. public void handleMessage(Message message) {
  17. imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
  18. }
  19. };
  20. new Thread() {
  21. @Override
  22. public void run() {
  23. Drawable drawable = loadImageFromUrl(imageUrl);
  24. imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
  25. Message message = handler.obtainMessage(0, drawable);
  26. handler.sendMessage(message);
  27. }
  28. }.start();
  29. return null;
  30. }
  31. public static Drawable loadImageFromUrl(String url) {
  32. // ...
  33. }
  34. public interface ImageCallback {
  35. public void imageLoaded(Drawable imageDrawable, String imageUrl);
  36. }
  37. }

注意这里使用了 SoftReference来缓存图片,允许 GC在需要的时候可以对缓存中的图片进行清理。它这样工作:

·         调用 loadDrawable(ImageUrl, imageCallback),传入一个匿名实现的 ImageCallback接口

·         如果图片在缓存中不存在的话,图片将从单一的线程中下载并在下载结束时通过 ImageCallback回调

·         如果图片确实存在于缓存中,就会马上返回,不会回调 ImageCallback

然后我们还可以根据09google I/0开发者大会提到的方式来继续优化Adapter 使用ViewHolder来减少一些比较费时的操作,譬如inflate XML 和 findViewById()等操作

  1. public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText> {
  2. private ListView listView;
  3. private AsyncImageLoader asyncImageLoader;
  4. public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {
  5. super(activity, 0, imageAndTexts);
  6. this.listView = listView;
  7. asyncImageLoader = new AsyncImageLoader();
  8. }
  9. @Override
  10. public View getView(int position, View convertView, ViewGroup parent) {
  11. Activity activity = (Activity) getContext();
  12. // Inflate the views from XML
  13. View rowView = convertView;
  14. ViewCache viewCache;
  15. if (rowView == null) {
  16. LayoutInflater inflater = activity.getLayoutInflater();
  17. rowView = inflater.inflate(R.layout.image_and_text_row, null);
  18. viewCache = new ViewCache(rowView);
  19. rowView.setTag(viewCache);
  20. } else {
  21. viewCache = (ViewCache) rowView.getTag();
  22. }
  23. ImageAndText imageAndText = getItem(position);
  24. // Load the image and set it on the ImageView
  25. String imageUrl = imageAndText.getImageUrl();
  26. ImageView imageView = viewCache.getImageView();
  27. imageView.setTag(imageUrl);
  28. Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() {
  29. public void imageLoaded(Drawable imageDrawable, String imageUrl) {
  30. ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
  31. if (imageViewByTag != null) {
  32. imageViewByTag.setImageDrawable(imageDrawable);
  33. }
  34. }
  35. });
  36. imageView.setImageDrawable(cachedImage);
  37. // Set the text on the TextView
  38. TextView textView = viewCache.getTextView();
  39. textView.setText(imageAndText.getText());
  40. return rowView;
  41. }
  42. }

这里我们没有加载完iamge之后直接设定到相应的ImageView上 ,而是通过Tag查找,这里我们重用的View 这里有个listView的引用来通过Tag查找 可见 CallBack的实现

  1. ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
  2. if (imageViewByTag != null) {
  3. imageViewByTag.setImageDrawable(imageDrawable);
  4. }

这里通过ViewCatch来减少了 findViewById的使用

  1. public class ViewCache {
  2. private View baseView;
  3. private TextView textView;
  4. private ImageView imageView;
  5. public ViewCache(View baseView) {
  6. this.baseView = baseView;
  7. }
  8. public TextView getTextView() {
  9. if (textView == null) {
  10. textView = (TextView) baseView.findViewById(R.id.text);
  11. }
  12. return titleView;
  13. }
  14. public ImageView getImageView() {
  15. if (imageView == null) {
  16. imageView = (ImageView) baseView.findViewById(R.id.image);
  17. }
  18. return imageView;
  19. }
  20. }

总结 :这里主要做了三点优化文章来源地址https://www.toymoban.com/news/detail-601213.html

  • 在单一线程里加载图片
  • 重用列表中行
  • 缓存行中的 View

到了这里,关于Android进阶:ListView性能优化异步加载图片 使滑动效果流畅的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 利用uniapp中模仿抖音、滑动视频组件、首个视频自动播放、预加载、实现加载更多,超高性能

    抖音效果图 本内容主要实现了滑动视频组件、首个视频自动播放、预加载、实现加载更多,超高性能, 前言:最近在做短剧,于是就在网上找了很多不错的例子,但是不是很完美,基本上都比较卡顿,我也是在站在巨人的肩膀上优化了一下。本片主要基于vue3、setup和ts开发的

    2024年02月04日
    浏览(69)
  • QML Image 通过 QQuickAsyncImageProvider 异步加载图片

    相关:QML Image 通过 QQuickImageProvider 加载图片-CSDN博客 根据 QQuickImageProvider 的文档说明,该类其实是支持在独立线程中异步加载的,但是 Async 类提供了专用于异步加载的接口,操作起来也不复杂,对于大文件或者网络文件,都可以采用异步方式加载图片。 继续 QQuickAsyncImag

    2024年01月19日
    浏览(42)
  • Android AsyncLayoutInflater 异步加载布局

    AsyncLayoutInflater 是 Android 提供的 一个用于异步加载布局的 工具类 。可以在异步线程上加载布局文件,以 避免 在主线程上加载布局过于耗时而导致的 UI  卡顿 问题。 通常情况下,使用传统的 LayoutInflater 在主线程上加载布局时,如果布局文件较为复杂或包含大量视图,会导

    2024年02月11日
    浏览(40)
  • java使用双异步,性能优化

    通过POI读取需要导入的Excel; 以文件名为表名、列头为列名、并将数据拼接成sql; 通过JDBC或mybatis插入数据库; 操作起来,如果文件比较多,数据量都很大的时候,会非常慢。 访问之后,感觉没什么反应,实际上已经在读取 + 入库了,只是比较慢而已。 读取一个10万行的E

    2024年01月23日
    浏览(45)
  • 前端面试:【性能优化】页面加载性能、渲染性能、资源优化

    嗨,亲爱的前端开发者!在今天的Web世界中,用户期望页面加载速度快、交互流畅。因此,前端性能优化成为了至关重要的任务。本文将探讨三个关键方面的性能优化:页面加载性能、渲染性能以及资源优化,以帮助你构建更快速、响应更快的Web应用程序。 1. 页面加载性能:

    2024年02月11日
    浏览(50)
  • Android Studio实现滑动图片验证码

    源代码链接 效果: MainActivity SlideImageView activity_main.xml

    2024年02月13日
    浏览(45)
  • 异步I/O优化Python代理程序性能

    作为一名爬虫程序员,你是否曾经遇到过需要处理大量网络请求的情况?你是否想要提高你的Python代理程序的性能,让它更快、更高效?别担心,我来给你分享一些关于异步I/O如何优化Python代理程序性能的实用知识。 首先,让我们来了解一下什么是异步I/O。在传统的同步I/

    2024年02月11日
    浏览(35)
  • vue前端性能优化之分包策略、异步组件、Gzip压缩

    目录 一、Gzip压缩 二、异步组件 三、分包策略 最后           项目的性能优化是有完整项目经历的开发者都会遇到得一个问题。这是整个项目开发最后的一步,也是最关键的一步,做一个项目并不是单单完成功能就算结束了,作为开发者,更要站在用户角度去进行项目体

    2024年02月09日
    浏览(49)
  • Web 前端性能优化之三:加载优化

    2、加载优化 1、延迟加载 本着节约不浪费的原则,在首次打开网站时,应尽量只加载首屏内容所包含的资源,而首屏之外涉及的图片或视频,可以等到用户滚动视窗浏览时再去加载。以上就是延迟加载优化策略的产生逻辑,通过延迟加载“非关键”的图片及视频资源,使得页

    2024年04月26日
    浏览(43)
  • 【 Vue3 性能优化】页面加载性能 与 更新性能

    Vue 在大多数常见场景下性能都是很优秀的,通常不需要手动优化。然而,总会有一些具有挑战性的场景需要进行针对性的微调。 数字化管理平台 Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus教程 权限系统-商城 个人博客地址 Web 性能优化主要有两个方面: 页面加载性能 首次访问时,应

    2024年02月14日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包