精华内容
下载资源
问答
  • android回调函数

    2016-03-04 23:19:57
    该demo实现简单自定义回调函数,大家可以下载学习一下,希望可以帮助到您。
  • Android回调函数demo

    2015-12-08 22:47:35
    回调函数在安卓中的使用,简单明了,一个demo入门了解回调机制
  • Android回调函数的例子

    2014-12-26 14:14:30
    Java回调函数的理解。通过在Android小程序下运行一个Java回调程序。代码内部有简单讲解。
  • Android回调函数机制那点事

    千次阅读 2016-04-01 23:12:26
    所谓的回调函数就是:在A类中定义了一个方法,这个方法中用到了一个接口和该接口中的抽象方法,但是抽象方法没有具体的实现,需要B类去实现,B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A类去调用...
     
    

    在Android的学习过程中经常会听到或者见到“回调”这个词,那么什么是回调呢?所谓的回调函数就是:在A类中定义了一个方法,这个方法中用到了一个接口和该接口中的抽象方法,但是抽象方法没有具体的实现,需要B类去实现,B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A类去调用,这种机制就称为回调。


    这么说可能还是有些模模糊糊,接下来我们用类比的方法一步步来看到底该怎么写一个回调函数,因为android回调中最常见的是Button的点击事件的回调,这里以此为参照:

    1、在A类中定义一个接口:需要我们在类中定义出一个接口,并且给这个接口定义出一个抽象方法,就像下面这样:

    public interface CallBack{
            public abstract void work()
        }

    以下是View.java类中定义的响应点击事件的接口:

    /**
         * Interface definition for a callback to be invoked when a view is clicked.
         */
        public interface OnClickListener {
            /**
             * Called when a view has been clicked.
             *
             * @param v The view that was clicked.
             */
            void onClick(View v);
        }

    2、在A类中定义出该接口的一个成员变量:

    public CallBack mCallBack

    以下是View.java类中获取点击事件接口成员变量的源码:

      /**
             * Listener used to dispatch click events.
             * This field should be made private, so it is hidden from the SDK.
             * {@hide}
             */
            public OnClickListener mOnClickListener;

    3、在A类中定义出一个公共方法,可以用来设置这个接口的对象,调用该方法可以给接口对象变量赋值:

    public void setCallBack(CallBack callBack) {    
        this.mCallBack = callBack;    
    }  

    这里看英文注释也看得出来是什么意思,是不是想到了我们平常使用setOnClickListener(OnClickListener l)的时候呢:

     /**
         * Register a callback to be invoked when this view is clicked. If this view is not
         * clickable, it becomes clickable.
         *
         * @param l The callback that will run
         *
         * @see #setClickable(boolean)
         */
        public void setOnClickListener(@Nullable OnClickListener l) {
            if (!isClickable()) {
                setClickable(true);
            }
            getListenerInfo().mOnClickListener = l;
        }

    最后一步,如果说前面的都没问题,但这一步可能更不好理解了,不过没关系,我们先看一下
    4、在A类中调用接口对象中的方法:

    public void doWork(){
       mCallBack.work();
    }

    在View.java中的体现:

     /**
         * Call this view's OnClickListener, if it is defined.  Performs all normal
         * actions associated with clicking: reporting accessibility event, playing
         * a sound, etc.
         *
         * @return True there was an assigned OnClickListener that was called, false
         *         otherwise is returned.
         */
        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;
            }
    

    这里附上整个项目的代码,这里A类映射到实际中使用Employee 这个类来代表:

    public class Employee {    
        /*  
         * 定义回调接口的成员变量  
         */    
        private CallBack mCallBack;    
        /*  
         * 声明回调接口  
         */    
        public interface CallBack{    
            public abstract void work();    
        }    
        /*  
         * 设置回调接口对象成员变量  
         */    
        public void setCallBack(CallBack callBack) {    
            this.mCallBack = callBack;    
        }    
        /*  
         * 调用回调接口对象中的方法  
         */    
        public void doWork() {    
            mCallback.work();    
        }    
    }    

    我们在定义出一个B类,就用Boss类吧:

    public class Boss {    
        private Employee employee;    
        /*  
         * 为Employee设置回调函数, 在这里定义具体的回调方法  
         */    
            employee.setCallback(new Employee.Callback() {    
                @Override    
                public void work() {    
                    System.out.println("work");    
                }    
            });      
    }   

    如果第一眼看不明白,我们附上我们最常用的Button点击事件的处理的代码,这里Employee 类类比一下就是View类:

    public class TestCallBack{
        private Button button;
        button.setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
               //做一些操作
                doWork();
            }
        });
    
    }

    这时候我们在再回头关于回调的定义:
    在A类中定义了一个方法,这个方法中用到了一个接口和该接口中的抽象方法,但是抽象方法没有具体的实现,需要B类去实现,B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A类去调用

    我们在Employee(View)类中定义了一个接口,接口当中还含有一个抽象方法,这个抽象方法没有具体的实现,当我们需要时候自己去实现这个方法,比如这里的Boss (Button)类,这句话可能难以理解:B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A类去调用,有些人会想,诶,在onClick()方法中我不是写了具体的实现嘛,其实真的是这样吗,我们接着往下看,我们就来好好的分析一下这个Button点击事件。

    首先,在View类中我们能找到setOnClickListener(OnClickListener l)方法:

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

    这里将OnClickListener赋值给了mOnClickListener,我们想要找到onClick()方法是由View回调而不是Button自己回调的证据,就在这里:

    public boolean performClick() {  
         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);  
         ListenerInfo li = mListenerInfo;  
         if (li != null && li.mOnClickListener != null) {  
             playSoundEffect(SoundEffectConstants.CLICK);  
             li.mOnClickListener.onClick(this);  
             return true;  
         }  
         return false;  
    }  

    对此我们的解释是:在父类中我们要用到onClick()方法,但是父类却没有去实现该方法,而是定义了一个方法setOnClickListener(OnClickListener l),如果子类想要自己能够响应点击事件,则它就必须重写父类的该方法,实现OnClickListener接口和它的onClick()方法。在子类实现该接口和方法后,将其通过参数传递给父类,在父类中执行onClick()方法。那么我们是如何运行到这个OnClick()函数的呢,这里由于涉及到View的事件分发机制不细说,想了解的话网上有很多资料,这里只给出结论,因为我们在TestCallBack这个类中没有实现OnTouchListener这个接口,那么当点击事件发的时候必然会运行到onTouchEvent()这个方法,我们来看一下这个方法:

    public boolean onTouchEvent(MotionEvent event) {  
        // 略去无用代码...  
        if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {  
    
             switch (event.getAction()) {  
    
                  case MotionEvent.ACTION_UP:  
    
                // 略去无用代码...  
                    if (!mHasPerformedLongPress) {   
                        // This is a tap, so remove the longpress check removeLongPressCallback();   
                        // Only perform take click actions if we were in the pressed state   
                        if (!focusTaken) {   
                            // Use a Runnable and post this rather than calling   
                            // performClick directly. This lets other visual state   
                            // of the view update before click actions start.   
                            if (mPerformClick == null) {   
                                mPerformClick = new PerformClick();   
                            }   
                            if (!post(mPerformClick)) {  
                                performClick(); //重点在这  
                            }   
                        }   
                    }   
                    //略去无用代码..  
                    break;   
            }   
            return true;   
        }   
        return false;   
    }  

    还记得前面我们在performClick();类里面找到的关于View.java类中对于回调方法onClick的调用么

    li.mOnClickListener.onClick(this);//就是这里

    这样我们就完整的了解了整个OnClickListener()接口中体现出来的回调机制

    为了实现一个回调方法,首先要先定义一个包含了接口的类,并且这个接口中要有一个抽象方法,这个抽象方法的具体实现由其他类来完成(比如我们响应Button的点击事件,onClick()方法里写上当点击事件产生并且该方法被调用时候需要做的操作,比如显示一些文本信息等等),最后该方法的回调是之前的包含有抽象方法的那个接口所在的类去调用的,比如说onClick()方法是当点击事件产生之后经过一系列的事件分发在View类中被调用的。这其中的奥秘就是:

    回调其实是一种双向调用模式,也就说调用方在接口被调用时也会调用对方的接口,实现方法交还给提供接口的父类处理!

    我们都知道Java是一门面向对象的语言,有一句很著名的话就是”万事万物皆为对象”,我们把普通事物的共性抽取出来,而这些共性之中又充斥着特性,每个不同的特性就需要交给特定的情况处理,通过暴露接口方法可以减少很多重复,代码更加优雅。

    打个比方,Button、ImageButton等都具有可被点击的共性,但是被点击之后相关事件的处理是不同的,比如说我想我要点击的这个Button弹出一个消息提示,然而我希望我的ImageButton点击之后可以弹出一个Notifaction通知,这个时候回调方法的好处就体现出来了,因为android对外暴露的OnClickListener()接口中含有一个OnClick()方法,你需要怎样的具体实现都由你自己定义,而这个回调方法的所在类View不会管你怎么实现的,它只负责调用这个回调方法,这就是使用回调的好处。

    android中的回调
    Android中回调函数机制解析

    我也是菜鸟一枚,也在一步步的爬坑,所以可能提供不了多少所谓的干货,但是我们可以一起进步,谢谢!
    这里写图片描述

    展开全文
  • Android 回调函数的理解,实用简单

    万次阅读 2017-03-03 14:42:00
    作者: 夏至,欢饮转载,也请保留这段申明一般我们在不同的应用传递数据,比较方便的是用广播和回调函数,当然还有其他方式,这里学学回调函数的使用; 什么是回调函数呢?在C/C++中,因为我们有指针这个东西,所以...

    作者: 夏至,欢饮转载,也请保留这段申明
    http://blog.csdn.net/u011418943/article/details/60139910

    一般我们在不同的应用传递数据,比较方便的是用广播和回调函数,当然还有其他方式,这里学学回调函数的使用;
    什么是回调函数呢?在C/C++中,因为我们有指针这个东西,所以传递数据什么的,挺方便,把那个指针地址发过来,改一下地址里面的值即可即可;但是Java中是没有指针这个概念的,所以,这个回调函数则是用一个interface 接口和内部类实现的。
    而实用回调函数的好处在于,可以很方便的监听到某个类的状态,常用的是监听一个下载任务的进度和下载状态等等。
    首先,先定义一个共有接口:

    public interface myCallBack {
        public void fail(int error,String msg);
    }

    ok,我们定义了一个接口,那怎么使用呢?首先先思考一下,假如我有两个类,b和c,我想在b类中监听c类的fail这种状态;那我只要把b类的实例给c,c实现方法就可以了。
    ok,那么我们在c类中,实现方法

    public class myc {
    
        public void test(int error,myCallBack mycallback){
            if (error ==1 ){
                mycallback.fail(1,"测试得到: "+1);
            }else{
                mycallback.fail(0,"没有得到1");
            }
        }
    }

    然后,我们在b类中,实例化c类,然后我们的 myCallBack 实例传递过去

     new myc().test(1, new myCallBack() {
                @Override
                public void fail(int error, String msg) {
                    Log.d(TAG, "fail: "+msg);
                }
            });

    打印如下:

    zsr: fail: 测试得到: 1
    

    在服务中心回到结果:

    有时候,我们需要这种需求,比如一个下载任务,我们在服务中开启了下载任务,我们需要在 MainActivity 去监听下载任务的进度和下载状态等一些信息,但是我们启动这个callback是在服务的,那怎么办?
    很简单,只要把 MainAcivity 的callback 实例给服务就可以了,但是不是用 inputextra 的方式:

    public class myb extends Service{
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
        private myCallBack myCallBack = MainActivity.myCallBack;
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
            new myc().test(0,myCallBack ); //把开启这个服务的 callback 实例传递过来
            return super.onStartCommand(intent, flags, startId);
        }
    }

    这样,我们就可以在 MainActivity 中监听c类中的状态了:

    public static myCallBack myCallBack =  new myCallBack(){
            @Override
            public void fail(int error, String msg) {
                Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
            }
        };
    展开全文
  • android回调函数的理解

    千次阅读 2011-05-26 00:25:00
    所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调 用C中的某个函数B,对于C来说,这个B便叫做回调函数。例如Win32下的窗口过程函数就是一个典型的回调函数。一般说来,C...

    所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调
    用C中的某个函数B,对于C来说,这个B便叫做回调函数。例如Win32下的窗口过程函数就是一个典型的回调函数。一般说来,C不会自己调用B,C提供B
    的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的B姓甚名谁,所以S会约定B的接口规范(函数原型),然后由C提前通过S的一个函数
    R告诉S自己将要使用B函数,这个过程称为回调函数的注册,R称为注册函数。Web Service以及Java

    RMI都用到回调机制,可以访问远程服务器程序。

         下面举个通俗的例子:

        
    某天,我打电话向你请教问题,当然是个难题,^_^,你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这
    样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。这个例子说明了“异步+回
    调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机
    能够接收到你的呼叫,这是回调函数必须符合接口规范。


    文章出处:飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/java/javajs/20100719/463101.html

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 101,828
精华内容 40,731
关键字:

android回调函数