zoukankan      html  css  js  c++  java
  • 一个经典例子让你彻彻底底理解java回调机制

    本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273

    以前不理解什么叫回调,天天听人家说加一个回调方法啥的,心里想我草,什么叫回调方法啊?然后自己就在网上找啊找啊找,找了很多也不是很明白,现在知道了,所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法,这样子说你是不是有点晕晕的,其实我刚开始也是这样不理解,看了人家说比较经典的回调方式:

    • Class A实现接口CallBack callback——背景1
    • class A中包含一个class B的引用b ——背景2
    • class B有一个参数为callback的方法f(CallBack callback) ——背景3
    • A的对象a调用B的方法 f(CallBack callback) ——A类调用B类的某个方法 C
    • 然后b就可以在f(CallBack callback)方法中调用A的方法 ——B类调用A类的某个方法D

    大家都喜欢用打电话的例子,好吧,为了跟上时代,我也用这个例子好了,我这个例子采用异步加回调

    有一天小王遇到一个很难的问题,问题是“1 + 1 = ?”,就打电话问小李,小李一下子也不知道,就跟小王说,等我办完手上的事情,就去想想答案,小王也不会傻傻的拿着电话去等小李的答案吧,于是小王就对小李说,我还要去逛街,你知道了答案就打我电话告诉我,于是挂了电话,自己办自己的事情,过了一个小时,小李打了小王的电话,告诉他答案是2

    1. /**
    2. * 这是一个回调接口
    3. * @author xiaanming
    4. *
    5. */ 
    6. public interface CallBack { 
    7.     /**
    8.      * 这个是小李知道答案时要调用的函数告诉小王,也就是回调函数
    9.      * @param result 是答案
    10.      */ 
    11.     public void solve(String result); 
    1. /**
    2. * 这个是小王
    3. * @author xiaanming
    4. * 实现了一个回调接口CallBack,相当于----->背景一
    5. */ 
    6. public class Wang implements CallBack { 
    7.     /**
    8.      * 小李对象的引用
    9.      * 相当于----->背景二
    10.      */ 
    11.     private Li li;  
    12.  
    13.     /**
    14.      * 小王的构造方法,持有小李的引用
    15.      * @param li
    16.      */ 
    17.     public Wang(Li li){ 
    18.         this.li = li; 
    19.     } 
    20.      
    21.     /**
    22.      * 小王通过这个方法去问小李的问题
    23.      * @param question  就是小王要问的问题,1 + 1 = ?
    24.      */ 
    25.     public void askQuestion(final String question){ 
    26.         //这里用一个线程就是异步, 
    27.         new Thread(new Runnable() { 
    28.             @Override 
    29.             public void run() { 
    30.                 /**
    31.                  * 小王调用小李中的方法,在这里注册回调接口
    32.                  * 这就相当于A类调用B的方法C
    33.                  */ 
    34.                 li.executeMessage(Wang.this, question);  
    35.             } 
    36.         }).start(); 
    37.          
    38.         //小网问完问题挂掉电话就去干其他的事情了,诳街去了 
    39.         play(); 
    40.     } 
    41.  
    42.     public void play(){ 
    43.         System.out.println("我要逛街去了"); 
    44.     } 
    45.  
    46.     /**
    47.      * 小李知道答案后调用此方法告诉小王,就是所谓的小王的回调方法
    48.      */ 
    49.     @Override 
    50.     public void solve(String result) { 
    51.         System.out.println("小李告诉小王的答案是--->" + result); 
    52.     } 
    53.      
    1. /**
    2. * 这个就是小李啦
    3. * @author xiaanming
    4. *
    5. */ 
    6. public class Li { 
    7.     /**
    8.      * 相当于B类有参数为CallBack callBack的f()---->背景三
    9.      * @param callBack 
    10.      * @param question  小王问的问题
    11.      */ 
    12.     public void executeMessage(CallBack callBack, String question){ 
    13.         System.out.println("小王问的问题--->" + question); 
    14.          
    15.         //模拟小李办自己的事情需要很长时间 
    16.         for(int i=0; i<10000;i++){ 
    17.              
    18.         } 
    19.          
    20.         /**
    21.          * 小李办完自己的事情之后想到了答案是2
    22.          */ 
    23.         String result = "答案是2"; 
    24.          
    25.         /**
    26.          * 于是就打电话告诉小王,调用小王中的方法
    27.          * 这就相当于B类反过来调用A的方法D
    28.          */ 
    29.         callBack.solve(result);  
    30.  
    31.          
    32.          
    33.     } 
    34.      
     
    1. /**
    2. * 测试类
    3. * @author xiaanming
    4. *
    5. */ 
    6. public class Test { 
    7.     public static void main(String[]args){ 
    8.         /**
    9.          * new 一个小李
    10.          */ 
    11.         Li li = new Li(); 
    12.  
    13.         /**
    14.          * new 一个小王
    15.          */ 
    16.         Wang wang = new Wang(li); 
    17.          
    18.         /**
    19.          * 小王问小李问题
    20.          */ 
    21.         wang.askQuestion("1 + 1 = ?"); 
    22.     } 
     

    通过上面的那个例子你是不是差不多明白了回调机制呢,上面是一个异步回调,我们看看同步回调吧,onClick()方法

    现在来分析分析下Android View的点击方法onclick();我们知道onclick()是一个回调方法,当用户点击View就执行这个方法,我们用Button来举例好了

    1. //这个是View的一个回调接口 
    2. /**
    3. * Interface definition for a callback to be invoked when a view is clicked.
    4. */ 
    5. public interface OnClickListener { 
    6.     /**
    7.      * Called when a view has been clicked.
    8.      *
    9.      * @param v The view that was clicked.
    10.      */ 
    11.     void onClick(View v); 
    1. package com.example.demoactivity; 
    2.  
    3. import android.app.Activity; 
    4. import android.os.Bundle; 
    5. import android.view.View; 
    6. import android.view.View.OnClickListener; 
    7. import android.widget.Button; 
    8. import android.widget.Toast; 
    9.  
    10. /**
    11. * 这个就相当于Class A
    12. * @author xiaanming
    13. * 实现了 OnClickListener接口---->背景一
    14. */ 
    15. public class MainActivity extends Activity implements OnClickListener{ 
    16.     /**
    17.      * Class A 包含Class B的引用----->背景二
    18.      */ 
    19.     private Button button; 
    20.  
    21.     @Override 
    22.     public void onCreate(Bundle savedInstanceState) { 
    23.         super.onCreate(savedInstanceState); 
    24.         setContentView(R.layout.activity_main); 
    25.         button = (Button)findViewById(R.id.button1); 
    26.          
    27.         /**
    28.          * Class A 调用View的方法,而Button extends View----->A类调用B类的某个方法 C
    29.          */ 
    30.         button.setOnClickListener(this); 
    31.     } 
    32.  
    33.     /**
    34.      * 用户点击Button时调用的回调函数,你可以做你要做的事
    35.      * 这里我做的是用Toast提示OnClick
    36.      */ 
    37.     @Override 
    38.     public void onClick(View v) { 
    39.         Toast.makeText(getApplication(), "OnClick", Toast.LENGTH_LONG).show(); 
    40.     } 
    41.  

     下面是View类的setOnClickListener方法,就相当于B类咯,只把关键代码贴出来

     [java] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    1. /**
    2. * 这个View就相当于B类
    3. * @author xiaanming
    4. *
    5. */ 
    6. public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { 
    7.     /**
    8.      * Listener used to dispatch click events.
    9.      * This field should be made private, so it is hidden from the SDK.
    10.      * {@hide}
    11.      */ 
    12.     protected OnClickListener mOnClickListener; 
    13.      
    14.     /**
    15.      * setOnClickListener()的参数是OnClickListener接口------>背景三
    16.      * Register a callback to be invoked when this view is clicked. If this view is not
    17.      * clickable, it becomes clickable.
    18.      *
    19.      * @param l The callback that will run
    20.      *
    21.      * @see #setClickable(boolean)
    22.      */ 
    23.      
    24.     public void setOnClickListener(OnClickListener l) { 
    25.         if (!isClickable()) { 
    26.             setClickable(true); 
    27.         } 
    28.         mOnClickListener = l; 
    29.     } 
    30.      
    31.      
    32.     /**
    33.      * Call this view's OnClickListener, if it is defined.
    34.      *
    35.      * @return True there was an assigned OnClickListener that was called, false
    36.      *         otherwise is returned.
    37.      */ 
    38.     public boolean performClick() { 
    39.         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); 
    40.  
    41.         if (mOnClickListener != null) { 
    42.             playSoundEffect(SoundEffectConstants.CLICK); 
    43.              
    44.             //这个不就是相当于B类调用A类的某个方法D,这个D就是所谓的回调方法咯 
    45.             mOnClickListener.onClick(this); 
    46.             return true; 
    47.         } 
    48.  
    49.         return false; 
    50.     } 

     这个例子就是Android典型的回调机制,看完这个你是不是更进一步的理解了回调机制呢? 线程run()也是一个回调方法,当执行Thread的start()方法就会回调这个run()方法,还有处理消息都比较经典等等

     这也是小弟对回调机制的一点拙见,不懂的请留言,如果有错误希望指出!多谢!

  • 相关阅读:
    poj 1743 Musical Theme 后缀数组
    poj 1743 Musical Theme 后缀数组
    cf 432D Prefixes and Suffixes kmp
    cf 432D Prefixes and Suffixes kmp
    hdu Data Structure? 线段树
    关于position和anchorPoint之间的关系
    ios POST 信息
    CALayers的代码示例
    CALayers详解
    ios中得sqlite使用基础
  • 原文地址:https://www.cnblogs.com/tbyang/p/4174148.html
Copyright © 2011-2022 走看看