首页 > 代码库 > Java 回调机制详解

Java 回调机制详解

一、说明

 

最近在写代码,发现 Java 回调机制蛮实用。在网上搜索部分资料以后,现在按照自己的理解进行归纳总结 ,有理解错的地方,希望大家能够帮忙指正! 
先从一个很简单的 Android 开发例子说起。我们在界面上使用 Button 时,为其增加点击事件监听大概需要以下几个步骤 : 
① 实例化 Button 对象,如 btn_call_back; 
② btn_call_back.setOnClickListener(MainActivity.this); 
③本类实现 OnClickListener 接口,重写 onClick(View view) 方法。

代码如下,这个时候我们点击按钮就会弹出一段话:”点击到回调方法按钮啦!” 至于为什么能够达到这种效果?就是应用到我们今天主题:Java 回调机制。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn_call_back;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_call_back = (Button) findViewById(R.id.btn_call_back);

        btn_call_back.setOnClickListener(MainActivity.this);
    }

    @Override
    public void onClick(View view) {
        //重写 onClick 方法
        Toast.makeText(this,"点击到回调方法按钮啦!",Toast.LENGTH_SHORT).show();
    }
}

 

二、查看源码

  2.1 OnClickListener 接口。接口很简单,只包含一个 onClick(View var1) 方法,每一个实现接口的类都必须实现 onClick(View var1) 方法。是不是觉得很熟悉呢?没错,就是我们在 MainActivity 中重写的方法。继续往下看

public interface OnClickListener {
    void onClick(View var1);
}

  2.2 setOnClickListener() 方法。这个方法将我们传入的 MainActivity.this 赋值给 mOnClickListener 对象,这样做有什么作用?再看按钮被点击触发的方法

/**
     * Register a callback to be invoked when this view is clicked. If this view is not
     * clickable, it becomes clickable.
     *
     * @param l The callback that will run
     *
     * @see #setClickable(boolean)
     */
    public void setOnClickListener(OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        getListenerInfo().mOnClickListener = l;
    }

  2.3 点击触发的方法 performClick()。这个方法实例 ListenerInfo 类型对象 li 接 mListenerInfo ,当 li != null && li.mOnClickListener != null 时调用 li.mOnClickListener.onClick(this);也就是 MainActivity 类中的我们重写的 onClick(View view) 方法。

    /**
     * Call this view‘s OnClickListener, if it is defined.  Performs all normal
     * actions associated with clicking: reporting accessibility event, playing
     * a sound, etc.
     *
     * @return True there was an assigned OnClickListener that was called, false
     *         otherwise is returned.
     */
    public boolean performClick() {
        final boolean result;
        final ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            li.mOnClickListener.onClick(this);
            result = true;
        } else {
            result = false;
        }

        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
        return result;
    }

  

三、总结

  3.1 现在我们重新梳理一下回调过程,如下图。首先 MainActivity 调用了 View 类中 setOnClickListener() 方法,将自身传参给 mOnClickListener 对象。当有点击事件到来时,触发 performClick() 方法,这个时候就会回调 onClick() 方法。这个方法就是传参进来的 MainActivity类重写的 onClick() 方法。所以,回调机制就是 A 类调用 B 类的方法,然后B 类反过来调用 A 类的方法。 

技术分享

  3.2 使用规则

  ① A 类实现接口 CallBack ,重写抽象方法 
  ② A 类存在可以调用 B类的引用,如上例中 Button,因为 Button 继承自 View 
  ③ B 类提供一个方法 fun,参数包含 CallBack 接口类型 
  ④ A 类通过引用调用B类方法 fun ,所以B 类就可以回调 A 类重写的抽象方法

  3.3 应用场景 

  回调机制应用很广泛,以我现在工作为例子,项目在请求网络数据、版本更新应用到回调机制。由于主线程不能进行耗时操作,必须开子线程获取到数据,这里就可以通过回调机制把获取到的数据传递给主线程,版本更新也是同样的道理,这里就不累赘了。以上属于个人理解,有不懂得可以留言,欢迎大家评论!

Java 回调机制详解