android 循环回调,Android回调机制浅谈
经典回调方式class A实现接口CallBack callback——背景1class A中包含一个class B的引用b ——背景2class B有一个参数为callback的方法f(CallBack callback) ——背景3A的对象a调用B的方法 f(CallBack callback) ——A类调用B类的某个方法 C然后b就可以在f(CallBack callback)方法中调用A的
经典回调方式
class A实现接口CallBack callback——背景1
class A中包含一个class B的引用b ——背景2
class B有一个参数为callback的方法f(CallBack callback) ——背景3
A的对象a调用B的方法 f(CallBack callback) ——A类调用B类的某个方法 C
然后b就可以在f(CallBack callback)方法中调用A的方法 ——B类调用A类的某个方法D
下面举一个小例子
/*定义一个接口Callback*/
interface Callback{
void doCallback(String result);
}
/*A类实现接口*/
class A implements Callback{
/*A类持有B类的引用,并把b传入A*/
B b;
A(B b){
this.b = b;
}
/*定义A类方法*/
public void funtionA(){
//此时b方法传入的参数必须是Callback的子类,这里我们传入A,因为A实现了Callback
b.setOnClickListener(A.this);
}
@Override
public void doCallback(String result) {
System.out.println("the answer is:"+result);
}
}
class B {
//创建一个含有Callback实例的B类方法
public void setOnClickListener(Callback callback){
String answer = "callback";
/*B类方法中调用A类方法,这个A类方法要包括接口中的那个抽象方法,即doCallback(),并将所得结果作为参数传回A类中
* 这里就是回调,实现内容在B类的回调中完成
*/
callback.doCallback(answer);
}
}
public class CallBackTest{
public static void main(String [] args){
B b = new B();
A a = new A(b);
//调用A类方法进回调
a.funtionA();
}
}
流程分析:
主函数执行到a.funtionA();
调用b.setOnClickListener(a);
String answer = "callback";表示在b中完成了该流程得到结果
a.doCallback(answer);然后将结果以参数的形式传入a中,执行doCallback()方法,回调
System.out.println("the answer is:"+result);//a.doCallback(answer);执行后进行结果输出
button中onclick()的第一种写法
//这个是View的一个回调接口
/**
* Interface definition for a callback to be invoked when a view is clicked.
*/
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* @param v The view that was clicked.
*/
void onClick(View v);
}
package com.example.demoactivity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
/**
* 这个就相当于Class A
* @author xiaanming
* 实现了 OnClickListener接口---->背景一
*/
public class MainActivity extends Activity implements OnClickListener{
/**
* Class A 包含Class B的引用----->背景二
*/
private Button button;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button1);
/**
* Class A 调用View的方法,而Button extends View----->A类调用B类的某个方法 C
*/
button.setOnClickListener(this);
}
/**
* 用户点击Button时调用的回调函数,你可以做你要做的事
* 这里我做的是用Toast提示OnClick
*/
@Override
public void onClick(View v) {
Toast.makeText(getApplication(), "OnClick", Toast.LENGTH_LONG).show();
}
}
/**
* 这个View就相当于B类
* @author xiaanming
*
*/
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
/**
* Listener used to dispatch click events.
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
protected OnClickListener mOnClickListener;
/**
* setOnClickListener()的参数是OnClickListener接口------>背景三
* 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);
}
mOnClickListener = l;
}
/**
* Click的触发是在系统捕捉到ACTION_UP后发生并由performClick()执行的,
*performClick里会调用先前注册的监听器的onClick()方法:
*/
public boolean performClick() {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
if (mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
//这个不就是相当于B类调用A类的某个方法D,这个D就是所谓的回调方法咯
mOnClickListener.onClick(this);
return true;
}
return false;
}
}
注:setOnClickListener()方法只是给mOnClickListener赋值,当用户执行点击操作的时候,由于事件分发机制,最终会触发performClick()方法进而触发onClick()方法产生回调。注意一下思维:btn.setOnClickListener();并不是执行回调,而是给回调创造条件(performClick()方法中的if语句)。
流程分析:
MainActiviy.class执行onCreate(),执行到button.setOnClickListener(this); 假设此时mc为this所指代对象,即为MainActiviy.class的一个对象,将自己传入。
触发点击事件后系统执行View中的performClick(),该方法调用了mc.onClick(view v),此时把执行后结果返回给MainActivity.class,即由A类进行回调
button中onclick()的第二种写法:匿名类写法
//此时button为B(子)类,重写A(父)类View中的setOnClickListener()
button.setOnClickListener(new View.OnClickListener() {
@Override
//注意:此时传入的参数是父类v,也就是说,会将执行结果返回给view
public void onClick(View v) { //做一些操作 doWork(); }
});
//类似于B类中此方法
public void setOnClickListener(Callback callback){
String answer = "callback";
/*B类方法中调用A类方法,这个A类方法要包括接口中的那个抽象方法,即doCallback(),并将所得结果作为参数传回A类中
* 这里就是回调,实现内容在B类的回调中完成
*/
callback.doCallback(answer);
View中代码:
//这里将OnClickListener赋值给了mOnClickListene
public void setOnClickListener(@Nullable OnClickListener l)
{ if (!isClickable()) {
setClickable(true); }
getListenerInfo().mOnClickListener = l; }
public boolean performClick() { sendAccessibilityEvent(
AccessibilityEvent.TYPE_VIEW_CLICKED);
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnClickListener != null) { playSoundEffect(
SoundEffectConstants.CLICK); li.mOnClickListener.onClick(this);
return true; }
return false; }
触发点击事件后系统自动执行view中的perfromClick()方法,自然也就执行到了.mOnClickListener.onClick(view)######还是由View中onClick()调用
两种写法的差别在于:
第一种写法:A类为MainActivity.class,B类为View(Button继承View)
第二种写法:A类为View类,B类为Button类
回调的理解
回调其实是一种双向调用模式,也就说调用方在接口被调用时也会调用对方的接口
翻译翻译就是“实现了抽象类/接口 的实例实现了父类的提供的抽象方法后,将该方法交还给父类来处理”
实现方法交还给提供接口的父类处理!
不好的地方求指教!!!
更多推荐
所有评论(0)