基本上所有 Android 开发都会接触到 onCreate()onDestory()onStart()onStop() 等这些生命周期方法,但却不是所有人都会去关注到 onAttachXXX() 这样的方法群体,今天,笔者就希望用简短的文章对此进行一定讲解。

Activity 中的 onAttachedToWindow

首先在 Activity 中我们可以重写 onAttachedToWindow()onDetachedFromWindow() 这一对方法。顾名思义,"Attached" 就是附加的意思,所以我们可以确定 onAttachedToWindow() 就是在 View 附加到 window 上的时候进行回调,而 onDetachedFromWindow() 就刚好相反。

这一对方法会在我们熟悉的 Activity 生命周期的 onResume()onPause() 中间,但并不是每一次 onResume()onPause() 回调的时候都会在接下来回调它们。应该比较好理解,我们当然不需要频繁往 window 中附加和分离 View 嘛。

这里自然我们容易产生一个问题,在 onAttachedToWindow() 回调的时候,我们能拿到 View 的宽高么?换句话说就是这时候 View 是否已经经过了测量和绘制呢?

我们编写一个 Demo 进行日志打印看看。

可以看到,并没有。我们只有在 onWindowFocusChanged 回调的时候才能真正的拿到 View 的宽高值。

所以,ActivityonAttachedToWindow() 回调之后,布局中的 View 会回调 onAttachedToWindow() ,然后才会去进行测量和绘制等。那么我们要获取一个 View 的宽高就最好是 View.post() 了。

View 的 onAttachedToWindow 使用场景

ViewonAttachedToWindow() 的调用时机会发生在 onMeasure() 之前,那么它们到底有什么使用场景呢?

我们在自定义 View 的时候,某些比较重量级的资源,而且不能与其他 View 通用的时候,就可以重写这两个方法,并在 onAttachedToWindow() 中进行初始化,onDetachedFromWindow() 方法里释放掉。

比如 Bitmap,虽说现在不用主动调用 recycle() 方法来回收,但在 8.0 及以上系统,手动调用是会立即释放所占用的内存的,所以个人认为还是有必要手动回收的,当然了,如果图片比较小,对内存没什么影响的就不用了。

再比如一些用作计算的子线程,或其他跟 View 显示有关的任务,在 onDetachedFromWindow() 中也可以停掉了,因为大多数情况下,这些实时数据对于被分离后 View 已经没有意义了。

RecyclerView.Adapter 的 onViewAttachedToWindow

细心的小伙伴会发现,在 RecyclerView.Adapter 中也会有这么一个 onViewAttachedToWindow()onViewAttachedToWindow()

这两个方法在列表布局的时候,用作曝光埋点非常好用,当 Adapter 创建的 View 被窗口分离(即滑动离开了当前窗口界面的)的时候,onViewAttachedToWindow() 会被直接回调,反之,在列表项 View 在被滑动进屏幕的时候,onViewAttachedToWindow() 会立马被调用。

有了这样的属性,对于我们的曝光埋点,就手到擒来了,直接在里面做就完事儿了。

RecyclerView.Adapter 咋还有一个 onAttachedToRecyclerView

说到 AdapteronViewAttachedToWindow,咋发现这里面竟然还有一个 onAttachedToRecyclerView 方法,根据源码我们可以发现,onAttachedToRecyclerView() 是在 setAdapter() 的时候触发。

对比一下,我们便能得出以下它们的使用场景:

  1. RecyclerView 本质上也是一个 ViewGroup,那么它的 Item 要显示出来,自然需要 addView() 进来,移出的时候,当然也要 removeView() 出去,所以对应的自然是 onViewAttachedToWindow()onViewAttachedToWindow() 了。所以在一定场景下,可以通过这两个回调来处理一些 Item 移出屏幕,移进屏幕锁需要的工作。为什么说一定场景下呢,因为如果调用了 notifyDataSetChanged() 方法的话,会触发当前在屏幕中的所有 Item 的 onViewAttachedToWindow()
  2. onAttachedToRecyclerViewonAttachedToRecyclerView() 的话,就更加适合做一些资源回收的工作啦。

我的 RecyclerView.Adapter 的 onViewAttachedToWindow 为啥没起作用?

可能会有小伙伴会遇到这个问题,在遇到这个问题前,先检查一下你这个 RecyclerView 是否是一个正常滚动的 View,你如果是被别人嵌套滚动,把自己设置了 isNestedScrollingEnabled 为 false 的话,那你都失去了 Recyclerview 的功用了,那自然是不行的。

可能又有小伙伴说了,由于需求历史原因,我就是用了 NestedScrollView 嵌套了 Recyclerview,并禁掉了 Recyclerview 的滑动功能,但又想做上面的曝光埋点功能,那如何是好?

如果是这样的话,大概你就只能通过类似 ViewgetGlobalVisibleRect() 这样的方法来判断 View 的可见性来处理了。关于 View 的可见性分析,这里就点到为止,大家就自行 Google 吧。

