码迷,mamicode.com
首页 > 移动开发 > 详细

Android 之动态代理

时间:2016-05-06 12:56:34      阅读:261      评论:0      收藏:0      [点我收藏+]

标签:

先不说话

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 没什么作用....

Android 之动态代理

标签:

原文地址:http://blog.csdn.net/sclgxt/article/details/51329415

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!