Java接口回调
Posted YQS_Love
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java接口回调相关的知识,希望对你有一定的参考价值。
一、接口回调概述
对于大多数刚刚接触或者没有实际项目的Java学习者来说,并不知道什么是接口回调,接口回调有什么好处,能给开发带来什么好处。下面我将告诉你我所知道的。在我刚刚接触Java时,并不知道什么是接口回调,该怎么用,那时我做了一个小小的项目,在底层处理好数据后,怎么传递给视图进行展示,当时我的做法是开了一个线程,不断的去获取新的值,很显然,这样做的代价是很大的;后面我又用了另外一个方法,就是将数据保存到集合里,每次都取最新的那个值,这样的做法代价也是很大的,需要足够的内存。并且,在一些项目开发中,比如桌面应用或者android App,当视图层改变,底层的某些引用又得改变,增加了维护成本。有没有这样的方法,不管你的视图如何变化,我底层都不需要变,答案是有的,那就是接口回调。
二、接口回调的使用
首先我编写了一个底层服务类,来模拟底层服务。底层服务实现的功能是一个时间倒数器,时间的变化需要实时的通知给试图,这个时候接口回调就派上大用场了。具体实现见如下代码:
package com.yaohong.callback;
/**
* 后台数据服务,计数器,单位秒
* @author Yaohong
*
*/
public class BackgroundService
public static final long SLEEP_TIME = 1000;
private int count = 0;
private int time;
private boolean isStart = true;
private CalCount calCountThread;
// 记录使用者注册的接口
private CalCallbackInterface callback;
public BackgroundService(int time)
this.time = time;
calCountThread = new CalCount();
/**
* 开始倒数
*/
public void start()
calCountThread.start();
/**
* 强制暂停倒数器
*/
public void stop()
isStart = false;
/**
* 注册数据回调接口
* @param callback
*/
public void addTimeListener(CalCallbackInterface callback)
this.callback = callback;
/**
* 定义数据回调接口
* @author Yaohong
*
*/
public interface CalCallbackInterface
public void currentTime(int currentTime);
/**
* 计数器倒数线程
* @author ASUS
*
*/
private class CalCount extends Thread
@Override
public void run()
// 验证time是否正确
if(time <= 0 || time >= Integer.MAX_VALUE)
throw new IllegalArgumentException(time+" is not valid!");
while(isStart)
// ① 使用数据回调接口
if(callback != null)
callback.currentTime(time);
// ②
--time;
if(time < 0 )
isStart = false;
break;
try
Thread.sleep(SLEEP_TIME);
catch (InterruptedException e)
e.printStackTrace();
代码中定义了接口CalCallbackInterface,用于对数据变化时进行回调(如果有需要,可以提取出来,分配到独立的包下)。如果学习过Java图形界面编程的人可能知道,这样的做法如何注册鼠标监听事件一样,那么在使用的时候,只需注册这个接口即可得到实时刷新的数据。
接口的使用:
package com.yaohong.callback;
import com.yaohong.callback.BackgroundService.CalCallbackInterface;
/**
* 接口回调测试
*
* @author Yaohong
*
*/
public class CallbackTestMain
public static void main(String[] args)
int time = 10;
BackgroundService service = new BackgroundService(time);
service.start();
service.addTimeListener(new CalCallbackInterface()
// ③
@Override
public void currentTime(int currentTime)
// ④
System.out.println("Surplus time: " + currentTime);
);
使用的方法很简单,只需注册这个接口即可。详情见上述代码
三、接口回调原理
阐述接口回调原理,我将根据上诉所讲的demo进行讲解。
要行成完整的调用过程的前提必须是使用者要注册这个接口,如果使用者没有调用addTimeListener(…)进行接口注册,那么将不产生调用过程。因此,在底层服务的线程中,一定要对callback变量判断是否为空指针,否则,当用户不注册,那么代码会包空指针异常。
如果用户注册接口后,callback将不在是控制针,程序运行到①代码处时,会先判断callback变量是否为null,如果不为null,那么,程序会跳转到③这行代码,然后执行代码④,当执行完这行代码后,程序会跳转回②处继续执行,从而完成一个回调过程。
在某些应用环境下,回调过程将会复杂些,例如在Android应用开发时,由于API严格限制子线程不能够更新主线程UI,因此,直接在代码④处更新UI是会导致程序崩溃的。为了实现接口回调,Android提供了Handler类来进行辅助更新。Handler本身是一个消息队列,子线程的一些操作都会被加入到这个队列中,然后主线程会从这个队列中取出消息进行执行。
四、总结
这里,我仅仅演示了接口回调的简单使用,并没有讲解过多的东西,希望的是快速学会使用接口回调,这样你可以高效编程,某种程度上也可以减轻代码之间的耦合度。
学习过C/C++的人,应该也知道C/C++的主函数也是通过接口回调的方式进行调用的。可见,接口回调是多么的利于编程,同时实现也比较简单,灵活性也高。
以上是关于Java接口回调的主要内容,如果未能解决你的问题,请参考以下文章