Android接口回调机制

首先解决啥是回调:

举个例子:某天,我打电话向你请教问题,当然是个难题,你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。


C不会自己调用b,C提供b的目的就是让S来调用它,而且C不得不提供。S并不知道C提供的b是什么,因此S会约定b的接口规范(函数原型),然后由C提前通过S的一个函数r告诉S自己将要使用b函数(即注册)。r为注册函数。

简单来说:回调函数就是预留给系统调用的函数,而且我们往往知道该函数被调用的时机,那我们继续完善下上面的那幅图。


看着这幅图,其实我们回想一下,会发现,生活中到处都有回调这种思想存在。软件的很多思想其实只是我们实际生活中思维方式的一种转化。

我们平时考试答题的第一件事是干嘛?没错,是写上学号和姓名。这里注意了,我们填写学号和姓名不是给自己看的(即该方法不是给自己调用的),而是给老师登记分数时看的(预留给系统将来调用),这其实就是一个回调的应用。老师提供接口(输入姓名,学号规则),我们利用接口注册。


看到上面的小示例,大家对回调就有了一些了解了,我们再回到文章刚开始的例子。
那个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。


我们已经大概知道了回调的基本流程,下面,来看看Android中回调的基本使用。

场景一:

Button button = (Button)this.findViewById(R.id.button);    
button.setOnClickListener(newButton.OnClickListener() {    
   //回调函数    
   @override    
   publicvoidonClick(View v) {    
      buttonTextView.setText("按钮被点击了");    
   }    
});   

上面的代码给按钮加了一个事件监听器,这其实就是“回调”最常见的应用场景之一。我们自己不会显式地去调用onClick方法。用户触发了该按钮的点击事件后,它会由Android系统来自动调用。

场景二:

@Override    
publicvoidonCreate(BundlesaveInstanceState) {    
   super.onCreate(saveInstanceState);    
   // You code...    
}    
@Override    
publicvoidonResume() {    
   super.onResume();    
   // You code...    
}   

Activity的整个生命周期基本上都说回调函数在发挥作用。

看了两个我们经常使用的回调方式,我们先来总结下android利用回调的基本方法。其实,只是把我们的那张图翻译了下。


--你类--

package lin.callback.test;  
   
public class You implements Runnable{  
   
       
    private String who;  
     private ContactInterface callBack;    
     public You() {  
            // TODO Auto-generated constructor stub  
     }  
        
    //调用此方法就表示有人联系你了,注册到你这来  
     public void setCallBack(String who,String question,ContactInterface callBack) {  
         this.who = who;      
         System.out.println("你说:当前联系到我的人是"+who+",问题是"+question);  
         this.callBack =callBack;  
     }  
          
     public void handleThings(){  
         //假如你现在正在想问题的答案,需要一点时间  
         for(int i=0;i<100000;i++){    
               if(i == 0){  
                   System.out.println("你正在思考问题.....");  
               }  
         }  
            
         String answer = "答案是A";  
         //想到问题的办法了  
         System.out.println("你说:想到答案了,准备打回去给"+who+"告诉他答案");  
         callBack.callBackByTel(answer);  
     }  
   
    /* (non-Javadoc) 
     * @see java.lang.Runnable#run() 
     */  
    @Override  
    public void run() {  
        try {  
            Thread.sleep(1000);  
            handleThings();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }   
}  
--我类--

public class Me {  
   
     public static void main(String[] args){    
            
         Me me = new Me();  
         me.hasQuestion();  
            
     }  
        
     private void hasQuestion(){  
         //现在有问题想不出来答案,想去问你  
         You you = new You();  
         you.setCallBack("蜗牛", "某道题答案是什么?", new ContactInterface() {  
               
            @Override  
            public void callBackByTel(String answer) {  
                System.out.println("我说:嗯,好的,我收到答案了:"+answer+",谢谢");  
                   
            }  
        });  
        //你接到电话,起床开始思考问题  
        new Thread(you).start();  
     }  
}  
--接口类(规范)--


public interface ContactInterface {
     
    public void callBackByTel(String answer);
     
}
验证结果:
你说:当前联系到我的人是蜗牛,问题是某道题答案是什么?
你正在思考问题
你说:想到问题了,准备打回去给蜗牛告诉他答案
我说:嗯,好的,我收到答案了:答案是A,谢谢

public interface ContactInterface {  
       
