浅析android系统设计中的回调思想
一、为何写作本文
在慢慢深入接触android开发的过程中,我越来越发现android中(至少应用曾的开发)用到了很多回调的思想。比如activity的生命周期,fragment的生命周期,皆是回调函数实现的,android中的事件处理机制其一就是回调,线程方面的异步任务、loader、hanlder等都是基于回调的,等等。
可见android的其一根本思想就是回调,需要你来参与时,回调用相关的回调方法,你来填充。
可以说回调的思想浸润与android设计的方方面面,android开发中几乎带有on的方法都是回调方法。作为一名致力于深入学习移动开发的菜鸟,深入理解回调就显得非常必要了。
二、为何要引入回调
回调是不得以而为之的设计策略,想象一种系统实现:在一个下载系统中有一个文件下载模块和一个下载文件当前进度显示模块,系统要求实时的显示文件的下载进度,想想很简单,在面向对象的世界里无非是实现两个类而已。但是问题恰恰出在这里,显示模块如何驱动下载进度条?显示模块不知道也不应该知道下载模块所知道的文件下载进度(面向对象设计的封装性,模块间要解耦,模块内要内聚),文件下载进度是只有下载模块才知道的事情,解决方案很简单给下载模块传递一个函数指针作为回调函数驱动显示模块的显示进度。
在面向对象的世界中这样的例子还真不少,造成这样的问题的根源,相信大家已经从上面的叙述中体会到了,就是面向对象的程序设计思想,就是设计模式中要求的模块独立性,高内聚低耦合等特性。
封装变化的编程策略给编程人员第一位的指导思想就是面向接口编程,即设计模式中提到的面向虚拟编程而不是面向实现。这样的编程思想极大地革新了编程世界,可以说没有这一原则就没有面向对象的程序设计,这一原则给程序设计一种指导思想:即如何更高的将现实模型映射成程序模型。这样的设计思想在极大地催生高度独立性模块的同时削弱了模块间的协作性,也就是耦合性,它使得模块间更多的从事着单向的调用工作,一个模块需要某种服务就去找另一个模块,这使得程序呈现出层次性,高层通过接口调用底层,底层提供服务。但是现实世界中严格遵循现层次特性的系统是很少见的,绝对的MVC是不存在的,因为更多的模块要求通并协作,可见没有耦合就没有协作没有好的调用关系,耦合真的不是错。
既然我们需要模块间的协作,同时我们又厌恶的摒弃模块间你中有我我中有你的暧昧关系那如何生成系统呢,答案是函数指针(不一定是函数指针)也就是使用回调的方式。如果一个对象关心另一个对象的状态变化那么给状态的变化注册回调函数让它通知你这类状态的改变,这样在封装了模块变化的同时实现了模块间的协作关系另辟独径的给对象解耦。
三、回调的通俗理解
你饿了,想吃饭,就一会去问你妈一声”开饭没有啊?”这就是正常函数调用.
但是今天你妈包饺子,花的时间比较长,你跑啊跑啊,就烦了.于是你给你妈说,我先出去玩会,开饭的时候打我手机.等过了一阵,你妈给你打电话说”开饭啦,快回来吃饭吧!”
其中,你告诉你妈打手机找你,就是个你把回调函数句柄保存到你妈的动作.你妈打电话叫你,就是个回调过程.
四、回调的详细解释
理解方式1:一般写程序是你调用系统的API,这个过程叫Call。如果把关系反过来,你写一个函数,让系统调用你的函数,那就是回调(CallBack)了,那个被系统调用的函数就是回调函数。放到android中,我们一般是调用framwork定义的api,但是如果我们写了一个方法,由framwork来调用,这个方法就是回调函数。
理解方式2:所谓回调函数,其运行方式是,“你不用调用我,等着我来调用你”。回调的意思是在你执行某个语句后成功了,再执行你传递进来的function,在做异步处理的时候特别有用。
理解方式3:归程序本质,刨除那些面向对象的概念,回调函数就是一个通过函数指针调用的函数。就是用函数指针做参数。那个函数指针就是回调函数。
回调是编程层面的设计模式,不是基于语言的。在C/C++中,要用回调函数,被调函数需要告诉调用者自己的指针地址,但在JAVA中没有指针,怎么办?我们可以通过接口(interface)来实现定义回调函数。在.Net的世界里Delegate ==Callback。
五、在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接口中的方法
六、简明案例
以妈妈喊儿子吃饭为例,贴代码如下:
//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秒后------
妈妈:饭做好了,儿子快过来吃饭了
儿子:我来吃饭了
七、回调用在哪里
回调函数主要用于一些比较费时的操作,或响应不知道何时将会发生的事件,场合异步结合(异步其实就是重开一个线程)。
当两个对象之间需要进行一些协同操作时,常使用回调函数,比如一个对象想获得另一个对象内部的某些数据。
八、回调的优点
回调函数使得程序设计更加灵活。
实现模块独立性,将实现者和调用者分离,符合面对对象高内聚低耦合的设计思想。
九、回调的缺点
代码的易读性不好。
转载:https://blog.csdn.net/a910626/article/details/45920893
浅析android系统设计中的回调思想的更多相关文章
- 浅析Android设备中grep命令处理流程
2017-04-18 概述 在TV开发板中,可以在串口中直接使用grep命令.这是因为在/system/bin/下有一个'grep'链接.这个链接指向'/system/bin/toolbo ...
- 浅析Android Dialog中setContentView()方法
2017-05-15 概述 Dialog在Android中是一个很优秀的工具.在使用Dialog时,我们一般都会自定义要显示的内容布局.Dialog自带了三个方法来支持自定义内容布局. public ...
- 讨论Android开发中的MVC设计思想
最近闲着没事,总是想想做点什么.在时间空余之时给大家说说MVC设计思想在Android开发中的运用吧! MVC设计思想在Android开发中一直都是一套比较好的设计思想.很多APP的设计都是使用这套方 ...
- Android中关于回调概念的笔记
一.回调函数 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调 ...
- [原创]Android系统中常用JAVA类源码浅析之HashMap
由于是浅析,所以我只分析常用的接口,注意是Android系统中的JAVA类,可能和JDK的源码有区别. 首先从构造函数开始, /** * Min capacity (other than zero) ...
- Android中自定义veiw使用Java中的回调方法
//------------------MainActivity----中---------------------------------- import android.os.Bundle;imp ...
- Android源码浅析(四)——我在Android开发中常用到的adb命令,Linux命令,源码编译命令
Android源码浅析(四)--我在Android开发中常用到的adb命令,Linux命令,源码编译命令 我自己平时开发的时候积累的一些命令,希望对你有所帮助 adb是什么?: adb的全称为Andr ...
- android中的回调
1.引子 android中的回调最经典的就是点击事件设置监听(一般通过switch(v.getId()))这里写个最基本的 btn_rigister.setOnClickListener(new Vi ...
- ZT ANDROID jni 中的事件回调机制JNIenv的使用 2012-09-10 12:53:01
ANDROID jni 中的事件回调机制JNIenv的使用 2012-09-10 12:53:01 分类: 嵌入式 android framework 里java调用native,使用JNI机制,ja ...
随机推荐
- JS(JavaScript)的进一步了解2(更新中···)
js数据类型 基本数据类型:string undefined null boolean number 引用数据类型 Object array function 二者的区别 基本数据类 ...
- Summary on deep learning framework --- PyTorch
Summary on deep learning framework --- PyTorch Updated on 2018-07-22 21:25:42 import osos.environ[ ...
- python 画广东省等压线图
最近开发时要实现一个业务逻辑: 调用中国气象数据网API接口获取广东省实时气象数据 根据数据,基于广东省地图渲染等压线图 最终效果图是这样的: 首先是获取实时气压数据,由于中国气象数据网每次只能获得3 ...
- MapReduce实现PageRank算法(稀疏图法)
前言 本文用Python编写代码,并通过hadoop streaming框架运行. 算法思想 下图是一个网络: 考虑转移矩阵是一个很多的稀疏矩阵,我们可以用稀疏矩阵的形式表示,我们把web图中的每一个 ...
- 2>&1的意思
2>&1的意思就是将标准错误也输出到标准输出当中.
- HTTP响应 状态码描述
- fiddler -- 一个强大的抓包工具
一.fiddler常用功能: 1. Fiddler 是位于客户端和服务器端的http代理,也是目前最常用的http抓包工具之一.它能够记录客户端和服务器之间的所有http请求,可以针对特定的http请 ...
- Django 管理站点
这一部分是关于 Django 的自动管理界面.这个特性是这样起作用的:它读取你模式中的元数据,然后提供给你一个强大而且可以使用的界面,网站管理者可以用它立即工作.在这里我们将讨论如何激活,使用和定制这 ...
- [数据结构] P2.3 Trie树
1.Trie树的概念 Trie树也叫做`字典树`或者`单词查找树`.用于字符串以及字符串元信息的快速查询. 例如:
- C语言实验一(2)
#include<stdio.h>int main(){ char c1,c2; c1=97; c2=98; printf("c1=%c,c2=%c\n",c1,c2) ...