本帖最后由 武汉分校-小舞 于 2016-3-24 17:25 编辑
【武汉校区】独家分享:理解回调(Listener)
前言
学习安卓,大家接触的第一个Listener很可能就是View.OnClickListener,而且用起来也没有问题,很简单。但是如果要大家去写一个回调,可能大家就犯难了。 其实回调的书写非常简单,我在这里把它总结程了2个类、5个步骤: · 2个类: 1. 定义了回调接口的类; 2. 实现了回调接口的类。 · 5个步骤分为: 定义了回调接口的类: 1. 定义一个回调接口,并对接口制定方法签名(方法名、返回值、参数),暂时称为**XxListener** 2. 对外提供传入实现了此接口的对象的方法,称为*setXxListener*,并记录为成员变量,叫做**xxListener** 3. 在合适的时机调用回调对象的方法,一般会检查是否为空
实现了回调接口的类: 1. 实现**XxListener**,完成接口规定的方法,称为**myXxListener** 2. 把此对象通过*setXxListener*方法,传递给上面的类。
理解回调 为了便于理解,我们举一个常见的购物的例子: 我(称作客户)在京东下订单买了一本书(《金瓶梅》),因为书是一个实物,所以必须经过快递员的配送才能到我手中,那么这里就几个关键概念:京东、客户、订单,其实快递员可以理解为京东的一部分。
我们来看一下这些步骤: 1. 客户填写订单,这个订单的格式是京东规定的; 2. 客户提交订单,京东提供了提交订单的方法; 3. 京东准备货物,在一段时间之后,让快递员送货,当快递员将要送到的时候,拨打订单上的电话,通知我,书到了,然后客户顺利的拿到了《金瓶梅》。
在上述步骤1中: 大家首先可以把京东理解为定义了回调接口的类,因为订单的格式是京东规定的;
那这个接口就是订单格式;
而客户呢,就是实现了订单接口的类(不是直接实现,而是客户的成员变量中有实现了订单接口的对象),具体表现是:填写订单。
在上述步骤2中: 客户调用京东的提交订单的方法,把实现了订单接口的对象(填写完成的订单)传递给了京东。
在上述步骤3中: 京东在货物快要送达的时候,调用之前传入的订单对象上的方法(拨打电话,通知货到了)。 如果理解了这个例子,我们再看一下View的OnClickListener: · Activity是实现了OnClickListener接口的类; 具体的activity,实现了OnClickListener,并调用具体的view的setOnclickListener方法,onClickListener传递给了View; · View是定义了OnClickListener接口的类; 那view对象做了什么呢?它通过分析落在自己身上的触摸事件,发现属于点击行为,就去检查一下是否具有点击监听,如果发现有就调用一下上面的onClick方法,并且对方法中传递自身作为参数并调用,让activity知道那个view被点击了。而我们的具体实现呢,可能是显示一个土司、打印一段日志、播放动画、下载数据都可以。 问答环节: 1. 那为什么使用回调呢? 就是因为在定义View之初,并不知道点击后具体有哪些事情要做,所以让其他的类告诉view做什么,view在发现点击后调用一下即可。主要目的在设计上提供接触耦合性,为程序的扩展性提供帮助。 2. 那么什么时候该使用回调? 想知道某件事件发生了,要进行进一步处理;但不知道该事件具体什么时候发生时使用。比如说,你肯定不知道用户在什么时候点击一个Button,但你知道用户根据界面点击Button后想完成什么操作,就可以对Button设置点击回调监听。 3. 那么监听和Callback是什么关系呢?比如说XUtils的HttpUtils的send方法中的Callback。 就具体来说,Callback是回调的一种,在这个具体例子中有以下几点: 1. 一次请求一般对应一次Callback,而设置了点击监听后,可以被多次调用 2. Callback包含子线程和主线程的切换,也就是说在主线程中不能下载,在子线程中不能改UI 3. Callback实际上是:在子线程中完成了下载(耗时),然会利用Handler,把下载好的数据传入到主线程中,让主线程完成更改界面操作 4. more 总结和提高 其实回调并不其他步骤都不难,最难的其实就是定义接口和接口上的方法,因为接口的中的方法确定了,那么了什么时候调用方法也是知道的,至于setXxListener方法更加是固定写法;接口中的方法定义,涉及的参数(几个、什么类型的返回值才刚好够用而又不嫌多余)、返回值(返回值到底是void 、boolean、int还是其他对象)才是最关键的。
大家编程之初,可能听过技术经理就是定义一些接口,具体实现都由开发人员完成,一定会决定技术经理的工作很轻松,但是这需要对业务、程序的深入理解才能胜任。 在学java时,对面向对象的概念懵懵懂懂,在写代码时常常会写面向过程的代码;而面向接口编程就是在掌握面向对象思想后的另一个境界。 一般来说,接口回调的设置回调对象方法是setXxListener,但是这样写就意味着只能接受1个监听,那么京东类肯定不能这样设计,不能之服务于一个客户。还有一种写法就是addXxListener,那么就可以记录多个回调对象。以我们熟悉的ViewPager的OnPageChangedListner为例,原先大家都写setOnPageChangedListener,在后来的support-v4包中,谷歌把此方法添加为过时,并提供了addOnPageChangedListener方法。因为google发现,有时候在OnPageChangedListner需要完成多种业务逻辑,如果代码混在一起,可读性就很差。 但是需要注意的是,如果有addXxListener方法,就一定要写removeXxListener方法,让外界调用,避免内存泄漏。但有时候,外界就是忽略了removeXxListener,那我们还不能直接使用普通的List或是Set集合去记录监听回调对象,而是应该使用软引用,避免内存泄漏和提高垃圾回收的及时性。
想获取最新传智播客武汉中心分享技术文章请加QQ 1641907557 ,后期会分享更多与实体班同步教程,助你冲击月薪20K!
推荐阅读:
|