Android 之动态代理

来源:互联网 发布:类似江南布衣淘宝店 编辑:程序博客网 时间:2024/06/08 08:21

先不说话

Class LogHandler

执行统一操作

 

获取方法注解,获取参数注解

 

获取参数的值

Interface LogUtil

定义方法,做方法注解,做参数注解

 

 

 

 

Parms

参数注解

 

 

 

 

Method

方法注解

 

 

 

 





1.Params 注解

package com.sclgxt.invokeapplication;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Created by Sclgxton 2016/5/5. */@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.PARAMETER)public @interface Params {    String value() default "";}
2.Method注解

package com.sclgxt.invokeapplication;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Created by Sclgxt on 2016/5/5. */@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface Tag {    String value() default "";}
3.CallBack
package com.sclgxt.invokeapplication;/** * Created by Sclgxt on 2016/5/5. */public interface CallBack {    void log(String message);}

4.LogUtil

package com.sclgxt.invokeapplication;/** * Created by Sclgxt on 2016/5/5. */public interface LogUtil {    @Tag("男神")    void print(@Params("Name") String message, CallBack callBack);    @Tag("女神")    void print(@Params("Name") String name, @Params("Age") String age, CallBack callBack);}
5.LogHandler

package com.sclgxt.invokeapplication;import java.lang.annotation.Annotation;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.HashMap;import java.util.Map;/** * Created by Dell on 2016/5/5. */public class LogHandler<T> {    private static LogHandler logPrint;    private static Map<String, Object> map = new HashMap<>();    private LogHandler() {    }    public static LogHandler getInstance() {        if (logPrint == null) {            logPrint = new LogHandler();        }        return logPrint;    }    public LogUtil create(Class mclass) {        /**         * 缓存中去         */        Object o = null;        map.get(mclass);        /**         * 取不到则取构造代理对象         */        if (o == null) {            o = Proxy.newProxyInstance(LogHandler.class.getClassLoader(), new Class[]{mclass}, new InvocationHandler() {                @Override                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                    final CallBack callback = (CallBack) args[args.length - 1];                    final Tag tag = method.getAnnotation(Tag.class);                    if (tag != null) {                        /**                         * 获得方法注解的值                         */                        StringBuilder tagvalue = new StringBuilder();                        tagvalue.append(tag.value());                        tagvalue.append("\n");                        System.out.println(tagvalue.toString());                        /**                         * 获得所有参数上的注解                         */                        Annotation[][] methodParameterAnnotationArrays = method.getParameterAnnotations();                        if (methodParameterAnnotationArrays != null) {                            int count = methodParameterAnnotationArrays.length;                            for (int i = 0; i < count; i++) {                                /**                                 * 获得单个参数上的注解                                 */                                Annotation[] methodParameterAnnotations = methodParameterAnnotationArrays[i];                                if (methodParameterAnnotations != null) {                                    for (Annotation methodParameterAnnotation : methodParameterAnnotations) {                                        /**                                         * 如果是Params注解                                         */                                        if (methodParameterAnnotation instanceof Params) {                                            /**                                             * 取得Params注解上的值                                             */                                            Params paramsinterface = (Params) methodParameterAnnotation;                                            String paramsvalue = paramsinterface.value();                                            System.out.println(paramsvalue);                                            /**                                             * 这是对应的参数的值                                             */                                            tagvalue.append(paramsvalue + ": ");                                            System.out.println(args[i]);                                            tagvalue.append(args[i]);                                            tagvalue.append("\n");                                            /**                                             * 使用Params注解替换get注解中的值为参数值                                             */                                        }                                    }                                }                            }                        }                        callback.log(tagvalue.toString());                    }                    return null;                }            });            map.put(mclass.toString(), o);        }        return (LogUtil) o;    }}
6.使用

final TextView tv = (TextView) findViewById(R.id.view);LogUtil logUtil = LogHandler.getInstance().create(LogUtil.class);logUtil.print("林允儿", "22", new CallBack() {    @Override    public void log(String message) {        tv.setText(message);        Log.i("", "-->" + message);    }});logUtil.print("郭碧婷", new CallBack() {    @Override    public void log(String message) {        tv.setText(tv.getText() + "\n" + message);        Log.i("", "-->" + message);    }});
7.效果


8.为什么这么写,为了那些虽然参数不同,方法名也不尽相同,但是它们都执行统一的操作的方法,我感觉这就是为了装逼,因为我们总有其他方法来实现;

    第一次看见的时候,是在一个同事写的网络请求之中:给你们贴一段代码

    NetUtil

//请求验证码@POST("/api/common/queryCode")NetRequest getCode(@PARAMS("mobile") String mobile, @PARAMS("type") int type);//请求用户信息@POST("/api/user/queryInfo")NetRequest<UserInfo> queryInfo(@PARAMS("sign") String sign);//登录@POST("/api/user/login")NetRequest<User> login(        @PARAMS("code") String code,        @PARAMS("network") int network,        @PARAMS("brand") String brand,        @PARAMS("lat") double lat,        @PARAMS("lng") double lng,        @PARAMS("brandId") String brandId,        @PARAMS("ostype") int ostype,        @PARAMS("osversion") String osversion,        @PARAMS("maptype") String maptype,        @PARAMS("countryCode") String countryCode,        @PARAMS("register_channel") String register_channel);
就这样,通过和后台商量好数据返回格式,再知道返回数据类型,就可以轻易的得到自己想要的各种class 数据,当然我们还有其他的实现方式,总之我还是觉得这是装逼!!!!!!!之前1-6的代码,拷贝下来可以运行,原理就不说了,自己想去!!
Proxy.newProxyInstance()这个方法的第一个参数,ClassLoder 没什么作用....

0 0
原创粉丝点击