Java回调与反复

作者: 这最后微笑是美丽 | 来源:发表于2016-04-10 16:59 被阅读196次

    什么是回调?##

    先举个通俗易懂的例子
    经理要出差,给某个员工安排了任务(挖了个坑就不管了,员工你去填坑。这个坑就是回调),临走前吩咐,任务做完了记得通知我.
    定义回调规范CallBack

    /**
     * 约定一个消息(经理留下手机号码),员工做好了,打电话给经理。经理才知道
     * @author afei
     * 
     */
    public interface CallBack {
        /**
         * 
         * @param feedback 员工做好后,得通知经理
         */
        void callback(String feedback);
    }
    

    Manager

    /**
     * 实现回调规范(我跟员工的约定,他做好了打电话通知我)
     * 我这里实现callback就是把手机带上。要不然员工上哪儿通知我。
     * @author afei
     *
     */
    public class Manager implements CallBack {
    
        /**
         * 经理接到员工的电话,收到消息
         */
        @Override
        public void callback(String feedback) {
            System.out.println("给我的反馈信息是:" + feedback);
        }
    
    }
    

    定义一个调用类

    public class Afei {
        /**
         *  
         * @param callback 就是做好了,我得通知经理啊(比如给打打电话,发邮件etc...
         * 临走前,经理留下了电话号码。我做好了,就骚扰他)
         */
        void doTask(CallBack callback) {
            String msg = "我做好了";
            callback.callback(msg);
        }
    
    }
    

    测试

    public class Client {
    
        public static void main(String[] args) {
            //员工做经理给的任务
            new Afei().doTask(new Manager());
        }
    }
    

    输出
    给我的反馈信息是:我做好了

    不知各位看官理解没有,没有的话,再来一个Android开发的例子。基本模拟activity调用过程,当然,实际情况复杂多了。。。

    /**
     * 定义回调
     * @author afei
     *
     */
    public abstract class Activity {
    
        abstract void onCreate(Map<String, String> bundle);
    }
    
    /**
     * 定义回调调用者
     * @author afei
     *
     */
    public class OS {
        static Map<String, String> bundle;
        
        static {
            bundle = new HashMap<String, String>();
        }
    
        void performCreate(Activity activity) {
            bundle.put("createdMsg", "the bundle be created by OS");
            activity.onCreate(bundle);
        }
    
    }
    
    /**
     * 模拟系统调用入口
     * @author afei
     *
     */
    public class Client {
        public static void main(String[] args) {
            new OS().performCreate(new OneActivity());
        }
    }
    

    Android开发者

    /**
     * 使用回调,开发人员填充代码
     * @author afei
     *
     */
    public class OneActivity extends Activity {
    
        @Override
        void onCreate(Map<String, String> savedInstanceState) {
            System.out.println("实例化布局,并且使用系统实例化的变量:" + savedInstanceState);
        }
    
    }
    

    运行Client.main()方法,输出
    实例化布局,并且使用系统实例化的变量:{createdMsg=the bundle be created by OS}

    看到这里的同鞋maybe会问道,你怎么知道activity是怎么调用的?
    下面我们来测试一下Android系统activity调用过程

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            try {
                throw new Exception("MY_EXCEPTION");
            } catch (Exception e) {
                e.printStackTrace();//使用该方法,可以清晰的知道方法之间的调用关系
            }
        }
    }
    
    activity-call.png preformCreate.png callActivityOnCreate.png ActivityThread.main.png

    来自知乎https://www.zhihu.com/question/20284432

    Android应用程序的入口点是什么?ActivityThread?onCreate?
    是一个搞 Android 开发的朋友,面试的时候被问一个"Android应用程序的入口点是什么?"
    他回答ActivityThread,结果面试的人一脸茫然;他再说onCreate,面试官就”说这就对了嘛”

    summary##

    现在再来总结回调,Java代码的回调函数经常由框架或是系统定义,由程序开发人员填充。回调函数包含:
    调用者:如dbutils中的QueryRunner。
    回调规范:即一个接口,如dbutils中的ResultSetHandler<T>。其中可以定义N多个它的子类。
    返回的数据:由用户自己定义,或是系统已经定义。

    /**
     * 定义回调规范
     */
    public interface Protocol<T> {
        /**
         * @param val 留着回调使用
         * @return
         */
        public  T obj(int val);
    }
    
    /**
     * 定义调用者
     */
    public class Runner {
    
        /**
         *
         * @param customNum 自定义数字
         * @param protocol 用户实现的接口
         * @param <T> 定义泛型
         * @return
         */
        public <T> List<T> getObjs(int customNum,Protocol<T> protocol){
    
            List<T>list = new ArrayList<T>();
            for (int i = 0;i< customNum;i++){
                T ret = protocol.obj(i);
                list.add(ret);
            }
            return list;
        }
    }
    
    public class Client {
    
        public static void main(String[] args) {
    
            Runner runner = new Runner();
    
    //        List<String> objs = runner.getObjs(20, new Protocol<String>() {
    //            @Override
    //            public String obj(int val) {
    //                return "hello" + val;
    //            }
    //        });
            List<String> num = runner.getObjs(30,(val)->{return "hello"+val;});//lambda
            System.err.println(num);
        }
    
    }
    

    运行Client.main()输出结果
    [hello0, hello1, hello2, hello3, hello4, hello5, hello6, hello7, hello8, hello9, hello10, hello11, hello12, hello13, hello14, hello15, hello16, hello17, hello18, hello19, hello20, hello21, hello22, hello23, hello24, hello25, hello26, hello27, hello28, hello29]

    相关文章

      网友评论

        本文标题:Java回调与反复

        本文链接:https://www.haomeiwen.com/subject/skwblttx.html