返回顶部
首页 > 资讯 > 移动开发 >Android异步回调中的UI同步性问题分析
  • 198
分享到

Android异步回调中的UI同步性问题分析

回调Android 2022-06-06 08:06:06 198人浏览 泡泡鱼
摘要

Android程序编码过程中,回调无处不在。从最常见的Activity生命周期回调开始,到BroadcastReceiver、Service以及sqlite等。Activity

Android程序编码过程中,回调无处不在。从最常见的Activity生命周期回调开始,到BroadcastReceiver、Service以及sqlite等。Activity、BroadcastReceiver和Service这些基本组件的回调路径和过程也就是通常意义上所谓的“生命周期”。同时,在处理具体的业务逻辑时,常常设计到不同线程之间的通信,如下载图片完成后通知 UI线程更新UI,凡此类场景,无论使用哪一种具体的线程间通信方式(Handler/Message、Handler/post、基于接口的回调、基于多对多的观察者模式如EventBus等),其本质上都是基于“回调”。在实际编码过程中,凡涉及到不同线程之间的通信,本质上更是属于“异步回调”。当需要在“异步回调”中修改UI时,此时需要特别注意UI同步性问题。

为了便于问题的阐述,在此先对“Android异步回调UI同步性问题”进行如下界定:当异步回调执行时(称之为“异步回调执行点”),当前UI界面上的元素与最初生成此异步回调的调用器开始执行时(称之为“异步回调生成点”)的UI元素已经存在不一致,不一致不仅包括UI元素可能的界面变化、可能的内容变化,也包括“异步回调执行点”和“异步回调生成点”时的UI元素中的某一特性的表征量(如某一具有表征当前UI元素的字段值)相关,即使UI元素界面和内容都尚未发生变化。

编码过程中,“Android异步回调UI同步性问题”经常存在,有时候稍不注意会产生一些看起来难以理解的bug,并由于异步特性的存在,此类bug还具有一定的随机性。有时候由于一些需求的复杂性,此类bug隐蔽性很强,也容易被忽略。至少到目前为止,在实际开发中,本人遇到此类问题已有数个。

纯文字的描述可能不太好理解,下面以一个很常用的Android-Universal-Image-Loader为例,简单举例一个潜在存在的“Android异步回调UI同步性问题”。

ListView Item View中有ImageView,通过Android-Universal-Image-Loader去加载显示,图片加载完成后需要做一些逻辑处理(如隐藏图片加载进度条等..),通常代码如下:


ImageLoader.getInstance().loadImage(imageUrl, new ImageLoadingListener() {
 @Override
 public void onLoadinGComplete(String imageUri, View view, Bitmap loadedImage) {
  if (loadedImage != null) {
   imageView.setImageBitmap(loadedImage);
   // 其他业务逻辑处理..
  }
 }
 @Override
 public void onLoadingStarted(String imageUri, View view) {
 }
 @Override
 public void onLoadingCancelled(String arg0, View arg1) {
 }
 @Override
 public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
 }
});

初看上去,代码逻辑好像也没什么问题,网上大部分人也是这么写的。当较慢滑动ListView时,或在平时正常使用时,也没有什么问题。但是此处的代码逻辑真的严密吗?

ListView的getView复用特性,大家也都熟知。对于之前遇到的“图片错位/先显示之前的图片后再被正确的图片覆盖掉”,此类现象也都知道如何解决(在getView逻辑开始处理处将ImageView设置成最先的默认图片,其他UI元素类似处理),基本上也不会再有“图片错位/先显示之前的图片后再被正确的图片覆盖掉”这类现象了。实际上,当网速条件一般,且loadImage大致与上述代码所示,在ListView中快速滑动列表,几屏后,不出意外,会发现“图片错位/先显示之前的图片后再被正确的图片覆盖掉”此问题依然存在。

此时问题出现的原因不在于getView本身,因为getView逻辑开始时已经将ImageView重置为默认图片,而在于“Android异步回调UI同步性问题”。由于ViewHolder的不断复用,网速一般时快速滑动几屏后,onLoadingComplete的异步回调执行时与当前UI元素已经存在不一致,简单点理解,ImageView被复用了ImageView position 0,ImageView position 11, ImageView position 21,此时滑动停止,onLoadingComplete的异步回调执行时ImageView已经是最后一次的ImageView position 21,而onLoadingComplete的异步回调可能被执行数次(ImageView position 0,ImageView position 11, ImageView position 21,且顺序还取决于异步中的具体处理和网络环境等),于是问题发生了。

解决方案:
抓住”UI元素中的某一特性的表征量“,在异步回调中通过比较“异步回调生成点”和“异步回调执行点”此特征变量的值直接作出逻辑上的处理。


public class HardRefSimpleImageLoadingListener implements ImageLoadingListener {
 public int identifier;
 public HardRefSimpleImageLoadingListener() {
 }
 public HardRefSimpleImageLoadingListener(int identifier) {
  this.identifier = identifier;
 }
 @Override
 public void onLoadingCancelled(String arg0, View arg1) {
 }
 @Override
 public void onLoadingComplete(String arg0, View arg1, Bitmap arg2) {
 }
 @Override
 public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
 }
 @Override
 public void onLoadingStarted(String arg0, View view) {
 }
}
ImageLoader.getInstance().loadImage(imageUrl, new HardRefSimpleImageLoadingListener(did) {
 @Override
 public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
  if (loadedImage != null) {
   if (identifier != did) {
    return;
   }
   imageView.setImageBitmap(loadedImage);
   // 其他业务逻辑处理..
  }
 }
});