每日一问:浅谈 onAttachedToWindow 和 onDetachedFromWindow的更多相关文章

  1. 浅谈REST API

    浅谈REST API 说明: 本文部分内容根据其它网络文章编写,如有版权问题请及时通知. 背景 发迹于互联网的REST,在国内国外混得可谓是风生水起,如今又进入电信行业的视野,连TMF都将其作为战略项 ...

  2. 浅谈Android编码规范及命名规范

    前言: 目前工作负责两个医疗APP项目的开发,同时使用LeanCloud进行云端配合开发,完全单挑. 现大框架已经完成,正在进行细节模块上的开发 抽空总结一下Android项目的开发规范:1.编码规范 ...

  3. 浅谈HTML5单页面架构(一)——requirejs + angular + angular-route

    心血来潮,打算结合实际开发的经验,浅谈一下HTML5单页面App或网页的架构. 众所周知,现在移动Webapp越来越多,例如天猫.京东.国美这些都是很好的例子.而在Webapp中,又要数单页面架构体验 ...

  4. 浅谈Linux中的信号处理机制(二)

    首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...

  5. 浅谈php生成静态页面

    一.引 言 在速度上,静态页面要比动态页面的比方php快很多,这是毫无疑问的,但是由于静态页面的灵活性较差,如果不借助数据库或其他的设备保存相关信息的话,整体的管理上比较繁琐,比方修改编辑.比方阅读权 ...

  6. 浅谈用ModelSim+Synplify+Quartus来实现Altera FPGA的仿真

    浅谈用ModelSim+Synplify+Quartus来实现Altera FPGA的仿真 工作内容: Mentor公司的ModelSim是业界最优秀的HDL语言仿真软件,它能提供友好的仿真环境,是业 ...

  7. 《浅谈磁盘控制器驱动》,磁盘控制器驱动答疑解惑![2012.1.29完结]by skyfree

    <浅谈磁盘控制器驱动>,磁盘控制器驱动答疑解惑![2012.1.29完结]  https://www.itiankong.net/thread-178655-1-1.html Skyfre ...

  8. 【架构】浅谈web网站架构演变过程

    浅谈web网站架构演变过程   前言 我们以javaweb为例,来搭建一个简单的电商系统,看看这个系统可以如何一步步演变.   该系统具备的功能:   用户模块:用户注册和管理 商品模块:商品展示和管 ...

  9. !! 浅谈Java学习方法和后期面试技巧

    浅谈Java学习方法和后期面试技巧 昨天查看3303回复33 部落用户大酋长 下面简单列举一下大家学习java的一个系统知识点的一些介绍 一.java基础部分:java基础的时候,有些知识点是非常重要 ...

随机推荐

  1. IIS相关优化

    1.修改IIS最大工作进程数 a. 请考虑以下几点: 1.每一个工作进程都会消耗系统资源和CPU占用率:太多的工作进程会导致系统资源和CPU利用率的急剧消耗: 2.每一个工作进程都具有自己的状态数据, ...

  2. 1 Task的简单实用

    Task是thread和threadpool两者结合的产物,吸收了二者的优点  进一步添加了一些新的 优秀的功能. using System; using System.Threading.Tasks ...

  3. redis在windows10上跑起来

    原文:redis在windows10上跑起来 今天,开始学习redis,发现大多数redis都是在Linux上面运行的,可是我想把它放到windows上面运行,经过查找资料,在GitHub上面发现了一 ...

  4. MFC 窗口分割与通信

    一.关于CSplitterWnd类我们在使用CuteFtp或者NetAnt等工具的时候,一般都会被其复杂的界面所吸引,在这些界面中窗口被分割为若干的区域,真正做到了窗口的任意分割. 那么我们自己如何创 ...

  5. Java Swing界面编程(29)---JCheckBox事件处理

    JCheckBox和JRadioButton的事件处理监听接口是一样的,都是使用ItemListener接口. package com.beyole.util; import java.awt.Con ...

  6. mac系统下虚拟机parallels安装ubuntu 14.04

    mac系统很棒,mac下的开发环境也很棒,但有时你还得需要ubuntu开发环境,比如进行嵌入式Linux交叉编译,使用Linaro toolchain… 其实mac系统下使用parallels虚拟机安 ...

  7. CORSFilter

    import java.io.IOException; import javax.servlet.Filter;import javax.servlet.FilterChain;import java ...

  8. 【Android先进】如何使用数据文件来保存程序

    在程序,有许多方法来存储和检索数据,本文,它描述了如何使用文件系统来保存数据编程和读取操作 我直接写了一个帮助类,进行文件的写入和读取操作 /** * 用于在文件里保存程序数据 * * @author ...

  9. PHP提取字符串中的图片地址

    PHP提取字符串中的图片地址 $str='<p><img border="0" src="upfiles/2009/07/1246430143_1.jp ...

  10. 图像滤镜艺术---保留细节的磨皮滤镜之PS实现

    原文:图像滤镜艺术---保留细节的磨皮滤镜之PS实现 目前,对于人物照片磨皮滤镜,相信大家没用过也听过吧,这个滤镜的实现方法是多种多样,有难有简,有好有差,本人经过长时间的总结,得出了一种最简单,效果 ...