java中的回调机制

    xiaoxiao2022-07-14  148

    同步回调

    类A中方法a调用了类B的方法b,方法a等待方法b执行完才能继续执行。

    举个例子:

    某天,小A在用计算机执行某些任务,但有个任务小A不会。

    于是小A叫来小B帮忙。

    由于计算机只有一台,所以小A让小B先帮忙实现那个自己不会的任务。

    小B很快的完成了这个任务。

    然后小A也很快的完成了剩下的任务。

     

    异步回调

    类A中方法a调用了类B中的方法b,给方法b单独开启一个线程,方法a和方法b同时执行,方法b完成后调用回调方法通知方法a。

    举个例子:

    又一天,小A用计算机执行某些任务,小A又碰到了一个不会的任务。

    于是小A又叫来小B帮忙。

    不过,这次小A多准备了一台计算机,一共有两台计算机。

    小A继续执行剩下的任务,同时小B帮助小A实现那个小A不会的任务。

    小B完成任务后通知小A。

     

    下面通过一个网络下载的例子举例说明异步回调。

    public class httpUtils { public static String get(){ new Thread(new Runnable() { public void run() { for(int i = 0; i < 10; ++i){ System.out.println("数据已经下载"+i*10+"%"); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO: handle exception } } } }).start(); try { Thread.sleep(2000); } catch (Exception e) { // TODO: handle exception } return "下载完成"; } }

    首先在httpUtils类中有个get方法。get里面启动了一个线程用来下载数据,当数据下载完成后,返回“下载完成”的字符串。

    String str = httpUtils.get(); System.out.println(str);

    调用get方法并打印结果。

    数据已经下载0% 数据已经下载10% 数据已经下载20% 数据已经下载30% 下载完成 数据已经下载40% 数据已经下载50% 数据已经下载60% 数据已经下载70% 数据已经下载80% 数据已经下载90%

    我们并没有下载完所有的数据,它就提示我们下载完成了。

    这肯定是有问题的。我们分析一下上述代码。

    首先我们在主线程中调用了httpUtils的get方法。在get方法中我们做了这样一件事情。

    我们又启动了一个线程用来下载数据。但我们不知道数据什么时候能下载完成,于是启动一个定时器进行等待。

    当数据下载的时候,get方法继续执行,进入定时器等待。

    但很明显定时器超时,任务还没完成。但这时候get方法仍然只能通知我们任务完成了。

     

    由此分析,我们可以清晰的发现问题----我们并不知道什么时候数据下载完成。

    再看下面的代码。

    public class httpUtils2 { interface MyHttpListener{ public void handleData(String str); public void handleError(String str); } public static void setMyHttpListener(MyHttpListener myHttpListener){ get(myHttpListener); } public static void get(MyHttpListener myHttpListener){ new Thread(new Runnable() { public void run() { for(int i = 0; i < 10; ++i){ System.out.println("数据已经下载"+i*10+"%"); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO: handle exception } } myHttpListener.handleData("下载完成"); } }).start(); } } httpUtils2.setMyHttpListener(new httpUtils2.MyHttpListener(){ public void handleData(String str){ System.out.println(str); } public void handleError(String str){ } });

    结果如下。

    数据已经下载0% 数据已经下载10% 数据已经下载20% 数据已经下载30% 数据已经下载40% 数据已经下载50% 数据已经下载60% 数据已经下载70% 数据已经下载80% 数据已经下载90% 下载完成

    结果符合预期效果,我们继续分析。

    在这里首先httpUtils2调用了setMyHttpListener方法。setMyHttpListener方法中又调用了get方法。

    同样在get方法中我们启动了一个线程来下载数据。

    注意这里在数据下载完成后,我们将“下载完成”传入了接口MyHttpListener的handleData方法中。

    我们在httpUtils2类中只申明了MyHttpListener接口。

    我们将“实例化”的MyHttpListener接口传入了setMyHttpListener方法中(注意这里是匿名类的形式)。

    在这里我们知道数据是什么时候下载完成的吗?我们还是不知道。

    但我们不用管,我们只需要知道当数据下载完成后就会调用handleData方法,并传入相关数据。

    而handleData的实现是由我们自己决定的。

    最新回复(0)