本文是作者原创文章,欢迎转载,请注明出处 from:@Eric_Lai
昨天做一个android的客户端和服务端的post通信,调试了整整一天都没有成功。作为一个不是计算机专业出身的人,我已经心力交瘁加绝望,横竖都看不出哪里有问题了。然而网上躺床真被看书睡觉的时候发现,书的后面几页就有关于这个的提示。原来是由于在新开的网络请求线程里面没有写回调方法导致数据无法传输。
好吧,接受了这个现实之后。我决心研究清楚究竟回调是什么鬼东东,之前在看事件处理的时候也有看到过这个东西,不过没怎么详细的留意它,给它留过去了。导致我一天宝贵的时间流失。在我找资料了解什么是回调,我参考到了这个博客的文章和例子感谢这位博主。但是本文是由我自己撰写的。
废话少说,下面研究下回调究竟是什么鬼。
回调说白了,就是通过A对象里面调用了B类的C方法,但是被调用B类的引用又反过来调用A对象里面的D方法。
我知道上面这么说肯定很多人都不知道我在说什么。我们先看一个故事。小明和小李是同学,小李的成绩比小明好,所以小明遇到不会的问题都会向小李请教。正好有一天小明遇到一个很难的问题“1+1”究竟等于多少呢?小明自己想了很久都没有想出来就只好向小李请教了,所以他打了一个电话给小李请教这个问题。刚好小李手上有事情在做,虽然他成绩好,也没有办法一下子回答出1+1等于多少这么难的问题。所以他告诉小明让他想一段时间留下电话号码,想出来了然后再打回去告诉答案。
在这个故事里面,小李让小明留下电话号码,而不是让小明一直拿着电话等待。这就是使用了回调的机制。
让我们看看回调机制的抽象过程:
一个实现了回调接口的A类 /接口当中声明的方法就是回调方法/
A类中有B类对像的引用,以便于可以调用B类的方法和回调接口的实现方法 /上面这句可以理解成,小明要有小李电话号码才可以打通小李的电话找到小李。实现接口的方法则是处理回调的逻辑代码/
B类中有接收回调接口对象的方法,以便于实现对A类中实现的回调接口方法的调用。 /上面这句可以理解成,小李要知道小明的电话才能够在知道答案之后返回去告诉他,这就是回调的方法/
下面我们通过demo的代码来理解一下 (我用的是eclipse作为IDE,先新建了一个工程,并加入一些必要的文件)
接下来是每一个类的具体代码,解释我都注释在代码当中了
/**
* name:CallBack.java
* by:ERIC_LAI
* date:13,July,2015
*/
/*package name different from person to person*/
package callbacktest;
/*create a interface*/
public interface CallBack {
/*declare the method*/
void result(String answer);
}
/**
* name:XiaoMing.java
* by:ERIC_LAI
* date:13,July,2015
*/
/*package name different from person to person*/
package callbacktest;
/*class name XiaoMing implement CallBack*/
public class XiaoMing implements CallBack{
/*use li to get class XiaoLi resource*/
private XiaoLi li;
/*constructor, give it a parameter from class XiaoLi*/
public XiaoMing(XiaoLi li){
/*put the parameter to the field*/
this.li=li;
}
/*method is used by xiaoming to ask question to xiaoli*/
public void askQuestion(final String question){
/*create new thread*/
new Thread(new Runnable() {
@Override
public void run() {
/*call the method from class XiaoLi used the field li*/
li.answerQuestion(XiaoMing.this,question);
}
/*start the thread*/
}).start();
/*after asking xiaoming can do other thing, now two threads is working*/
play();
}
private void play() {
System.out.println("i am playing");
}
/*the implement of the CallBack interface*/
@Override
public void result(String answer) {
System.out.println("xiaoli tell xiaoming the answer is--->" + answer);
}
}
/**
* name:XiaoLi.java
* by:ERIC_LAI
* date:13,July,2015
*/
/*package name different from person to person*/
package callbacktest;
/*class name XiaoMing*/
public class XiaoLi {
/*method which is used to answer xiaoming's question*/
public void answerQuestion(CallBack callback,String question) {
/*show the question*/
System.out.println("the question is "+question);
/*xiaoli is busy when xiaoming ask him*/
for (int i = 0; i < 10000; i++) {};
/*xiaoli finally figure out the difficult question*/
String answer = "answer is two";
/*callback the method to tell xiaoming what the answer is*/
callback.result(answer);
}
}
以上是每个类和接口的代码,接下来是写一个程序的入口,并让小明提出问题。这个很简单就不用注释了。
/**
* name:CallBackTest.java
* by:ERIC_LAI
* date:13,July,2015
*/
package callbacktest;
public class CallBackTest {
public static void main(String[] args){
XiaoLi li = new XiaoLi();
XiaoMing xiaoming = new XiaoMing(li);
xiaoming.askQuestion("what is the answer of one and one ?");
}
}
通过以上,我们可以基本理解出什么是回调了吧。重复一下,就是在通过A对象里面调用了B类的C方法,但是被调用B类的引用又反过来调用A对象里面的D方法。 代码里面有一个play方法,通过输出的结果我们发现是paly方式先被执行。这里体现了一个异步的回调过程。 因为小明问问题是通过一个新的线程来进行的。所以问问题并不会堵塞住原来的主线程(也就是play的线程)。
以上就是我对回调的理解了,可能有所错漏,欢迎批评指正。