以前看了一些接口回调的定义,但是都不是很懂,最近使用到了这一技术,所以就想给大家分享一下自己的理解。
首先看他的定义:可以把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调。
这么长一段,当初看的我晕晕的,实际上这个接口回调主要功能是先给出一个接口,然后你就可以调用这个接口的方法,但是这个接口的实现是什么,要等到运行的时候才知道,这样还是挺抽象的,那咱们举个例子,就比如说,你女朋友给你说明天要你陪他去逛街买东西,这时候作为男朋友的你要做什么准备呢,哈哈,要准备好钱啦,但是这个具体要花多少钱你还不知道,要等明天逛完才清楚,这时候你要计算明天的 花销,你就可以定义一个女朋友接口,写一个明天去购物一个函数,这个函数会返回具体花销多少钱,你计算花销的时候就可以先调用这个函数,看看具体代码实现:
package com.java.test;
/**
* GirlFriend接口
*
* @author LiuShuaiQ
*
*/
public interface GirlFriend {
/**
* GirlFriend明天去逛街买东西
*/
public double buySomethingTomorrow();
}
package com.java.test;
/**
* BoyFriend class
*
* @author LiuShuaiQ
*
*/
public class BoyFriend {
private double payForTomorrow = 0;
public BoyFriend() {
super();
}
/**
* 计算支出,调用GirlFriend接口的buySomethingTomorrow方法
*/
public void countPay(GirlFriend girlFriend) {
payForTomorrow = girlFriend.buySomethingTomorrow();
}
public double getPayForTomorrow() {
return payForTomorrow;
}
public void setPayForTomorrow(double payForTomorrow) {
this.payForTomorrow = payForTomorrow;
}
}
这个时候写主函数,计算支出:
package com.java.test;
public class InterfaceCallBackTest {
public static void main(String[] args) {
BoyFriend mBoyFriend = new BoyFriend();
//接口GirlFriend参数传进来
mBoyFriend.countPay(new GirlFriend() {
public double buySomethingTomorrow() {
return 300;
}
});
System.out.println(mBoyFriend.getPayForTomorrow());
}
}
其实在Android中有很多使用到接口回调的地方,比如说事件的监听:
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//.........
}
});
这个地方的OnClickListener其实是View中的一个内部接口,定义了一个点击事件,但这个事件具体做什么事情,是等程序运行的时候才知道的。
这是OnClickListener的源码:
/**
* 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);
}
我们用它还能达成一个效果,这也是我最近经常使用到的,就是在Android中使用AsyncTask进行异步任务时,想用它的onPostExecute()方法进行更新UI但是你的AsyncTask子类与要更新的Activity不在一个类里,这时你用它来更新UI就必须获得组件的引用,一个解决方法是通过参数传进来,要更新的组件少时这样用还可以,但是如果组件多了,用接口回调会更方便,看一个例子:
public class PatientInfoAsync extends AsyncTask<String, Void, Patient> {
private Context mContext;
//接口定义见下文
private SocketInfoOfPatirntInterface mInfoInterfce;
public PatientInfoAsync(Context context,
SocketInfoOfPatirntInterface mInfoInterfce) {
super();
mContext = context;
this.mInfoInterfce = mInfoInterfce;
}
@Override
protected Patient doInBackground(String... params) {
........
//中间代码省略
.......
//返回一个Patient类的对象,(Patient是自定义的一个类)
return patient;
}
@Override
protected void onPostExecute(Patient result) {
super.onPostExecute(result);
if (result != null) {
mInfoInterfce.getPatient(result);
} else {
Toast.makeText(mContext, "失败!",
Toast.LENGTH_SHORT).show();
}
}
}
在PatientInfoAsync 中我们定义了一个SocketInfoOfPatirntInterface 接口:
public interface SocketInfoOfPatirntInterface {
public void getPatient(Patient patient);
}
这样我们就可以在要用PatientInfoAsync 更新UI的Activity中实现这个接口,然后作为参数传到PatientInfoAsync 的构造方法中,剩下的代码就不贴出来了,有兴趣的朋友可以试一试。