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