android 接口回调用处,今天,我们细说回调

楔子

苏格拉底曾说过:“不懂回调的程序员不是一个好厨子”。

但对很多刚入行的朋友来说,回调确实又是一个不明觉厉的东西,理解起来稍稍有一点摸不着头脑。那么今天,笔者就以最浅显通俗的文字,带大家一起揭开回调神秘的面纱

一、回调到底是个啥?

根据《Java核心技术 第八版》中对回调的定义,回调(callback)是一种常见的程序设计模式。在这种模式中,可以指出某个特定事件发生时应该采取的动作。

啥意思?举个例子,今天你上班上到一半的时候,老板突然跑过来说:“xxx,去把办公室地扫了,扫干净了给我说一下。”好了,然后你现在自愿去扫地。扫了半个小时终于整完了,这个时候你马上跑去办公室给老板报告:“x总,地都扫干净了!”OK,你跑去给领导报告的这个动作就叫做“回调”。

再举个程序之中运用回调的例子?

OK,对Android程序员来说,我想就算你不知道回调,你也一定知道View的点击事件,点击事件就完全符合标准的回调定义“指出某个特定事件发生时应该采取的动作”。那么我们一起来看看点击事件长什么样子

view.setOnClickListener(new View.OnClickListener(){

@Override

public void onClick(View v) {

//do something

}

});

这是一个点击事件的常见写法,在onClick()方法里面实现view被点击时需要执行的逻辑即可。可是,这个onClickListener()是个啥?setOnclickListener()又是个啥?看官别急,且听我娓娓道来。

二、那我怎么写一个回调?

先甩代码

public class Coder{

//声明回调对象

private void SweepFloorListener listener;

//定义回调接口

interface SweepFloorListener{

void onFinish(String str);

}

//回调对象的实例化

public void setSweepFloorListener(SweepFloorListener listener){

this.listener = listener;

}

private void fun(){

//执行回调方法

listener.onFinish("扫完啦!");

}

}

public class Boss{

private Coder coder = new Coder()

private void fun(){

coder.setSweepFloorListener(new Coder.SweepFloorListener(){

@Override

public void onFinish(String str){

//扫完地了

doSomething(str)

}

});

}

}

OK,这样我们就实现了一个简单的回调。

仔细看,coder.setSweepFloorListener()是不是和我们上面的点击事件view.setOnclickListener()长得一模一样?一样就对了

现在我们来逐一分析回调的组成。

回调是由接口实现的,所以我们首先要写一个接口SweepFloorListener,接口里面要定义一些方法。啥方法?就是你想要在回调的时候执行的方法。比如说老板要你扫完地了告诉他,那你就要定义一个onFinish()方法表示扫完地了执行这个方法。

声明一个回调的对象。

要写一个set方法来实现对回调对象的实例化。那么为什么要有这个方法?我自己new对象不行吗?还真不行,因为今天可能是张老板叫你扫地,明天可能是李老板叫你,后天又可能是王老板,那你怎么知道扫完了该给谁汇报?所以我们才需要通过set方法传过来对象,这样我们才知道:“哦,今天扫完了该给李老板汇报”。

执行回调方法。就是在你扫完地的时候执行listener.onFinish()方法

接收回调。这一步是站在老板的角度:今天心情好,随机抓一个程序员扫地。当他扫完的了需要告诉我地都扫完了,这个时候就给他安一个回调,具体就是执行coder.setSweepFloorListener()方法,给这个方法传入一个回调接口,就是Coder.SetSweepFloorListener()参数,然后重写这个回调接口里面的onFinish()方法,当onFinish()方法执行的时候,就表示地已经扫完了,扫地的程序员已经在通知我了。

三、那有没有更优雅的写法?

1.Lambda表达式

我们可以使用Lambda表达式来使代码看起来更优雅,其实质是没有变的,如点击事件

view.setOnClickListener(new View.OnClickListener(){

@Override

public void onClick(View v) {

finish();

}

});

可以用Lambda表达式改写

view.setOnClickListener(v -> finish());

这里的v表示onClick(View v)的参数v

coder.setSweepFloorListener(new Coder.SweepFloorListener(){

@Override

public void onFinish(String str){

doSomething(str);

}

});

可以改写为

coder.setSweepFloorListener(str -> doSomething(str));

这里的str表示onFinish(String str)的参数

怎么样,看起来是不是优雅多了?

那还有没有更优雅的?

2.Kotlin高阶函数实现回调

作为一个Android开发人员,怎么能不会Kotlin呢?Kotlin的高阶函数特性可以让我们更优雅的实现回调。

对Coder和Boss类进行改写

class Coder(){

private lateinit var onFinish: (String) -> Unit

fun setSweepFloorListener(onFinish:(String) -> Unit){

this.onFinish = onFinish

}

private fun sweepFloor(){

//执行回调方法

onFinish("扫完啦!")

}

}

class Boss(){

private coder = Coder()

private fun test(){

coder.setSweepFloorListener{ str -> doSomething(str) }

}

}

这就很优雅了,我们直接干掉了回调接口SweepFloorListener()。

卧槽,还可以这么干?

所谓高阶函数,就是指可以接收函数作为入参的函数,嗯……好像听起来跟Lambda表达式是一个东西。那么我们这里具体是怎么运用了高阶函数来实现的回调呢?

我们首先定义了一个变量onFinish,这个变量本身就是一个函数,(String) -> Unit 表示这个函数的入参为一个String,没有返回值

然后写了一个setSweepFloorListener()方法来为这个变量进行实例化

需要的地方直接调用onFinish(str)方法即可

在另一个类里面进行回调coder.setSweepFloorListener{ str -> doSomething(str) }

OK,这样我们就使用Kotlin优雅地实现了回调。

四、总结

今天总结了回调的几种不同实现方式,希望能给到初级的朋友们一些帮助。

有不对之处还望各位同僚雅正。

参考资料:

《Java核心技术 第八版》

《解密Kotlin编程原理》

作者:机智的张尼玛

链接:https://juejin.im/post/5e4cdaa3e51d4526e807e96e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值