不知道是我学Java的时候没有认真听还是怎么的,曾经一直不知道什么是“回调”,它有什么用,百度一大堆,都太复杂看不明白(好吧是我笨),所以想把自己理解的分享给其他看到的人,大家都真正认识一下这个重要的机制。

如果你要进行Android开发,那么回调肯定是会经常用到的,为什么?下面慢慢来说,大牛其实这个地方已经可以离开了......

先从简单的开始,什么是回调?

Java允许我们调用接口的方法,但是有一个前提,就是编译的时候接口的对象必须是一个具体的类,并且这个类实现了接口。当我们调用接口的方法的时候,接口的具体子类中的具体方法会被调用,这就是回调。嗯,我说什么鬼?还是上代码吧。

public interface A {
void printClassName();
}
public class B implements A {
public void printClassName() {
System.out.println("This is class B!");
}
}
public static void main(String[] args) {
A a = new B();
a.printClassName();
}

输出的结果如下:

从上面的代码可以看到,我们在主函数中定义了接口A,也调用了接口A的方法,但是要注意,我们实例化的时候其实new的是一个实现了A接口的具体类,我们调用A中的printClassName方法的时候Java就会去回调B中的该方法。这样做的优点是什么?就是我们在调用的时候,可以完全不管A的子类是如何实现A中的方法的,只需要调用这个方法即可,怎么实现,我们不管,那是子类的事情了,这样其实是解耦的一种很好的方法,如果我们要修改为别的类,只需要把new后面的子类改掉就好。

是不是很简单?如果代码你都懂,那么恭喜你,你已经距离成功只有一步之遥了。

说回Androd,其实里面是有很多地方用到这个机制的,我们也是从简单的说起。

很多时候,我们对某个控件实现点击事件的监听,会像下面这样做:

Button btn = new Button(this);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// doSth
}
});

很多人都觉得,这样很直接明了啊,可是如果我问你,为什么我们要new一个OnClickListener进去呢?如果你不知道,证明你还不完全了解回调。按照我们上面所说的,我们可以调用接口的方法,但是接口需要一个具体的实现,所以我们应该知道,setOnClickListener中的参数应该是一个接口,不信?我们一起看看源码

public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* @param v The view that was clicked.
*/
void onClick(View v);
}

果然,接口中还有一个onClick方法。既然是回调,我们再看看这个方法在哪里被调用了

先看setOnClickListener方法

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

关键是把OnClickListener的对象赋值给了ListenerInfo的mOnClickListener,我们再看下去

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);
return result;
}

我们看到在这个叫做performClick的方法中调用了onClick方法,还有另外一个叫做callOnClick的方法也会调用onClick,区别可以去看看源码的说明,这里不详细。那么这两个方法又在什么时候被执行的呢?其实他们都是在屏幕接收到点击信号的时候,把数据一层一层的往上传递给framework,由framework来调用。对于了解回调,我觉得到这里就足够了,再往下就有点偏了。

要明白的一点就是,在这个类中,调用的是接口的方法。现在你应该明白了吧,为什么我们要new一个OnClickListener的子类呢?就是让编译器知道,调用接口方法的时候,去回调我们设置的OnClickListener子类的对应方法。

如果到这里你都懂了,很好,我们再说多一些,具体一些。

究竟我们知道了这个机制之后,它有什么用呢?一般来说,用得比较多,就是通信以及MVP模式

通信,其实就是不同组件之间的通信,可以是Fragment和Activity,也可以是Adapter和Activity,这里不详细说太多,可以看看之前的博文:http://www.cnblogs.com/Fndroid/p/5187444.html

上面我们说到了MVP,这个模式真的很重要,对于比较大的项目来说,意义很深远,既能帮助我们解耦不堪重负的Activity,也能便于我们维护和扩展,有兴趣可以参考下面这个项目:https://github.com/bboyfeiyu/the-tech-frontier-app

