Java回调机制的“简单”理解

刚刚接触Java回调的时候真是一脸懵逼,在网上也搜索了大量的资料,试图重新理解。但发现网上的各种解释,阐述的都很复杂,甚至两个类的调用关系都解释反了,误导性很强。下面从工作的应用场景上,分别JavaAndroid应用两个方面去理解一下。

1.多种理解:

(1)首先阐述一下,网络上最多的一个类比描述:小王有一个问题需要处理,所以向小李请教。小李说需要思考一下,解答之后再给小王回复。一段时间之后,小李打电话告诉了小王问题的答案。其中“电话号码”就可以看作是一个“回调接口”。这只是一个很感性的认识。

(2)然后阐述一下,很官方的一个描述:A类有方法c()和e(),B类有一个方法d(),方法c()中调用了方法d(),在方法d()执行过程中,又调用了e()方法。e()方法就是所说的“回调函数”。这个描述是一个抽象的认识。


(3)再说一下我自己的一个理解:就以APP层和FrameWork层为例,APP层在实现功能过程中,调用FrameWork库中的API方法fun();但是fun()方法需要APP层传下来一个参数值,才能返回一个值,供APP层去实现功能。这个fun()方法就是回调方法。

2.Java场景

下面通过一个“更改前端界面”需求的APP层和FrameWork层的调用关系来具体理解一下“回调机制”。

首先是定义一个接口,并声明“execute()"方法。

public interface CallBackInterface {
    void execute();
}

应用层的实现继承这个接口,并实现对应的方法。同时开启appRun()方法。在此方法中获取一个实例,首先把继承接口的appClientOne,通过setCallBackInterface注册到了底层(只有注册在底层,底层才能调用execute()方法),然后再调用底层的方法drawPage()。很明显:appClientOne对应的是A类,appRun()对应c()方法,execute()对应e()方法。

/**
 * 应用端实现回调接口
 */
public class AppClient {

    public static class AppClientOne implements CallBackInterface {
        @Override
        public void execute() {
            System.out.println("需求只是在变: 这里模拟渲染前端界面为红色");
        }

        public void appRun() {
            FrameworkService frameworkService = new FrameworkService();
            frameworkService.setCallBackInterface(new AppClientOne());
            frameworkService.drawPage();
        }
    }
}

FrameWork层获取了注册的参数callBackInterface实例,在执行drawPage()执行完的时候,调用execute(),完成了回调。同样也很明显:FrameWork对应的就是B类,drawPage()对应d()方法。

public class FrameworkService {

    private CallBackInterface callBackInterface = null;

    public void setCallBackInterface(CallBackInterface callBackInterface) {
        this.callBackInterface = callBackInterface;
    }

    /**
     * 渲染前端界面颜色
     */
    public void drawPage() {
        //渲染前端界面的准备工作
        System.out.println("渲染前端页面颜色准备工作");

        //调用留给前端进行个性化定制的接口
        System.out.println("选用前端个性化渲染的颜色");
        callBackInterface.execute();
    }
}

3.Android场景

对java回调有个具体的了解之后,再回到Android回调机制。在Android当中,回调是极为常见的,其中最典型就是“button”的点击事件,我们可以试着重新理解一下。

下面是常见的MainActivity类中相关代码。MainActivity类明显对应的就是A类,onCreate方法(对应方法c())中,获取Button的一个实例,并注册监听事件setOnclickListener,onClick()方法也进行了实现。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button)findViewById(R.id.bottom);
        btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        //do something
    }

APP层的代码很清晰了,Framework层是如何实现setOnclickListener,并调用onClick方法的呢,我们点击跳转,注册的监听事件setOnclickListener,看到代码如下,而且是View类当中的方法,Button就是继承View的嘛。

 public void setOnClickListener(@Nullable OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        getListenerInfo().mOnClickListener = l;
    }

看到了setOnclickListener的实现,然后查找一下对应的实例mOnclickListener在哪里调用了onClick方法。看到响应View点击的有一个performClick() 方法,说明Framework层是在执行这个方法时进行了回调。

public boolean performClick() {
        final boolean result;
        final ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            li.mOnClickListener.onClick(this);
            result = true;
        } else {
            result = false;
        }

        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);

        notifyEnterOrExitForAutoFillIfNeeded(true);

        return result;
    }
相信在具体的Java场景和Android场景,和一些抽象的定义,这几种理解结合起来,会对Java的回调有一个比较具体准确的认知了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值