个人评论:真心不错的一篇文章,以后coding,以及写基础框架又多了一些考虑点。
作者:范怀宇
链接:https://zhuanlan.zhihu.com/p/20214237
来源:知乎
如果有人问我,Android 程序什么时候最容易出错?一个备选答案(额,这个备选集可能会有点长...):在界面开发中使用了异步回调。在任何程序开发中,异步操作的处理都是一个麻烦事,而在 Android 中更繁杂一些,这是由于 Android 基于组件的设计对异步操作不够友好。所以,如果你在 Android 中开发界面,不妥善处理全部的异步回调,崩溃、内存泄露、状态错乱,就都接踵而至了。

而在 Android 中如何处理好异步请求,则是一个非常宽泛的话题,从这篇开始的若干篇,都会围绕这个来聊一聊。而这篇要讲的,就是看看界面中的异步回调,经常会引发什么问题,要注意些什么。

要在异步回调中判断界面状态

最典型的问题,就是回调时触碰界面而引发崩溃,一个简单示例如下:

// 发起一个异步请求,执行完成后更新界面状态
requestManager.execute(aRequest, new Callback() {protected void completed() {textView.setText("Completed!");}
});

如果回调时,用户已经离开了界面,textView 可能会由于状态不对抛出异常而引发程序崩溃。因此,只要在页面上做了异步回调,需仔细考虑回调时的页面状态,可能需要调用 Activity.isFinishing 来检查界面是否销毁避免触发状态异常的崩溃;如果在 Fragment 中,就要调用 Fragment.isAdded 进行判断,避免 Activity 解绑后触发空指针;以及,在调用各种 Fragment 的 APIs 时,都需要确定页面是否 Save State 了,否则很多 Fragment 的调用都会出错。当然,简单粗暴的,还能赤果果把回调操作中全部 Runtime 级别开始的全部异常都吃掉,不优雅,但至少比崩溃好...

但其实,解决回调崩溃的问题是知易行难,真实的项目中,情况会非常隐匿,线上崩溃总是由于 "不小心"、"没想到" 而引发的。所以,很多时候把保护放在服务内而不是调用者那里,是更安全可靠的方案。

在豌豆荚一览中,小帆给新用户做了一个非常华美的产品介绍(为了纪念这个一次性的功能,我们还特意在设置里面放了一个 "观看产品介绍" 的入口),它的实现充满了十数次异步动画和网络回调,异步操作满地都是,在修改时一不小心就埋下了潜在的线上崩溃(异步回调崩溃的特点,就是不容易发现...)。小帆不堪忍受这样的画面,于是封装了一个欢迎页面的调度引擎,由它来处理全部回调,它接受当前页面的 Fragment 作为参数,回调前会自行判断 Fragment 的状态(并吃掉异常...),这才避免了在无数异步回调中迷失。

要尽可能的取消异步操作

除了崩溃,和异步形影不离的还有内存泄露,它的隐蔽性很强,总是藏匿在 Activity 等具有 Context 的对象中。比如:

