Why does the XML onClick attribute set an OnClickL

2020-05-03 01:47发布

问题:

When Android inflates a Button with an onClick XML attribute, it internally sets a DeclaredOnClickListener on that Button which then uses reflection to trigger the actually onClick method in our code.

case R.styleable.View_onClick:
    [...]

    final String handlerName = a.getString(attr);
    if (handlerName != null) {
        setOnClickListener(new DeclaredOnClickListener(this, handlerName));
    }
    break;

I noticed that for AppCompatButtons (i.e. normal Buttons in an AppCompatActivity) the same process gets repeated in the AppCompatViewInflater class, resulting in 2 different DeclaredOnClickListeners set in succession.

private void checkOnClickListener(View view, AttributeSet attrs) {
    Context context = view.getContext();
    if (context instanceof ContextWrapper && (VERSION.SDK_INT < 15 || ViewCompat.hasOnClickListeners(view))) {
        TypedArray a = context.obtainStyledAttributes(attrs, sOnClickAttrs);
        String handlerName = a.getString(0);
        if (handlerName != null) {
            view.setOnClickListener(new AppCompatViewInflater.DeclaredOnClickListener(view, handlerName));
        }

        a.recycle();
    }
}

Both methods are executed, and both DeclaredOnClickListeners are created and set on the Button. First the View one, which then gets replaced by the AppCompatViewInflater one. This all happens in the View inflation process. Is that a bug? Or what is the purpose of that behavior?