您的位置:首页 > 其它

接口回调,用最简单的一个匿名内部类来讲解(附接口回调高级应用场景,让你对接口的了解登堂入室)

2018-01-05 16:59 435 查看
接口回调,是Java开发者必须要学的一个东西,可是他呢,书上没有,大神博客里也没有,所以导致了有部分小伙纸并不了解这个知识,所以这里做一个最简单的讲解。

(先不牵扯什么异步回调、同步回调)

首先,只需要记住一点,接口回调的含义就是把代码换个地方写

正常我们是这样写的

public class Data3 extends MyData {

Data3() {
System.out.print("-----");
}


可是我们因为某种原因,不得不把代码放到另外一个地方去写,怎么办?我们第一时间想到的是,再新建一个方法,调用这个方法即可。

public class Data3 extends MyData {

Data3() {
cal();
}

void cal() {
System.out.print("-----");
}

这样其实已经算是回调了,但是我们没有采用接口,采用的是方法,所以称之为方法回调。

但是因为种种原因(原因稍后会讲),我们不能总写在我们这一个类里吧?所以我们需要弄一个类,这里用内部类的形式

public class Data3 extends MyData {

Data3() {
C c = new C();
c.cal();
}

class C {
void cal() {
System.out.print("-----");
}
}


但是总是要新建一个类,这性能开销和代码量开销也太大了吧!所以我们采用接口的形式

public class Data3 extends MyData {

Data3() {
call.whatToDo();
}

Call call = new Call() {
@Override
public void whatToDo() {
System.out.print("-----");
}
};

interface Call {
void whatToDo();
}
}

定义一个内部接口,再“实例化”这个接口,再调用这个接口里的方法。这就是接口回调了。

有人可能有疑问,为什么接口可以实例化呢?其实上述代码,是创建了一个匿名内部类,再继承了这个接口,效果等同于下面的代码:

public class Data3 extends MyData {

Data3() {
xxx x = new xxx();
x.whatToDo();
}

interface Call {
void whatToDo();
}

class xxx implements Call {
@Override
public void whatToDo() {
System.out.print("-----");
}
}
}

创建一个类,继承这个接口,调用的是这个类的方法。而上面的就是通过匿名内部类的形式,其实就是Java的语法糖,让你可以少些许多代码。讲到这里,看官肯定已经对接口回调掌握通透了。

下面来分析下,为什么需要用接口回调,接口回调的应用场景是怎么样的

onClick就是一例

mRv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//do some thing
}
});

当你的点击事件点击了,他不会立刻执行代码,他会执行onClick方法,而onClick方法是交给我们来实现的。所以我们可以验证我们的结论,接口回调就是让你的代码换一个地方执行。如果你没有设置这个监听器的话,那么虽然有点击事件,但是方法肯定得不到执行。但是如果设置了监听器的话,你所设置的接口里的方法就会得到执行。所以我们想进行接口回调,就必须让调用者得到你这个接口。很显然这个setOnClickListener就是一个传递接口的方法。

可以看一下源码

public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}

看,这里就是把我们传进来的接口赋值了。可想而知,最后我们执行的时候,肯定会调用getListenerInfo().mOnClickListener.onClick,感兴趣的同学可以自行查看源码。我们说了我们想进行接口回调,就必须让调用者得到你这个接口,我们之前为什么没有设置接口的方法呢?因为接口就是一个成员变量啊,自然可以直接调用。而如果你平时在用的时候,发现想要让两个类之间进行通信,那么你必须先获取其中的那个类的实例,比如说是object,再调用objet.setListener(listener)即可。

其实这种简单的应用还有很多很多,下面介绍一下进阶的应用。Android消息机制

安卓的消息机制和接口回调有啥区别呢?其实消息机制的基础就是接口回调!只不过,他把你所有的接口都进入一个队列,可以灵活自如地控制这一系列的回调何时执行,先后顺序。上图:



图中的每个小方块,都是一个接口。这里就是消息的灵活性了。此外他可以灵活地切换线程,实现线程间的通信,这也是普通的接口回调做不到的。

看似神秘的观察者模式 

何为观察者模式,他和接口回调的区别简单来说就是他是一对多的。比如有多个观察者同时观察着一个被观察者,在被观察者改变的时候,观察者全部都观察到了,并且做出了响应。这个过程看似高大上,其实无非也不过是利用了接口回调。 已经精通接口回调的你应该可以轻松想到是怎么实现的了。他就是当被观察者内容改变时,会执行被观察 者中的某个方法,而该方法里面调用的是所有观察者接口中的方法,从而实现了一对多的观察。

再上升一下,架构,MVP模式

MVP分V层,P层,M层。通俗来讲,V是UI,P是媒婆,M是业务。P中会维护V层和M层的引用,通过分别调用V层和M层的接口中的方法,来实现业务和UI的分离。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