Android源码分析之 - 从Button点击事件来分析Java接口回调

Android源码分析之 - 从Button点击事件来分析Java接口回调

1.1 最终效果

这里写图片描述

1.2 实例目录

这里写图片描述

1.3 源码分析

1.3.1 点击事件执行方法一

  • 点击事件
public class MainActivity extends AppCompatActivity {

    private Button button;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        clickEvent();
    }

    private void initView() {
        button = findViewById(R.id.button);
        textView = findViewById(R.id.textview);
    }

    private void clickEvent() {
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText("我是点击后的结果");
            }
        });
    }

}
  • 点击button执行点击事件
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 响应点击事件
    }
});
  • 源码分析

先看button.setOnClickListener()的源码,跳转到View内部执行View的setOnClickListener()方法,这是因为Button继承自TextView,TextView有继承自View,因此Button可以执行View中的public方法:

public void setOnClickListener(@Nullable OnClickListener l) {
    if (!isClickable()) {
        setClickable(true);
    }
    getListenerInfo().mOnClickListener = l;
}

看getListenerInfo()的源码:

ListenerInfo getListenerInfo() {
    if (mListenerInfo != null) {
        return mListenerInfo;
    }
    mListenerInfo = new ListenerInfo();
    return mListenerInfo;
}

它的作用是创建ListenerInfo实例,而ListenerInfo又是View的内部类,而mOnClickListener又是内部类ListenerInfo的一个成员变量,那么mOnClickListener是什么类型呢?

public interface OnClickListener {
    /**
     * Called when a view has been clicked.
     *
     * @param v The view that was clicked.
     */
    void onClick(View v);
}

可以看到OnClickListener是View内部定义的一个接口,这个接口规定执行onClick()方法

看源码getListenerInfo().mOnClickListener = l;,它将用户自己创建的View.OnClickListener的接口实例赋值给getListenerInfo().mOnClickListener即给View的内部类ListenerInfo中的变量OnClickListener赋值,因此在内部类ListenerInfo中执行mOnClickListener.onClick()方法就会回调到用户自定义的View.OnClickListener接口实例中的onClick()方法中,响应点击事件

1.3.2 点击事件执行方法二

  • 点击事件
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button button;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        button.setOnClickListener(this);
    }

    private void initView() {
        button = findViewById(R.id.button);
        textView = findViewById(R.id.textview);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button:
                textView.setText("我是点击之后的结果");
                break;
            default:
                break;
        }
    }
}

可以看到MainActivity实现了View.OnClickListener接口,因此MainActivity需要实现View.OnClickListener接口规定的方法onClick(),为了执行onClick()这个方法,需要将MainActivity的实例赋值给button.setOnClickListener(),先看button.setOnClickListener()的源码:

public void setOnClickListener(@Nullable OnClickListener l) {
    if (!isClickable()) {
        setClickable(true);
    }
    getListenerInfo().mOnClickListener = l;
}

与1.3.1一样,用户将View.OnClickListener接口实例赋值给了View的setOnClickListener方法,这是因为MainActivity实现了View.OnClickListener接口,因此MainActivity的实例就是View.OnClickListener接口实例,下面就与1.3.1一样了,当在View的内部类ListenerInfo中执行mOnClickListener.onClick()方法时,就会回调到MainActivity中的onClick()方法中,去响应点击事件

1.4 接口回调的实质

接口回调的实质就是将接口中方法的执行与实现进行分离

Button点击事件接口中方法在View的内部类ListenerInfo中执行,而接口中方法的实现是在MainActivity中进行,点击事件中接口的执行是由android系统内部机制来控制发起的,而接口的实现是由用户自己控制的,因此可以在接口实现要执行的方法中写入响应接口回调的代码

猜你喜欢

转载自blog.csdn.net/amoscxy/article/details/80189908