Java回调

来源:互联网 发布:python 安卓 编辑:程序博客网 时间:2024/06/05 07:10

Java回调机制

回调函数一般也叫作钩子函数
大家用过吗,当你创建一个线程的时候就已经用到了回调机制

new Thread(new Runnable() {    @Override    public void run() {        //TODO task here    }})

那么回调是什么呢?
我个人理解就是多态的一种应用.
它一般通过接口,抽象类实现.
简单理解就是,你要调用的某个方法A内部 , 调用了没有被实现的方法B , 需要你在调用A的时候给补全B , A要回过头来调用B


比如说最常见的回调应用场景就是事件处理
比如说setOnclicklistener这个方法

view.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        //TODO handle event    }});

事件多种多样.每个事件发生之后会触发怎样的操作也是不确定的,这时候就可以在捕获事件方法里定义一个参数,参数类型就是一个简单接口OnClickListener,并在OnClickListener里面定义一个方法onClick,我们规定,这个onClick方法就是用来消费事件的.

在setOnclicklistener方法内部,处理event的位置调用onClick方法

这样尽管事件多种多样,你也可以都使用setOnclicklistener方法去处理,而不必每次都写一个方法,这样就提高了代码的重用性,更便于阅读

这是回调方法的定义,那么回调方法是怎么用的呢?

由于我们在setOnclicklistener方法中定义了一个接口类型的参数OnClickListener,所以当你每次调用setOnclicklistener的时候,你都必须传一个相应的OnClickListener实现类,但我们一般不专门去创建一个实现类,因为我们这个实现类只会用一次,所以我们可以用匿名内部类的方式来写,调用一次实现一次,写在一块,更直观

所以在不同的场合,你只需根据需要在onClick添加相应的实现代码,就可以实现在不同场合消费不同的事件

回过头来看,本来是你去调用setOnclicklistener这个方法,而在setOnclicklistener真正执行过程中却会回过头来执行刚刚你匿名内部类里面实现的方法onClick,这个onClick就叫回调方法,所以把它叫做钩子函数挺形象生动的,勾过来用嘛


回调还经常出现在客户端访问网络的时候,安卓规定在主线程中不可以访问网络更新UI的,你应该放在子线程中去执行这些耗时的操作.不然会阻塞主线程
本来我们从语法上来,这样写也不应该有任何编译上的错误是吧,但是谷歌是不允许你这样写的,你要是在主线程里写个网络请求,编译都无法通过…谷歌这么做也是为了开发的规范吧,强制或者提醒你去子线程进行这些操作,这样对用户更友好

为了应对这样的场景,我们可以建一个工具类HttpUtil并创建一个访问网络的方法,比如说getData,专门用来处理网络请求,对于每次请求,getData里创建一个线程去异步访问网络,这样你主线程没有被阻塞,不影响与用户交互

但是子线程他什么时候执行完,返回一个什么样的结果,这也是不确定的,但他总会有一个结果,要么OK,要么error,要么timeout,所以你总.得想办法handle一下,又因为你这个结果我主线程是要用的,鬼想知道你经历了什么,反正最终都得把结果告知我.

这样就用到我们上面说的回调的思想,先定义一个Callback接口,因为你这个接口是专用的,可以直接定义在HttpUtil内部,在CallBack里定义onResponse,onFailure方法,再在getData的参数中,定义一个CallBack类型参数,在callback里定义的方法在哪里调用呢,就在你子线程处理完得到结果的时候调用

public interface HttpCallBack {    void onResponse(JSONObject jsonObject);    void onFailure(String errorMsg);}

这样一来,这个工具类HttpUtil就是通用的了,你可以用他来下载一张图片,或者发布朋友圈,或者拉取朋友圈json数据等等,而你每次调用的时候都以匿名内部类方式实现CallBack,在response里添加相应的数据处理逻辑,比如说更新图片,解析得到的json数据,或者在onFailure里弹出一个出错对话框,这就是回调在网络请求场景中一个应用

可以总结出,回调一般跟异步有关系
定义:

public void getDate(List<Param> params, String url, final HttpCallBack httpCallBack) {    //new Thread    new Thread(new Runnable() {        @Override        public void run() {            //send request            //...            {                //if success                httpCallBack.onResponse(json);                //if failure                httpCallBack.onFailure(errorMsg);            }        }    }).start();}

使用:

getDate(params, url, new HttpCallBack() {    @Override    public void onResponse(JSONObject jsonObject) {    }    @Override    public void onFailure(String errorMsg) {    }});