浅析android系统设计中的回调思想

1、为什么写做本文
  在慢慢深刻接触android开发的过程当中,我愈来愈发现android中(至少应用曾的开发)用到了不少回调的思想。好比activity的生命周期,fragment的生命周期,皆是回调函数实现的,android中的事件处理机制其一就是回调,线程方面的异步任务、loader、hanlder等都是基于回调的,等等。java

  可见android的其一根本思想就是回调,须要你来参与时,回调用相关的回调方法,你来填充。android

  能够说回调的思想浸润与android设计的方方面面,android开发中几乎带有on的方法都是回调方法。做为一名致力于深刻学习移动开发的菜鸟,深刻理解回调就显得很是必要了。编程

2、为什么要引入回调
  回调是不得以而为之的设计策略,想象一种系统实现:在一个下载系统中有一个文件下载模块和一个下载文件当前进度显示模块,系统要求实时的显示文件的下载进度,想一想很简单,在面向对象的世界里无非是实现两个类而已。可是问题偏偏出在这里,显示模块如何驱动下载进度条?显示模块不知道也不该该知道下载模块所知道的文件下载进度(面向对象设计的封装性,模块间要解耦,模块内要内聚),文件下载进度是只有下载模块才知道的事情,解决方案很简单给下载模块传递一个函数指针做为回调函数驱动显示模块的显示进度。设计模式

  在面向对象的世界中这样的例子还真很多,形成这样的问题的根源,相信你们已经从上面的叙述中体会到了,就是面向对象的程序设计思想,就是设计模式中要求的模块独立性,高内聚低耦合等特性。api

  封装变化的编程策略给编程人员第一位的指导思想就是面向接口编程,即设计模式中提到的面向虚拟编程而不是面向实现。这样的编程思想极大地革新了编程世界,能够说没有这一原则就没有面向对象的程序设计,这一原则给程序设计一种指导思想:即如何更高的将现实模型映射成程序模型。这样的设计思想在极大地催生高度独立性模块的同时削弱了模块间的协做性,也就是耦合性,它使得模块间更多的从事着单向的调用工做,一个模块须要某种服务就去找另外一个模块,这使得程序呈现出层次性,高层经过接口调用底层,底层提供服务。可是现实世界中严格遵循现层次特性的系统是不多见的,绝对的MVC是不存在的,由于更多的模块要求通并协做,可见没有耦合就没有协做没有好的调用关系,耦合真的不是错。异步

  既然咱们须要模块间的协做,同时咱们又厌恶的摒弃模块间你中有我我中有你的暧昧关系那如何生成系统呢,答案是函数指针(不必定是函数指针)也就是使用回调的方式。若是一个对象关心另外一个对象的状态变化那么给状态的变化注册回调函数让它通知你这类状态的改变,这样在封装了模块变化的同时实现了模块间的协做关系另辟独径的给对象解耦。ide

3、回调的通俗理解
  你饿了,想吃饭,就一会去问你妈一声”开饭没有啊?”这就是正常函数调用.函数

  可是今天你妈包饺子,花的时间比较长,你跑啊跑啊,就烦了.因而你给你妈说,我先出去玩会,开饭的时候打我手机.等过了一阵,你妈给你打电话说”开饭啦,快回来吃饭吧!”学习

  其中,你告诉你妈打手机找你,就是个你把回调函数句柄保存到你妈的动做.你妈打电话叫你,就是个回调过程.测试

4、回调的详细解释
理解方式1:通常写程序是你调用系统的API,这个过程叫Call。若是把关系反过来,你写一个函数,让系统调用你的函数,那就是回调(CallBack)了,那个被系统调用的函数就是回调函数。放到android中,咱们通常是调用framwork定义的api,可是若是咱们写了一个方法,由framwork来调用,这个方法就是回调函数。

理解方式2:所谓回调函数,其运行方式是,“你不用调用我,等着我来调用你”。回调的意思是在你执行某个语句后成功了,再执行你传递进来的function,在作异步处理的时候特别有用。

理解方式3:归程序本质,刨除那些面向对象的概念,回调函数就是一个经过函数指针调用的函数。就是用函数指针作参数。那个函数指针就是回调函数。

  回调是编程层面的设计模式,不是基于语言的。在C/C++中,要用回调函数,被调函数须要告诉调用者本身的指针地址,但在JAVA中没有指针,怎么办?咱们能够经过接口(interface)来实现定义回调函数。在.Net的世界里Delegate ==Callback。

 

5、在android中怎么使用回调呢
JAVA的CALLBACK经过接口来实现。
例:
1.class A,class B
2.class A实现接口operate
3.class B拥有一个参数为operate接口类型的函数test(operate o)
4.class A运行时调用class B中test函数,以自身传入参数
5.class B已取得A,就能够随时回调A所实现的operate接口中的方法

6、简明案例
  以妈妈喊儿子吃饭为例,贴代码以下:

//java实现回调,采用接口作回调函数
public interface CallBack { void eat(); }
/* * * 儿子要去玩游戏,不愿乖乖坐在那里等饭作好。 * 因此,他须要先问妈妈饭作好了没?即正常函数调用 : call askMom() * 没有就去玩游戏,等妈妈饭作好了,再来叫他吃饭即函数回调: callback eat() * */
public class Son implements CallBack { //son持有mom的引用.
    private Mom mom; public void setMom(Mom mom){ this.mom = mom; } public void eat() { System.out.println("儿子:我来吃饭了"); } public void askMom(){ //经过对mom的引用调用含有接口参数的方法
        System.out.println("儿子:饭作好了吗"); System.out.println("儿子:没作好的话,我去玩游戏了"); new Thread(new Runnable() { @Override public void run() { mom.doCook(Son.this); } }).start(); }
}
/* * 调用回调函数的对象:妈妈 */
public class Mom { public void doCook(final CallBack callBack){ new Thread(new Runnable() { public void run() { System.out.println("妈妈:还没作好...."); try { Thread.sleep(5000); System.out.println("\n"); System.out.println("------5秒后------"); System.out.println("妈妈:饭作好了,儿子快过来吃饭了"); //调用回调函数,喊来儿子来吃饭
 callBack.eat(); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }
/* * 测试案例 */
public class Test { public static void main(String[] args) { Mom mom = new Mom(); Son son = new Son(); son.setMom(mom); son.askMom(); } }
运行结果: 儿子:饭作好了吗 儿子:没作好的话,我去玩游戏了 妈妈:还没作好.... ------5秒后------ 妈妈:饭作好了,儿子快过来吃饭了 儿子:我来吃饭了

 

 

7、回调用在哪里
回调函数主要用于一些比较费时的操做,或响应不知道什么时候将会发生的事件,场合异步结合(异步其实就是重开一个线程)。

当两个对象之间须要进行一些协同操做时,常使用回调函数,好比一个对象想得到另外一个对象内部的某些数据。

8、回调的优势
回调函数使得程序设计更加灵活。

实现模块独立性,将实现者和调用者分离,符合面对对象高内聚低耦合的设计思想。

9、回调的缺点
代码的易读性很差。

 

转载:https://blog.csdn.net/a910626/article/details/45920893 

相关文章
相关标签/搜索