// 执行一个时间很长的操作...
requestManager.execute(aRequest(activity) {protected void run() {// wait long long time...}
});

这个异步操作拿了 Activity 对象,如果它需要执行很长时间,那在这个阶段 Activity 和它上面的各种元素都是无法释放的,在用户离开页面很长时间后,内存依旧在占用,并且反复进出会持续累加直到 Out Of Memory(OOM),这其实也就是引发了内存泄露。而这样长时间的等待,有可能是定时引发、有可能是队列排队引发、有可能卡在了某个操作上(比如网络、IO ...),很多时候,甚至都难于提前判断。

因此,如果我们假设,大部分的异步操作都可能是慢的,需要执行很长时间,那如何来处理呢?使用弱引用是一个办法,把等待回调的界面对象(一般都持有 Context)用 WeakReference 包裹起来,如果用户离开页面,很快也会把它给收了,以此来避免内存泄露。但弱引用本身使用上有很多禁忌,稍有不慎就从一个坑到了另一个坑。比如,弱引用最好不要放到服务内弄成黑盒,而是要调用者自行使用,如果放在服务内调用者很可能会出现傻等回调等不来的状况;而一旦完全交由调用者,又难以保证实现是统一可靠的,依旧会由于 "不小心" 引发问题。

除此之外呢?支持干净的取消可以算是最漂亮的方案之一了,在异步回调未返回但界面要退出之前,把操作给回收了,而这个回收不只是设定一个标志位,而是要将回调中潜在泄露的对象彻底移除,这样才能是干净的、可以避免内存泄露的取消方案。

而怎么做一个支持取消的异步机制?那就下(jie)回(hou)分解了。

#Effective Android# 警惕界面上的异步回调(No.2)相关推荐

  1. 警惕界面上的异步回调

    2019独角兽企业重金招聘Python工程师标准>>> 如果有人问我,Android 程序什么时候最容易出错?一个备选答案(额,这个备选集可能会有点长...):在界面开发中使用了异步 ...

  2. 内存泄漏,关于异步回调导致的内存泄漏,使用LeakCanary检测内存泄漏

    在任何程序开发中,异步操作的处理都是一个麻烦事,而在 Android 中更繁杂一些,这是由于 Android 基于组件的设计对异步操作不够友好.所以,如果你在 Android 中开发界面,不妥善处理全 ...

  3. 异步回调需要注意的问题

    如果有人问我,Android 程序什么时候最容易出错?一个备选答案(额,这个备选集可能会有点长...):在界面开发中使用了异步回调.在任何程序开发中,异步操作的处理都是一个麻烦事,而在 Android ...

  4. android 异步回调中操作UI线程,UI同步、卡死阻塞等性能问题

    android开发中,回调无处不在,整个android开发的框架就是以回调机制建立起来的.如:activity,service,broadcast,fragment,view事件监听,baseadap ...

  5. Android 避免主线程执行网络请求之Activity/Fragment 结束后处理异步回调

    大家都知道Android涉及到与UI相关的操作只能在主线程执行 android4.0以后就禁止在主线程进行网络请求了,在主线程里面执行Http请求都会报NetworkOnMainThreadExcep ...

  6. android界面布局题,【填空题】Android 系统中, 用于定义布局显示在界面上的风格。...

    [填空题]Android 系统中, 用于定义布局显示在界面上的风格. 更多相关问题 [37]A.anotherB.each otherC.the otherD.one another Tabor ma ...

  7. Android 屏蔽锁屏界面上的通知显示

    一. 前言 [定制需求描述]:在插入SD后,  锁屏状态下, 去掉提示"SD卡可用于传输照片和媒体文件" 需求拆解:  要求正常显示在SystemUI下拉状态栏,  只需要屏蔽在锁 ...

  8. Android跳转动画时长,Android_Activit跳转动画之界面上某个位置并裂开上下拉伸动画跳转,需求:Activity(fragment)跳转的时候 - phpStudy...

    Activit跳转动画之界面上某个位置并裂开上下拉伸动画跳转 需求:Activity(fragment)跳转的时候当前界面裂开,上下各自拉出手机屏幕,之后跳转到相对应的Activity.整体效果图如下 ...

  9. Android自定义拍照上传界面,Android自定义dialog——设置头像(拍照,相册)

    Android自定义dialog--设置头像(拍照,相册) 需求场景:个人信息设置,点击头像,在界面上弹出一个弹框,用户选择"拍照"/"从图库选择",选择照片后 ...

最新文章

  1. 计算机网络7层协议模型,计算机网络(一) OSI七层模型及TCP/IP dubbo协议
  2. 《windows核心编程系列》十八谈谈windows钩子
  3. 盘点 | 2020年「21篇」医学影像算法最佳综述
  4. 从视觉系统的原理入手 破解VR眩晕症
  5. VNF 的性能测试设计要点
  6. 深入理解Lustre文件系统-第1篇 前言
  7. sublime Text3插入参考文献问题
  8. Python 2 最后一个版本发布,正式迈入 Python 3 时代
  9. 项目管理(4):备战pmp
  10. Python数据结构与算法(五)--链表
  11. Spring Validation校验
  12. 英国莽汉司机认罪:放任特斯拉自动驾驶,自己躺在副驾悠哉悠哉
  13. mysql数据库中 pri_mysql数据库part2
  14. Pads logic 创建文件时发生严重错误
  15. oracle 中的角色
  16. 扫描指定ip的指定端口,识别开放的端口所对应的服务
  17. 汇编实验----电话号码
  18. 斐讯N1盒子 TTL救砖教程
  19. Easypoi模版形式导出excel导出图片
  20. 系统自带输入法➋➌➍➎➏➐➑➒问题

热门文章

  1. ping不通Linux服务器怎么办?
  2. 关于定向耦合器(二)
  3. 0-1背包问题详解(一步一步超详细)
  4. 论文阅读:基于区块链的分布式软件定义车载网络一种深度q -学习方法
  5. oracle trunc月份,oracle trunc
  6. 计算机断电后自动启动,我的计算机最近一启动就不断自动上电和断电
  7. 转:致地理信息软件公司的一封公开信
  8. XJTU_ 西安交通大学2020大学计算机作业-第九周
  9. passive模式 tcp_ftp的主动模式active mode和被动模式 passive mode的配置和区
  10. 股票量化软件:运用 R-平方 评估策略余额曲线的品质