先举1个Java的例子用来引入

小王去向小李请教数学题,小李在判断完小王的问题后将结果返回给小王:

//这个是回调接口,在小李返回结果给小王时要用到public  interface CallBack {    void solve(String result);}
//这个是小王,重写了solve方法public class Wang implements CallBack {    private Li li;    public Wang(Li li) { this.li = li; }    public void ask(String question){        li.answer(Wang.this , question);    }//此处的solve()便是回调方法,可以在其他类中调用    @Override    public void solve(String result) {        System.out.println("答案是:"  + result);    }}
//这个是小李,判断完问题之后将答案通过callBack.solve返回给小王public  class Li {    public  void answer(CallBack callBack, String question){        String result = "不知道";        System.out.println("问题是:" + question);        if(question.equals("1+1=?"))    result = "2";        else if(question.equals("1+2=?"))   result = "3";        callBack.solve(result);    }}
测试类public  class Test {    public  static  void main(String[]args){        Li li = new  Li();        Wang wang = new  Wang(li);        wang.ask("1+1=?" );    }}

此例如果能看懂就不必再深究了,这里只是为了引入
直接看下面的Android的实际例子


简单需求:点击Fragment的Button,改变MainActivity中TextView的显示
//定义接口public interface CallBackListener {    void onCallBack();}
public class MainActivity extends AppCompatActivity implements CallBackListener {    int i = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }//根据自定义需求重写方法    @Override    public void onCallBack() {        TextView textView = findViewById(R.id.textView);        textView.setText("点击了" + i + "次");        i++;    }}
public class CallBackFragment extends Fragment {    private CallBackListener callBackListener;    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        return inflater.inflate(R.layout.fragment, container, false);    }    @Override    public void onActivityCreated(@Nullable Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);                if (getActivity() instanceof CallBackListener)            callBackListener = (CallBackListener) getActivity();    }    @Override    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {        super.onViewCreated(view, savedInstanceState);        Button btn = (Button) view.findViewById(R.id.button);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if(callBackListener != null)                    callBackListener.onCallBack();            }        });    }}

onCreateView和onViewCreated的区别:日常使用没区别:)

onCreateView可能会(极少)在绘制子View(TextView、Button等除了主Layout的其他控件)的时候崩溃,这时可以尝试在onCreateView中初始化主Layout,而在onViewCreated中使用findViewById初始化其他控件。
调用顺序:onViewCreated()会在onCreateView()之后立马被调用

来源:stackoverflow




综上2个例子,以下是我个人的理解和想法

  1. 首先创建一个接口L(如上例的CallBack或CallBackListener),并在其中添加你想要的效果( solve() 或 onCallBack() )。这个接口可以创建在外面,也可以创建在某个类中

  2. 哪个类想要实现这个效果,这个效果最终体现在哪个类上面,就让这个类继承前面定义好的那个接口(如果这个接口是单独新建的情况1),或者在这个类中new出接口并重写方法(如果这个接口是新建在其他类中的情况2)

    情况1: 你想让小王去输出结果(因为如果是小王输出的话就说明小王拿到了结果),就让Wang继承CallBack;你想让MainActivity中的Textview显示点击次数,那就让MainActivity继承CallBackListener。
    情况2: 假设CallBack接口是定义在类A中的,而你想要B类去实现你要的效果。

    public class A {public void add(MyCallBack myCallBack){    myCallBack.complete();}public interface MyCallBack{    void complete();};}
    public class B {A a = new A();public void test(){    a.add(new A.MyCallBack(){    @Override    public void complete() {    //自定义效果    }    });};}
  3. 第二步中你想要的那个效果,是谁导致的,是谁触发的,就在谁中引用
    比如:小王拿到结果是由于小李将答案传给了小王,所以小李就需要通过answer()中的callback获取到小王的引用,通过callBack.solve把resul传给小王;MainActivity中TextView变化是由于Fragment中Button的点击,所以在Fragment中,首先通过getActivity()获取到MainActivity,然后在Button的点击事件中调用onCallBack()方法达到效果;自定义效果是在调用a.add时触发的,所以就在类A中引用,即myCallBack.complete()(情况二这种情况,一般引用的类和接口定义的类是同一个类)


这时候就要考虑为什么需要有Callback的存在,它的意义是什么
在Java学习中我们就知道了,接口的作用是「我想要一个XX效果,但是我目前实现不出来,或者说实现的不完全,那就把它定义成一个接口,让下面会用到这个效果的类去继承,然后再根据自己的情况去重调代码」
我们这时候举例,假如这个我们想要的效果就是点击事件

Button原生的点击事件
package android.view;public interface OnClickListener {void  onClick(View v);//省去了其他代码}  
//MainActivity类public  class MainActivity  extends Activity implements  OnClickListener{  private  Button button;      @Override   public void onCreate(Bundle savedInstanceState) {  super .onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  button = (Button)findViewById(R.id.button1);  button.setOnClickListener(this);  }  @Override   public void onClick(View v) {//这里写你想要效果}  }  
//参见‘个人的理解和想法’第三点//因为这个效果的直接来由是「我点击了View」 (Button隶属View),所以需要在View类中获取MainActivity并去调用MainActivity的onClick()方法public class View implements Drawable.Callback, KeyEvent.Callback,AccessibilityEventSource {public OnClickListener mOnClickListener;    public void setOnClickListener(@Nullable OnClickListener l) {        if (!isClickable()) {            setClickable(true);        }                //获取到了MainActivity,类似于例2中的getActivity()        getListenerInfo().mOnClickListener = l;    }    public boolean performClick() {if (li != null && li.mOnClickListener != null) {playSoundEffect(SoundEffectConstants.CLICK);//点击事件,这里即是「回调」li.mOnClickListener.onClick(this);result = true;}     }    //省去了其他代码}

具体分析可以看简书




由上总结,回调其实就是:

A调用B的方法b,需要传入A自身引用,或通过其他方式( getActivity() )拿到A的引用,在方法b执行完毕之后,再利用拿到的A的引用,来调用A中的方法


以上为个人理解,如果有哪里各位dalao觉得不对或者可以改进的希望可以提出,如果有疑惑想要一起交流的也同样欢迎


更多相关文章

  1. 网页标签
  2. Android(安卓)翻书效果
  3. Android下利用Fragment+RadioGroup和TabHost实现底部选项卡的效
  4. 最简便实现Android(安卓)ListView选中item高亮显示
  5. Android(安卓)框架层为IMountService 增加新接口
  6. Android(安卓)开发艺术探索学习笔记(二)
  7. cocos2d怎么设置屏幕朝向?横屏 or 竖屏设置
  8. [置顶] 【Android】 给我一个Path,还你一个酷炫动画
  9. Android(安卓)搜索结果关键字动态匹配筛选变色效果且高亮显示

随机推荐

  1. android 百度sdk之 百度定位
  2. Android 应用程序之间数据共享 - Content
  3. android中的Notification使用
  4. connectbot 1.8.2 下载from github
  5. Android热补丁技术—dexposed原理简析(手
  6. Android之在子线程更新UI(超详细)
  7. 解决WebView加载URL跳转到系统浏览器的问
  8. android kernel启动学习笔记
  9. 风投称Android将像Windows一样主宰移动市
  10. Android签名漏洞分析