Android开发学习之路-回调机制学习笔记的更多相关文章

  1. dubbo学习之路-SPI机制

    dubbo学习之路-SPI机制 1.SPI 1.1Java SPI 原理 SPI是service provider interface简称.在java JDK中 内置的一种服务提供发现机制.它解决在一 ...

  2. ZT ANDROID jni 中的事件回调机制JNIenv的使用 2012-09-10 12:53:01

    ANDROID jni 中的事件回调机制JNIenv的使用 2012-09-10 12:53:01 分类: 嵌入式 android framework 里java调用native,使用JNI机制,ja ...

  3. Android开发学习之路-回调实现Service向activity传递数据

    开启服务的时候,如果我们是通过bindService来绑定服务并且要向服务传递数据,可以直接在Intent中设置bundle来达到效果,但是如果是我们需要从服务中返回一些数据到Activity中的时候 ...

  4. java模板和回调机制学习总结

    最近看spring的JDBCTemplete的模板方式调用时,对模板和回调产生了浓厚兴趣,查询了一些资料,做一些总结. 回调函数: 所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个 ...

  5. Android开发艺术-第二章 IPC 机制

    2.1 Android IPC 简单介绍 IPC 意为进程间通信或者跨进程通信,线程是 CPU 调度的最小单元,是一种有限的系统资源. 进程一般指一个执行单元.不论什么操作系统都须要对应的 IPC 机 ...

  6. Android开发系列之事件拦截机制

    对于Android开发者来说理解事件传递机制的重要性,我想应该是不言而喻的.在一个Activity里面,我们经常会重写onTouchEvent事件,可是重写结束之后,对于是返回true还是返回fals ...

  7. [android开发篇] api demo 官网学习网址

    http://www.android-doc.com/resources/samples/wifidirectdemo/index.html

  8. python 操作exls学习之路1-openpyxl库学习

    这篇要讲到的就是如何利用Python与openpyxl结合来处理xlsx表格数据.Python处理表格的库有很多,这里的openpyxl就是其中之一,但是它是处理excel2007/2010的格式,也 ...

  9. Vue学习之路8-v-on指令学习简单事件绑定之属性

    前言 上一篇文章以v-on指令绑定click事件为例介绍了v-on指令的使用方法,本文介绍一下v-on绑定事件的一些属性的使用方法. v-on绑定指令属性 .stop属性 阻止单击事件继续向上传播(简 ...

随机推荐

  1. Unity 依赖注入之一

    在项目中引入Unity,建立一个接口IWork跟一个继承IWork接口的Work类 public interface IMyWork { void Work(); } public class MyW ...

  2. 一台电脑安装多个版本的jdk

    我们平时在做Java开发的时候,有时需要使用多个版本的jdk, 那么一台电脑上需要安装多个JDK了. 那一台电脑上可不可以同时安装多个版本的jdk呢? 答案是可以的! 但使用的时候,只能使用一个,不能 ...

  3. 丢手帕问题即约瑟夫问题的PHP解法

    问题描述:n个人排成一圈.从某个人开始,依次报数,数到m的人被杀死.下一个人重新从1开始报数,数到m的人被杀死.直到剩下最后一个人. 解决思路:从数学角度去看,每一次报数决定谁去死是一个n.m的求余数 ...

  4. Android Handler消息传递机制

    在Android系统中,类Handler主要有如下两个作用. 在新启动的线程中发送消息. 在主线程中获取.处理消息. 类Handler在实现上述作用时,首先在新启动的线程中发送消息,然后在主线程中获取 ...

  5. 【转】Oracle 执行计划(Explain Plan) 说明

    转自:http://blog.chinaunix.net/uid-21187846-id-3022916.html       如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQ ...

  6. 【转】php Thread Safe(线程安全)和None Thread Safe(NTS,非 线程安全)之分

    Windows版的PHP从版本5.2.1开始有Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分,这两者不同在于何处?到底应该用哪种?这里做一个简单的介绍. ...

  7. python实现简单爬虫功能

    在我们日常上网浏览网页的时候,经常会看到一些好看的图片,我们就希望把这些图片保存下载,或者用户用来做桌面壁纸,或者用来做设计的素材. 我们最常规的做法就是通过鼠标右键,选择另存为.但有些图片鼠标右键的 ...

  8. Xml 建议优先使用属性

    要点:建议优先选用属性的方式记录数据,除非还需要包容层级式的数据. 优点: 1. 可以完全覆盖关系型数据库的数据格式设计,利于交换. 2. 占用空间小.相当于 JSON 格式,不再有大量重复的节点名后 ...

  9. React-Native -课后练习

    import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, Image, } fro ...

  10. java的基础知识运算符

    一.运算符. 1.算数运算符:+,-,*,/,% 2.自增自减 :++ ,-- ++在前 先运算在赋值 ++在后 先赋值后运算 -- 减减同上. 3.赋值运算符 : = ,+=,-=,*=,/= 4. ...