首页 > 编程知识 正文

JAVA接口回调,java接口回调机制

时间:2023-05-06 15:31:50 阅读:250551 作者:1785

回调的含义和用途 什么是回调?

一般来说,模块之间都存在一定的调用关系,从调用方式上看,可以分为三类:同步调用异步调用回调。同步调用是一种阻塞式调用,即在函数A的函数体里通过书写函数B的函数名来调用之,使内存中对应函数B的代码得以执行。异步调用是一种类似消息或事件的机制解决了同步阻塞的问题,例如 A通知 B后,他们各走各的路,互不影响,不用像同步调用那样, A通知 B后,非得等到 B走完后, A才继续走 。回调是一种双向的调用模式,也就是说,被调用的接口被调用时也会调用对方的接口,例如A要调用B,B在执行完又要调用A。

回调的用处

回调一般用于层间协作,上层将本层函数安装在下层,这个函数就是回调,而下层在一定条件下触发回调。例如作为一个驱动,是一个底层,他在收到一个数据时,除了完成本层的处理工作外,还将进行回调,将这个数据交给上层应用层来做进一步处理,这在分层的数据通信中很普遍。

Java中接口回调机制

java接口回调机制想必大家并不陌生,其思想简单,应用广泛,如网络请求、界面的点击监听等,是一个java开发者必须要掌握的基本思想之一。

我们在做java开发时经常会遇到文件下载、请求服务器数据等基本操作,大家都知道网络请求属于耗时操作,我们如果在直接主线程执行这些逻辑时很可能会造成主线程堵塞,从而导致程序崩溃。我们通常都是开启一个子线程来执行网络请求操作。

public void doSomeWork() { new Thread(new Runnable() { @Override public void run() { // 执行逻辑,发起网络请求,如请求后台数据,下载文件等 } }).start();}

上面这段代码想必你已经再熟悉不过了,不过当我们在做一次开发时,经常会多次使用网络请求,比如多次请求服务器的数据,所以我们更愿意将其写成一个小框架: 

public String doRequest(String url) { new Thread(new Runnable() { @Override public void run() { // 执行逻辑,请求后台json数据 } }).start(); //将获取的数据转化为String,并返回 }

那么问题来了: 我们在写成框架时,网络请求是在子线程中进行的,很可能数据还没返回来的时候,doRequest方法就已经执行完了(不懂的就需要去看看守护线程哦),那么这时候返回的数据就没有任何意义了,最终的结果是我们得到的String为空的,而不是我们期待的的数据。

解决此问题的一种方法: 子线程请求到数据后,直接对数据进行处理(缺陷:失去了框架的意义)

public void doRequestAndDealData(String url) { new Thread(new Runnable() { @Override public void run() { // 执行逻辑,请求后台json数据 // 直接对获取到的数据进行处理 } }).start(); }

对比上一段代码,我们这里直接对返回的数据进行了处理,而没有在方法里返回数据,但是这样的处理逻辑就是唯一的了,并不能随着请求的url不同而执行不同的处理逻辑,那么有没有一种方法能将在子线程中获取到的数据"传出去",使其能得到成功的处理呢? 这就是接口回调的巧妙之处了!

先定义一个接口

public abstract class CallBackListener { public abstract void onFinish() public abstract void onError(Exception ex);}

在类A中通过在子线程发起网络请求,并将接口作为参数,写到类A中!

public class A { public void doRequest(String url,CallBackListener backListener) { new Thread(new Runnable() { @Override public void run() { try { // 执行逻辑,发起网络请求,如请求后台数据,下载文件等 backListener.onFinish(); } catch (Exception ex) { backListener.onError(ex); } } }).start(); }}

在类B中调用类A的对象,发起请求,并且对请求得到的数据进行处理。

public class B { public void deal() { A a = new A(); a.doRequest("http://请求的url",new CallBackListener() { @Override public void onFinish() { //请求成功的逻辑,如下载完成后的处理,请求到数据后的处理 } @Override public void onError(Exception ex) { // 异常逻辑 } }); }}

我们在B中调用A的方法时,重写了接口中的方法,当发起的网络请求完成时,就会调用我们重写后的方法,这就是接口回调,这样根据需要来进行不同的重写,同样保留了框架的意义。

我们在下载完成后,界面的点击事件监听,后台数据请求完成时...还有很多地方都可以用到接口回调,掌握其思想后,我们也可以写的更加规范一点了,如将A类中的接口作参数就写为单的一个方法,setListener(CallBackListener listener);

无论如何如何重新分配内存Python Scala中怎么使用def语句定义方法

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。