    public void callBackByTel(String answer);  
       
}  

对回调的深入思考:

程序的本质就是代码跳转,不管同步异步反射接口虚函数,本质上都是函数调用。函数我们要调用它,就需要它的指针,不同语言通过不同的方式来得到这个指针。而我们定义的接口其实就是一个函数指针,那么那个注册过程,其实就是相当于对那个函数指针赋值。通过这个函数指针来调用我们定义的自实现函数。




首先解决啥是回调:

举个例子:某天,我打电话向你请教问题,当然是个难题,你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。


C不会自己调用b,C提供b的目的就是让S来调用它,而且C不得不提供。S并不知道C提供的b是什么,因此S会约定b的接口规范(函数原型),然后由C提前通过S的一个函数r告诉S自己将要使用b函数(即注册)。r为注册函数。

简单来说:回调函数就是预留给系统调用的函数,而且我们往往知道该函数被调用的时机,那我们继续完善下上面的那幅图。


看着这幅图,其实我们回想一下,会发现,生活中到处都有回调这种思想存在。软件的很多思想其实只是我们实际生活中思维方式的一种转化。

我们平时考试答题的第一件事是干嘛?没错,是写上学号和姓名。这里注意了,我们填写学号和姓名不是给自己看的(即该方法不是给自己调用的),而是给老师登记分数时看的(预留给系统将来调用),这其实就是一个回调的应用。老师提供接口(输入姓名,学号规则),我们利用接口注册。


看到上面的小示例,大家对回调就有了一些了解了,我们再回到文章刚开始的例子。
那个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。


我们已经大概知道了回调的基本流程,下面,来看看Android中回调的基本使用。

场景一:

Button button = (Button)this.findViewById(R.id.button);    
button.setOnClickListener(newButton.OnClickListener() {    
   //回调函数    
   @override    
   publicvoidonClick(View v) {    
      buttonTextView.setText("按钮被点击了");    
   }    
});   

上面的代码给按钮加了一个事件监听器,这其实就是“回调”最常见的应用场景之一。我们自己不会显式地去调用onClick方法。用户触发了该按钮的点击事件后,它会由Android系统来自动调用。

场景二:

@Override    
publicvoidonCreate(BundlesaveInstanceState) {    
   super.onCreate(saveInstanceState);    
   // You code...    
}    
@Override    
publicvoidonResume() {    
   super.onResume();    
   // You code...    
}   

Activity的整个生命周期基本上都说回调函数在发挥作用。

看了两个我们经常使用的回调方式,我们先来总结下android利用回调的基本方法。其实,只是把我们的那张图翻译了下。


--你类--

package lin.callback.test;  
   
public class You implements Runnable{  
   
       
    private String who;  
     private ContactInterface callBack;    
     public You() {  
            // TODO Auto-generated constructor stub  
     }  
        
    //调用此方法就表示有人联系你了,注册到你这来  
     public void setCallBack(String who,String question,ContactInterface callBack) {  
         this.who = who;      
         System.out.println("你说:当前联系到我的人是"+who+",问题是"+question);  
         this.callBack =callBack;  
     }  
          
     public void handleThings(){  
         //假如你现在正在想问题的答案,需要一点时间  
         for(int i=0;i<100000;i++){    
               if(i == 0){  
                   System.out.println("你正在思考问题.....");  
               }  
         }  
            
         String answer = "答案是A";  
         //想到问题的办法了  
         System.out.println("你说:想到答案了,准备打回去给"+who+"告诉他答案");  
         callBack.callBackByTel(answer);  
     }  
   
    /* (non-Javadoc) 
     * @see java.lang.Runnable#run() 
     */  
    @Override  
    public void run() {  
        try {  
            Thread.sleep(1000);  
            handleThings();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }   
}  
--我类--

public class Me {  
   
     public static void main(String[] args){    
            
         Me me = new Me();  
         me.hasQuestion();  
            
     }  
        
     private void hasQuestion(){  
         //现在有问题想不出来答案,想去问你  
         You you = new You();  
         you.setCallBack("蜗牛", "某道题答案是什么?", new ContactInterface() {  
               
            @Override  
            public void callBackByTel(String answer) {  
                System.out.println("我说:嗯,好的,我收到答案了:"+answer+",谢谢");  
                   
            }  
        });  
        //你接到电话,起床开始思考问题  
        new Thread(you).start();  
     }  
}  
--接口类(规范)--


public interface ContactInterface {
     
    public void callBackByTel(String answer);
     
}
验证结果:
你说:当前联系到我的人是蜗牛,问题是某道题答案是什么?
你正在思考问题
你说:想到问题了,准备打回去给蜗牛告诉他答案
我说:嗯,好的,我收到答案了:答案是A,谢谢

public interface ContactInterface {  
       
    public void callBackByTel(String answer);  
       
}  

对回调的深入思考:

程序的本质就是代码跳转,不管同步异步反射接口虚函数,本质上都是函数调用。函数我们要调用它,就需要它的指针,不同语言通过不同的方式来得到这个指针。而我们定义的接口其实就是一个函数指针,那么那个注册过程,其实就是相当于对那个函数指针赋值。通过这个函数指针来调用我们定义的自实现函数。




猜你喜欢

转载自blog.csdn.net/mr_leixiansheng/article/details/78249043