从一开始接触回调机制到现在,一直不太明白这其中的过程和原理。直到最近在网上混了很久,才突然明白。对于我这个Android小白还是一件很值得开心的事情。
今天特此在这里写下来我对回调机制的愚见,也做个留念。
下面就从一个小故事开始说起。
----------------------------------------------------------------------
华丽的分割线
----------------------------------------------------------------------
有一天皇帝乾隆(King)想知道地方政府苏州(Local)抓贼怎么样,生产粮食怎么样,就找来一个钦差大臣小栓子(QinChai)说,你给我去地方看看,要是抓贼到20有赏,生产50顿粮食有赏。
于是小栓子就带着圣旨去了苏州。到了苏州,小栓子也不说话,就看着。
皇帝和地方本来知道有钦差大臣这个职位,有这个概念,和钦差的作用,监管地方,执行皇帝命令。(接口及其方法)
苏州官府上也有钦差大臣的住处。
这小栓子一来,就给安排到这住处。
而苏州地方每天依然抓贼,产粮食。小栓子也跟着看着。
直到有一天,苏州抓贼满20个了。这时候小栓子掏出了乾隆的圣旨,“奉天承运,皇帝诏曰:赏银千两”。
又有一天,粮食产到50吨了。小栓子又掏出圣旨,“奉天承运,皇帝诏曰:赏金万两”。
到这,乾隆的两个圣旨被小栓子下达执行了。
----------------------------------------------------------------------
华丽的分割线
----------------------------------------------------------------------
讲这个小故事是什么意思呢?其实这个故事里蕴含了回调机制的真谛。那么这个真谛是什么呢?暂且不急,我们先用代码来实现上面那个小故事。
钦差大臣这个官职(接口)
package callback.test; public interface QinChai { /*这个QinChai(钦差)的官职拥有这两个权利,但是具体该怎么做是皇帝下达 * 这其实就是一个Listener */ //看地方逮小偷 public void onCatchTheftDone(); //看地方生产粮食 public void onMakeGrainDone(); }<strong> </strong>
King类 (想)
package callback.test; public class King { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub King qianLong = new King(); qianLong.wantToKnowLocal(); } public King(){ } public void wantToKnowLocal(){ System.out.println("乾隆:朕想知道苏州逮了多少贼,生产多少粮食"); Local suZhou = new Local(); System.out.println("乾隆:小栓子,你给我去看看,要是逮贼50赏银千两;产量50吨赏金万两!"); //乾隆把小栓子派到苏州去了,并告诉小栓子该怎么做 suZhou.welcomeQinChai(new QinChai(){ public void onCatchTheftDone() { // TODO Auto-generated method stub System.out.println("小栓子:奉天承运,皇帝诏曰:逮贼20,赏银千两!"); } public void onMakeGrainDone() { // TODO Auto-generated method stub System.out.println("小栓子:奉天承运,皇帝诏曰:产粮50,赏金万两!"); } }); } }
地方类
package callback.test; public class Local{ //钦差这个位置,在小栓子没来之前都是空着的 private QinChai qinChaiDaRen = null; private Thread catchTheft = null; private Thread makeGrain = null; private Thread otherThing = null; public Local(){ localShouldDo(); doLocalShouldDo(); } private void localShouldDo(){ System.out.println("地方:我可以逮贼,产粮,做其他事!"); catchTheft = new Thread(){ public void run() { super.run(); catchTheft(); } }; makeGrain = new Thread(){ public void run() { super.run(); makeGrain(); } }; otherThing = new Thread(){ public void run() { super.run(); doOther(); } }; } private void doLocalShouldDo(){ System.out.println("地方:开始干活"); catchTheft.start(); makeGrain.start(); otherThing.start(); } private void catchTheft(){ for(int i = 0;i < 40;i++){ System.out.println("地方:逮贼" + i + "个"); if(null != qinChaiDaRen && i == 20){ qinChaiDaRen.onCatchTheftDone(); } try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private void makeGrain(){ for(int i = 0;i < 60;i++){ System.out.println("地方:产粮" + i + "吨"); if(null != qinChaiDaRen && i == 50){ qinChaiDaRen.onMakeGrainDone(); } try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private void doOther(){ System.out.println("地方:其他事情。。。"); } public void welcomeQinChai(QinChai qinchai){ System.out.println("地方:欢迎钦差大人!"); this.qinChaiDaRen = qinchai; } }
运行结果:
乾隆:朕想知道苏州逮了多少贼,生产多少粮食 地方:我可以逮贼,产粮,做其他事! 地方:开始干活 乾隆:小栓子,你给我去看看,要是逮贼20赏银千两;产量50吨赏金万两! 地方:其他事情。。。 地方:逮贼0个 地方:产粮0吨 地方:欢迎钦差大人! 地方:产粮1吨 地方:逮贼1个 地方:逮贼2个 地方:产粮2吨 地方:产粮3吨 地方:逮贼3个 地方:产粮4吨 地方:逮贼4个 地方:逮贼5个 地方:产粮5吨 地方:产粮6吨 地方:逮贼6个 地方:产粮7吨 地方:逮贼7个 地方:逮贼8个 地方:产粮8吨 地方:逮贼9个 地方:产粮9吨 地方:产粮10吨 地方:逮贼10个 地方:逮贼11个 地方:产粮11吨 地方:产粮12吨 地方:逮贼12个 地方:逮贼13个 地方:产粮13吨 地方:逮贼14个 地方:产粮14吨 地方:逮贼15个 地方:产粮15吨 地方:产粮16吨 地方:逮贼16个 地方:逮贼17个 地方:产粮17吨 地方:逮贼18个 地方:产粮18吨 地方:产粮19吨 地方:逮贼19个 地方:产粮20吨 地方:逮贼20个 小栓子:奉天承运,皇帝诏曰:逮贼20,赏银千两! 地方:产粮21吨 地方:逮贼21个 地方:逮贼22个 地方:产粮22吨 地方:逮贼23个 地方:产粮23吨 地方:逮贼24个 地方:产粮24吨 地方:逮贼25个 地方:产粮25吨 地方:产粮26吨 地方:逮贼26个 地方:产粮27吨 地方:逮贼27个 地方:产粮28吨 地方:逮贼28个 地方:逮贼29个 地方:产粮29吨 地方:产粮30吨 地方:逮贼30个 地方:产粮31吨 地方:逮贼31个 地方:产粮32吨 地方:逮贼32个 地方:产粮33吨 地方:逮贼33个 地方:产粮34吨 地方:逮贼34个 地方:逮贼35个 地方:产粮35吨 地方:逮贼36个 地方:产粮36吨 地方:产粮37吨 地方:逮贼37个 地方:产粮38吨 地方:逮贼38个 地方:逮贼39个 地方:产粮39吨 地方:产粮40吨 地方:产粮41吨 地方:产粮42吨 地方:产粮43吨 地方:产粮44吨 地方:产粮45吨 地方:产粮46吨 地方:产粮47吨 地方:产粮48吨 地方:产粮49吨 地方:产粮50吨 小栓子:奉天承运,皇帝诏曰:产粮50,赏金万两! 地方:产粮51吨 地方:产粮52吨 地方:产粮53吨 地方:产粮54吨 地方:产粮55吨 地方:产粮56吨 地方:产粮57吨 地方:产粮58吨 地方:产粮59吨
从上面的结果可以看出:
小栓子在地方逮贼到20和产量到50的时候分别颁布圣旨进行赏赐。而这是乾隆所事先告诉好的。
----------------------------------------------------------------------
华丽的分割线
----------------------------------------------------------------------
从这个有趣的故事里走出来。小栓子:定义的一个接口,并声明了某些功能。但是不能自己实现。
乾隆:监听的发起者,创建接口实例,实现接口的功能,并把这个接口传给想监听的类。
地方(苏州):被监听者,提供接纳接口实例的setter函数(welcomeQinchai),并有容纳这个实例的位置(如上例中,地方留着的钦差大臣的位置)。
所以,就到回调机制的真谛了。通过 被监听者的setter函数 将监听发起者创建的接口实例传给了被监听者。所以被监听者 通过引用这个实例就可以在条件满足时 调用监听者已经实现的内容。
真谛 = 传递接口实例。
哈哈,不知我说的对不对。如果有不对,欢迎指教!!!本文就暂时到这里了。