总之,凡此类“Android异步回调UI同步性问题”,最好都通过比较“异步回调生成点”“异步回调执行点”特征变量的值去针对性的做逻辑处理,以免出现不必要的Bug,是非常必要且有效的手段。

 原文地址:Http://www.cnblogs.com/lwbqqyumidi/p/4110377.html

您可能感兴趣的文章:Android使用OkHttp进行网络同步异步操作Android异步方法以同步方式实现


--结束END--

本文标题: Android异步回调中的UI同步性问题分析

本文链接: https://lsjlt.com/news/24896.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android异步回调中的UI同步性问题分析
    Android程序编码过程中,回调无处不在。从最常见的Activity生命周期回调开始,到BroadcastReceiver、Service以及Sqlite等。Activity...
    99+
    2022-06-06
    回调 Android
  • JavaScript中回调函数及区分下同步和异步回调的示例分析
    小编给大家分享一下JavaScript中回调函数及区分下同步和异步回调的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1...
    99+
    2024-04-02
  • React中setState同步或异步问题的示例分析
    这篇文章主要为大家展示了“React中setState同步或异步问题的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“React中setState同步或异步问题的示例分析”这篇文章吧。1....
    99+
    2023-06-25
  • Java中使用同步回调和异步回调的示例详解
    目录(一)同步回调(1)匿名内部类回调(2)Lambda 回调(二)异步回调(1)简单的线程回调(2)异步并行回调(3)CompletableFuture 回调小结完整代码(一)同步...
    99+
    2023-05-16
    java同步回调 java异步回调 java异步和同步回调
  • 代码解析React中setState同步和异步问题
     React起源于Facebook的内部项目。React的出现是革命性的创新,React的是一个颠覆式的前端框架。在React官方这样介绍的它:一个声明式、高效、灵活的、创...
    99+
    2024-04-02
  • Ajax中同步和异步的示例分析
    小编给大家分享一下Ajax中同步和异步的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!通过ajax向后台发送和接收数据时...
    99+
    2024-04-02
  • php异步回调问题怎么处理
    在PHP中处理异步回调通常需要借助于一些库或框架来实现。以下是一些常用的方法: 使用swoole扩展:swoole是一个高性能的...
    99+
    2024-04-09
    php
  • React中setState同步和异步的示例分析
    这篇文章主要介绍React中setState同步和异步的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! React起源于Facebook的内部项目。React的出现是革命性的创新,React的是一个...
    99+
    2023-06-15
  • Java线程同步问题分析
    本篇内容主要讲解“Java线程同步问题分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java线程同步问题分析”吧!Java线程同步的基本实现思路还是比较容易理解的。我们可以给共享资源加一把锁...
    99+
    2023-06-17
  • Unity同步/异步调用Android的方法实例
    目录1 Unity如何使用Android插件2 同步方法如何调用2.1 例子12.2 例子23 异步方法如何调用3.1 Android端3.1.1 添加依赖3.1.2 代码逻辑3.2...
    99+
    2024-04-02
  • koa之异步回调处理的示例分析
    这篇文章主要介绍koa之异步回调处理的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. 回调金字塔及理想中的解决方案我们都知道javascript是一门单线程异步非阻塞语言...
    99+
    2024-04-02
  • Ajax请求中异步与同步的示例分析
    这篇文章主要为大家展示了“Ajax请求中异步与同步的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Ajax请求中异步与同步的示例分析”这篇文章吧。 ...
    99+
    2024-04-02
  • ajax同步和异步XMLHTTP的示例分析
    这篇文章给大家分享的是有关ajax同步和异步XMLHTTP的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 在网页脚本编程中,绝大多数情况应...
    99+
    2024-04-02
  • Vue中的同步调用和异步调用方式
    目录Vue的同步调用和异步调用Promise实现异步调用async /await方法实现同步调用Vue同步和异步的问题基本语法实例Vue的同步调用和异步调用 Promise实现异步调...
    99+
    2024-04-02
  • 关于React中setState同步或异步问题的理解
    目录1. setState同步?异步? 2. 表现为异步 1. React 合成事件 2. 生命周期函数 3. 表现为同步 1. 原生事件 2. setTimeout 4. setS...
    99+
    2024-04-02
  • 同步与异步:Python与Laravel的对比分析
    在现代的软件开发中,同步和异步是两个重要的概念。同步指的是程序在执行某个任务时,必须等待该任务完成后才能执行下一个任务。而异步则是指程序在执行某个任务时,可以继续执行其他任务,不必等待该任务完成。Python和Laravel是两种常用的编...
    99+
    2023-09-16
    并发 同步 laravel
  • Java线程同步问题实例分析
    这篇文章主要讲解了“Java线程同步问题实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java线程同步问题实例分析”吧!1.场景有五位沉默的哲学家围坐在一张圆桌旁,他们一生都在吃东西...
    99+
    2023-06-29
  • Java中CountDownLatch异步转同步工具类的示例分析
    小编给大家分享一下Java中CountDownLatch异步转同步工具类的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!使用场景由于公司业务需求,需要对接socket、MQTT等消息队列。众所周知 socket 是...
    99+
    2023-06-20
  • Spring Boot异步请求和异步调用的示例分析
    这篇文章主要为大家展示了“Spring Boot异步请求和异步调用的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Spring Boot异步请求和异步调用的示例分析”这篇文章吧。一、Sp...
    99+
    2023-06-16
  • Vue中的同步调用和异步调用怎么实现
    这篇“Vue中的同步调用和异步调用怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue中的同步调用和异步调用怎么实现...
    99+
    2023-06-28
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作