本文参考文章:点击打开链接。
Android 中处处存在回调,比如一个按钮的点击事件;虽然平时代码已经写麻木了,完全已经背下来;但是知其然还要只其所以然,昨天终于把回调弄懂了,今天把知识整理出来。 以下代码只要敲一遍,再小白的人都会理解Android中的回调机制,当然你也可以先看参考文章,再看这篇。
回调的简单理解:个人理解就是,A让B想一个问题,B想好后通过A的回调方法告诉A。
回调的两个条件:
Class A调用Class B的X方法(A需持有对B的引用)
Class B中X方法执行过程中调用Class A中的Y方法完成回调。
数据的大致流向: A –> B –> A
图表示如下:
public class A {
public A(B b ){
b.dosomething( this ,"question->1+1=?" );
}
public void callback(String answer){
System. out .println(answer );
}
}
public class B {
public void dosomething(A a,String question){
String answer= question+2;
a.callback( answer);
}
}
public static void main(String[] args) {
B b= new B();
new A(b );
}
这就是java中最简单的回调,A类中的回调方法将输出B给的答案,即B调用A的回调方法把答案传给A。
接下来,问题来了,如果B不仅要把答案告诉A,还要告诉C类,D类,那怎么办?为了方便我们可以使用多态,把A中的回调方法抽象出接口,这样只要实现了该接口的类都可以得到B的回调。代码如下:
public interface CallBackInterface {
public void callback(String answer);
}
public class A implements CallBackInterface{
public A(B b ){
b.dosomething( this ,"question->1+1=?" );//多态思想,此时如果多个类想得到B的回调,只要继承父类(接口),并传入子类(类自己this)即可。
}
@Override
public void callback(String answer) {
System. out .println(answer );
}
}
public class B {
public void dosomething(CallBackInterface callBackItf,String question){
String answer= question+2;
callBackItf .callback(answer );
}
}
public static void main(String[] args) {
B b= new B();
new A(b );
}
我们可以再改造一下,在B类中添加思考问题的线程,A类中把持有B的引用和调用B的Y方法分开来。如下:
public class A implements CallBackInterface{
B b;
public A(B b ){
this .b =b ;
}
public void askQuestion(){
b.dosomething( this ,"question->1+1=?" );
}
@Override
public void callback(String answer) {
System. out .println(answer );
}
}
public class B {
public void dosomething(CallBackInterface callBackItf,String question){
new Thread(new Runnable() {
@Override
public void run() {
System. out .println("Think the question...." );
try {
Thread. sleep(3000);
} catch (InterruptedException e ) {
e.printStackTrace();
}
String answer= question+2;
callBackItf .callback(answer );
}
}).start();
}
}
public static void main(String[] args) {
B b= new B();
A a= new A(b );
a.askQuestion();
}
最终改造,B类解耦和,B类中的X()方法只对外提供引用,而调用回调在B类的思考问题方法执行。如下:
public class A implements CallBackInterface{
B b;
public A(B b ){
this .b =b ;//相当于Button的findViewById
}
public void askQuestion(){
b.dosomething( this ,"question->1+1=?" );
}
@Override
public void callback(String answer) {
System. out .println(answer );
}
}
//如果不继承父类(接口) 传入this,也可直接new 出父类(接口)并传入。写法如下:
public class A{
B b;
public A(B b ){
this .b =b ;
}
public void askQuestion(){
b.dosomething( new CallBackInterface() {//匿名内部类
@Override
public void callback(String answer) {
System. out .println(answer );
}
}, "question->1+1=?" );
}
}
public class B {
CallBackInterface callBackItf ;
public void setCallBackListener(CallBackInterface callBackItf){ //暴露对外调用方法 X()
this .callBackItf =callBackItf ;
}
public void dosomething(String question){ //思考问题方法
new Thread(new Runnable() {
@Override
public void run() {
System. out .println("Think the question...." );
try {
Thread. sleep(3000);
} catch (InterruptedException e ) {
e.printStackTrace();
}
String answer= question+2;
callBackItf .callback(answer );
}
}).start();
}
}
public static void main(String[] args) {
B b= new B();
A a= new A(b );
a.askQuestion();
}
这就是Android中随处可见的回调。