【Java/Android】对回调机制的理解

从一开始接触回调机制到现在,一直不太明白这其中的过程和原理。直到最近在网上混了很久,才突然明白。对于我这个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函数  将监听发起者创建的接口实例传给了被监听者。所以被监听者 通过引用这个实例就可以在条件满足时 调用监听者已经实现的内容。

真谛 = 传递接口实例。

哈哈,不知我说的对不对。如果有不对,欢迎指教!!!本文就暂时到这里了。

猜你喜欢

转载自blog.csdn.net/dfghhvbafbga/article/details/51009595
今日推荐