最近在搞项目中的接口回调,整理了一下自己对于接口的理解,并参考了安卓中回调的一些源码,顺便把自己的想法写到博客里。
浅解
1.先从错误的案例开始
private List queryfirstdata() {
query.findObjects(new FindListener<car_logo>() {
@Override
public void done(List<car_logo> list, final BmobException e) {
if (e == null) {
logos.addAll(list);
} else {
}
}
});
return logos;
}
这是一个简单的包含异步任务的方法,而方法的返回值是异步任务完成返回的数据,这里大家一看就明白返回的是null,因为异步任务是耗时操作他会优先retrun返回空值。
2.解决办法
定义一个接口 接口中声明 业务执行的进度
public interface BmobCallback<T>{
void LoadComplete(List<T> list);
void LoadError(BmobException e);
void LoadStart();
}
将接口当做参数传入业务方法中 传入的参数的实现由调用者完成
private void queryfirstdata(BmobCallback bmobCallback) {
bmobCallback.LoadStart();
query.findObjects(new FindListener<car_logo>() {
@Override
public void done(List<car_logo> list, final BmobException e) {
if (e == null) {
bmobCallback.LoadComplete(list);
} else {
bmobCallback.LoadError(e);
}
}
});
}
3.这样我们就完成了一个简单的回调实现,接着我们来看看安卓的点击事件是如何实现回调的
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;
}
这是安卓中点击屏幕中的view执行的方法,他得到View中设置的ListenerInfo里的接口,并在这个方法里调用了这个接口中的onClick方法,再看下面一段代码
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
这段代码我们应该非常熟悉,就是我们设置点击事件实现的方法,他得到了我们传入带有实现的接口并将它赋值给了View中的ListenerInfo()中的mOnClickListener接口
至此,安卓中的回调机制就清晰起来了,正是这种类似于通知的回调,我们用户才能与安卓系统进行一次次的交互
优化
这里我们参照安卓的这种注册回调接口的思想,优化下我们的工程代码
private BmobCallback bmobCallback;
//提供外界的注册接口方法
public void setBmobCallback(BmobCallback bmobCallback){
this.bmobCallback=bmobCallback;
}
queryfirstdata()................ 参照上方
onCreat()中
QueryData queryData=new QueryData();//实例化view
queryData.setBmobCallback(new BmobCallback() {//设置监听
@Override
public void LoadComplete(List list) {
Log.e("taqqq",list.size()+"");
}
@Override
public void LoadError(BmobException e) {
Log.e("taqqq",e.getMessage());
}
@Override
public void LoadStart() {
}
});
queryData.queryfirstdata();//类似点击触发
总结
程序的本质就是代码跳转,不管同步异步反射接口虚函数,本质上都是函数调用。函数我们要调用它,就需要它的指针,不同语言通过不同的方式来得到这个指针。而我们定义的接口其实就是一个函数指针,那么那个注册过程,其实就是相当于对那个函数指针赋值。通过这个函数指针来调用我们定义的自实现函数。
利用函数指针实现回调,在代码的世界中无处不在,但只是一个小部分,愿在代码的大道上你我共勉。
关于作者
陈鸿(大四在校学生,目前寻找实习中)
QQ:568261070
GitHub:https://github.com/MrCodeSniper