说明
最近在写代码,发现 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);
}
//重写 onClick 方法
@Override
public void onClick(View view) {
Toast.makeText(this,"点击到回调方法按钮啦!",Toast.LENGTH_SHORT).show();
}
}
查看源码
- OnClickListener 接口。接口很简单,只包含一个 onClick(View var1) 方法,每一个实现接口的类都必须实现 onClick(View var1) 方法。是不是觉得很熟悉呢?没错,就是我们在 MainActivity 中重写的方法。继续往下看
public interface OnClickListener {
void onClick(View var1);
}
- 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;
}
- 点击触发的方法 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;
}
总结
现在我们重新梳理一下回调过程,如下图。首先 MainActivity 调用了 View 类中 setOnClickListener() 方法,将自身传参给 mOnClickListener 对象。当有点击事件到来时,触发 performClick() 方法,这个时候就会回调 onClick() 方法。这个方法就是传参进来的 MainActivity类重写的 onClick() 方法。所以,回调机制就是 A 类调用 B 类的方法,然后B 类反过来调用 A 类的方法。
使用规则
① A 类实现接口 CallBack ,重写抽象方法
② A 类存在可以调用 B类的引用,如上例中 Button,因为 Button 继承自 View
③ B 类提供一个方法 fun,参数包含 CallBack 接口类型
④ A 类通过引用调用B类方法 fun ,所以B 类就可以回调 A 类重写的抽象方法应用场景
回调机制应用很广泛,以我现在工作为例子,项目在请求网络数据、版本更新应用到回调机制。由于主线程不能进行耗时操作,必须开子线程获取到数据,这里就可以通过回调机制把获取到的数据传递给主线程,版本更新也是同样的道理,这里就不累赘了。以上属于个人理解,有不懂得可以留言,欢迎大家评论!